LakeQL
Overview
  • Introduction
Configuration
  • Client Setup
Queries
  • Executing Queries
  • Streaming
Metadata
  • Inspecting Catalogs
  • API Reference
GitHub
LakeQL
  1. Trino Client
  2. Queries
  3. Executing Queries

On this page

  1. Basic Usage
  2. Row Transforms
  3. User Impersonation
  4. Query Cancellation
  5. Error Handling
  6. How Pagination Works
  7. QueryProps Reference

Executing Queries

Run SQL statements against Trino and collect all result pages into a single array.

Basic Usage #

The query method executes a SQL statement and automatically follows Trino's nextUri pagination links until all result pages have been collected.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { TrinoClient } from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
  schema: "sales",
})

const rows = await client.query<[string, string, number]>({
  sql: "SELECT id, region, amount FROM orders WHERE status = 'shipped'",
})

for (const [id, region, amount] of rows) {
  console.log(`Order ${id}: ${region} - $${amount}`)
}

Row Transforms #

Use the transform option to map raw row arrays into typed objects:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29import { TrinoClient } from "@lakeql/trino-client"
import type { Column } from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
  schema: "sales",
})

interface Order {
  id: string
  region: string
  amount: number
}

const orders = await client.query<Order>({
  sql: "SELECT id, region, amount FROM orders",
  transform: (row: unknown[], columns: Column[]) => ({
    id: row[0] as string,
    region: row[1] as string,
    amount: row[2] as number,
  }),
})

// orders: Order[]
console.log(orders[0].region)

The transform function receives the raw row array and the column metadata, and returns the desired shape.

User Impersonation #

Pass impersonateAs to execute the query as a different Trino user. This sets the X-Trino-User header for that request only:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { TrinoClient } from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
})

const rows = await client.query<[string]>({
  sql: "SELECT current_user",
  impersonateAs: "data-team-service",
})
// rows: [["data-team-service"]]

Query Cancellation #

Cancel a running query using an AbortSignal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import { TrinoClient, TrinoCancellationError } from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
})

const controller = new AbortController()

// Cancel after 10 seconds
setTimeout(() => controller.abort(), 10_000)

try {
  const rows = await client.query({
    sql: "SELECT * FROM very_large_table",
    signal: controller.signal,
  })
} catch (error) {
  if (error instanceof TrinoCancellationError) {
    console.log("Query was cancelled")
  }
}

You can also cancel queries by ID:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { TrinoClient } from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
})

// Cancel a specific query
await client.cancelQuery("20240101_123456_00001_abcde")

// Cancel all active queries
await client.cancelAllQueries()

// Check what's currently running
const active = client.getActiveQueries()

Error Handling #

The client throws typed errors depending on the failure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32import {
  TrinoClient,
  TrinoClientError,
  TrinoQueryError,
  TrinoCancellationError,
} from "@lakeql/trino-client"

const client = new TrinoClient({
  host: "https://trino.example.com",
  port: 8443,
  auth: { type: "basic", username: "analyst", password: "secret" },
  catalog: "hive",
})

try {
  const rows = await client.query({ sql: "SELECT * FROM nonexistent_table" })
} catch (error) {
  if (error instanceof TrinoQueryError) {
    // Trino returned an error in the response body
    console.error(error.errorName) // e.g. "TABLE_NOT_FOUND"
    console.error(error.errorType) // e.g. "USER_ERROR"
    console.error(error.queryId)
  } else if (error instanceof TrinoClientError) {
    // HTTP-level error (non-2xx status)
    console.error(error.statusCode) // e.g. 503
    console.error(error.message)
  } else if (error instanceof TrinoCancellationError) {
    // Query was cancelled via AbortSignal
    console.log("Cancelled:", error.queryId)
  }
}

How Pagination Works #

  1. A POST is sent to /v1/statement with the SQL body
  2. Trino returns an initial response with (optionally) data and a nextUri
  3. The client follows nextUri with GET requests, collecting data arrays
  4. When no nextUri is returned, all pages have been fetched
  5. The concatenated result array is returned

This is entirely transparent — you call query() and get the complete result regardless of how many pages Trino needed internally.

QueryProps Reference #

PropertyType
sqlstring

The SQL statement to execute.

impersonateAs?string

Optional Trino user to impersonate via X-Trino-User.

signal?AbortSignal

Abort signal for cancelling the query.

transform?(row: unknown[], columns: Column[]) => T

Optional transform function to map raw row arrays to typed objects.

Previous page

Queries

Next page

Streaming

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32