Skip to Content

Querying & DML

Raw SQL execution

const res = await client.query('SELECT * FROM app.messages LIMIT 10'); console.log(res.status, res.results?.[0]?.rows);

With parameters:

const res = await client.query( 'SELECT * FROM app.messages WHERE conversation_id = $1', ['conv_42'], );

From client.ts, params are sent through queryWithParams(sql, JSON.stringify(params)).

Typed row parsing helpers

query() returns array rows + schema. For object-shaped typed rows:

interface MessageRow { id: string; sender: string; content: string; } const first = await client.queryOne<MessageRow>( 'SELECT id, sender, content FROM app.messages LIMIT 1' ); const all = await client.queryAll<MessageRow>( 'SELECT id, sender, content FROM app.messages' );

Internally, queryOne/queryAll use parseRows() from helpers/query_helpers.ts.

Execute as another user

await client.executeAsUser( 'SELECT * FROM app.messages LIMIT 1', 'alice', );

Source behavior:

  • wraps SQL as EXECUTE AS USER 'username' ( <statement> )
  • strips trailing semicolons in inner SQL
  • escapes ' in username
  • requires one non-empty statement and a non-empty username

Convenience DML methods

await client.insert('app.messages', { id: 1, sender: 'alice', content: 'hello', }); await client.update('app.messages', 1, { content: 'updated' }); await client.delete('app.messages', 1);

Important caveat

update() builds SQL string values directly (with quote escaping for strings). For complex/untrusted inputs, prefer query() with parameter placeholders where possible.

Query response normalization utilities

query_helpers.ts exports:

  • normalizeQueryResponse(response, preferredOrder)
  • sortColumns(columns, preferredOrder)
  • parseRows<T>(response)
  • SYSTEM_TABLES_ORDER

Use these for stable column ordering in dashboards/admin UIs.

Type shape notes from generated declarations

Generated SDK types mark some fields optional:

interface QueryResponse { status: 'success' | 'error'; results?: QueryResult[]; took?: number; error?: ErrorDetail; } interface QueryResult { schema?: SchemaField[]; rows?: unknown[][]; row_count: number; message?: string; }

Handle missing results/schema defensively in generic tooling.

Last updated on