Skip to content

Feature/postgres improvements#11

Merged
whilo merged 8 commits intomainfrom
feature/postgres-improvements
Apr 17, 2026
Merged

Feature/postgres improvements#11
whilo merged 8 commits intomainfrom
feature/postgres-improvements

Conversation

@whilo
Copy link
Copy Markdown
Member

@whilo whilo commented Apr 16, 2026

No description provided.

whilo added 8 commits April 16, 2026 16:13
Same fix as datahike/pg-server: the Bind handler now reads parameter
values from the Bind message. The Execute handler substitutes $1, $2
placeholders with bound parameter values before execution.

Fixes all JDBC PreparedStatement, psycopg2, and ORM parameterized
queries that were silently failing (parameter values discarded).
Previously returned empty rows, breaking DBeaver/DataGrip column type
detection. Now iterates the table-registry and returns attname,
atttypid, attnum, attrelid for each column. Column types inferred
from the typed array backing (long-array → int8, double-array → float8,
else → text).
- QueryHandlerFactory: per-connection handler with independent tx state;
  each connection gets its own atom tracking {:in-tx false :aborted false}
- Transaction state machine: BEGIN→'T', COMMIT/ROLLBACK→'I', error-in-tx→'E';
  ReadyForQuery and Sync now return the correct status byte
- Aborted state: rejects all non-ROLLBACK/COMMIT commands after an error
  in a transaction, matching PostgreSQL's ACID semantics
- Describe handler: returns ParameterDescription for $N params; executes
  SELECT queries and caches the result so Execute doesn't double-execute;
  DML gets NoData without executing (no accidental early mutations)
- Execute handler: reuses cached Describe result, skips duplicate RowDescription
- Statement splitter: handles dollar-quoted strings ($$…$$, $tag$…$tag$),
  -- line comments, and /* block comments */ in addition to single-quoted strings
- OID constants expanded: BOOL, INT2, INT4, NAME, OID, VARCHAR, TIMESTAMPTZ,
  NUMERIC, UUID, JSONB; typeSize covers all new types
- execute-sql extracted as top-level private fn; make-handler-factory wraps it
  with per-connection tx logic without duplicating the dispatch code
Wire protocol tests (pgwire_test.clj):
- Tests run against a live server via raw TCP sockets, exercising the full stack
- Simple Query: basic aggregation result
- Extended protocol: Parse→Bind→Execute→Sync without params
- Extended protocol: single and multi numeric params, string param, null param
- Describe portal: returns RowDescription with correct column names, Execute
  does not resend it (caching works)
- Describe statement: returns ParameterDescription for $N params
- Transaction state: BEGIN→'T', query-in-tx→'T', COMMIT→'I'
- Transaction abort: error-in-tx→'E', subsequent commands rejected, ROLLBACK→'I'
- Statement splitter: -- comments stripped (psql sends these)
- GROUP BY analytic query with parameterized filter

Bug fixes found by tests:
- handleQuery in PgWireServer.java: txStatus was not updated when result.txStatus='I'
  (COMMIT/ROLLBACK kept stale 'T' status — same fix already in handleExecuteMsg)
- format-results in sql.clj: internal engine keys starting with _ (e.g. _count)
  leaked into SQL result columns; now filtered before serializing to DataRows
@whilo whilo force-pushed the feature/postgres-improvements branch from c22c43e to 6a62473 Compare April 16, 2026 23:25
@whilo whilo merged commit c1e6f61 into main Apr 17, 2026
5 of 6 checks passed
@whilo whilo deleted the feature/postgres-improvements branch April 17, 2026 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant