Protocol Reference

Every stdin/stdout line is one JSON object with required code.

Interface Boundary

This protocol is the only runtime interface.

Input (stdin)

query

Execute one SQL statement.

FieldRequiredDescription
codeyes"query"
idyesclient correlation id
sessionnosession id; default session if omitted
sqlyesSQL text
paramsnopositional bind values
optionsnoquery behavior

options fields:

FieldDefaultDescription
stream_rowsfalsestream rows as result_rows events
batch_rows1000max rows per result_rows event
batch_bytes262144soft byte target per streamed batch
statement_timeout_msconfig defaultper-query statement timeout
lock_timeout_msconfig defaultper-query lock timeout
read_onlyfalseenforce read-only transaction for this query
inline_max_rowsconfig defaultinline row cap for non-streaming
inline_max_bytesconfig defaultinline payload bytes cap for non-streaming

Parameter Binding Rules

  1. Dynamic values should be passed via params with $1..$N placeholders.
  2. Placeholder count must equal params length (validated from prepared-statement metadata, not SQL text scanning).
  3. Count/type validation failures return error_code: "invalid_params".

Driver-side type mapping (prepared statement parameter OIDs):

Unsupported:

CLI mapping notes:

config

Partial runtime config update. Echoes full config afterward.

FieldRequiredDescription
codeyes"config"
default_sessionnodefault session name
sessionsnosession connection definitions
inline_max_rowsnoglobal inline row limit
inline_max_bytesnoglobal inline payload bytes limit
statement_timeout_msnoglobal statement timeout
lock_timeout_msnoglobal lock timeout
lognoenabled log categories

Session connection shape supports:

TLS settings supplied in dsn_secret or conninfo_secret (for example sslmode=require) are honored by the PostgreSQL driver.

CLI translation notes:

cancel

Cancel an in-flight query by id.

{"code":"cancel","id":"q-123"}

When the database connection is already established, afpsql sends a PostgreSQL server-side cancel request before aborting local output handling. Cancellation is still race-prone: a query may finish normally before the cancel request is processed.

ping

Health check.

{"code":"ping"}

close

Graceful shutdown.

{"code":"close"}

Output (stdout)

result

Small result returned inline.

FieldDescription
code"result"
idquery id
sessionsession used
command_tagNormalized command tag (ROWS N / EXECUTE N)
columnscolumn metadata array
rowsresult rows
row_countrow count
tracetiming and counters

result_start

Start of streamed result.

FieldDescription
code"result_start"
idquery id
sessionsession used
columnscolumn metadata

result_rows

One streamed row batch.

FieldDescription
code"result_rows"
idquery id
rowsrow objects for this batch
rows_batch_countrows in batch

result_end

End of streamed result.

FieldDescription
code"result_end"
idquery id
sessionsession used
command_tagNormalized command tag (ROWS N / EXECUTE N)
traceincludes duration_ms, row_count, payload_bytes

sql_error

Database execution error.

FieldDescription
code"sql_error"
idquery id
sessionsession used
sqlstateSQLSTATE (23505, 42P01, …)
messageprimary error message
detailoptional detail
hintoptional hint
positionoptional SQL character position
tracetiming and counters

error

Client/runtime/protocol error.

FieldDescription
code"error"
idoptional related query id
error_codemachine-readable code
errorhuman-readable detail
retryablewhether retry may succeed
tracetiming and counters

Canonical error_code values:

Other output codes

codeMeaning
configfull runtime config echo
pongping response with counters
closeshutdown acknowledgement
logoptional runtime diagnostic event (enabled by log config/categories)

log event fields:

Startup log events include parsed args, redacted config, and selected redacted environment fallback fields. They intentionally omit raw argv. Bind values are summarized as param_count, not logged as plaintext.

log category matching (from config.log / --log):

Runtime Safety Limits

Pipe mode applies hard protocol limits before executing a request:

Environment Fallback

Optional runtime fallback variables:

Standard PostgreSQL environment fallback (lower precedence):

Example: Small Result

Input:

{"code":"query","id":"q1","sql":"select 1 as n"}

Output:

{"code":"result","id":"q1","command_tag":"ROWS 1","columns":[{"name":"n","type":"int4"}],"rows":[{"n":1}],"row_count":1,"trace":{"duration_ms":2}}

Example: Streamed Result

Input:

{"code":"query","id":"q2","sql":"select * from big_table where id > $1","params":[100],"options":{"stream_rows":true,"batch_rows":1000}}

Output:

{"code":"result_start","id":"q2","columns":[{"name":"id","type":"int8"},{"name":"name","type":"text"}]}
{"code":"result_rows","id":"q2","rows":[{"id":101,"name":"a"},{"id":102,"name":"b"}],"rows_batch_count":2}
{"code":"result_end","id":"q2","command_tag":"ROWS 200000","trace":{"duration_ms":443,"row_count":200000,"payload_bytes":34199211}}