Repository navigation
Fix schemas and Bind formats for SQL cursor FETCH - #1
Merged
Merged
Conversation
tonyalaribe
marked this pull request as ready for review
October 21, 2026 14:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extended FETCH describes no columns for SQL-declared cursors, then returns a populated DataRow. Newer PostgreSQL clients reject the field-count mismatch. The cursor also encodes rows as text at DECLARE time, preventing Bind from selecting binary output.
Retain the cursor input as a streaming Arrow source and encode each FETCH with the requested format. The portal's retained scan owns that source; the per-session schema registry contains weak references. Limited FETCH keeps the remainder of its current batch, and unlimited FETCH streams through the existing encoder. Parse describes the actual result schema. Reusing a prepared FETCH after a cursor changes result type returns SQLSTATE 0A000 instead of malformed rows.
The new formatted hook delegates to the existing hook by default, preserving existing custom hooks. No dependency, persisted format, or codec implementation changes.
Consumer validation in TimeFusion with tokio-postgres 0.7.18:
PostgreSQL defines Bind as the format selector for extended FETCH: https://www.postgresql.org/docs/16/sql-declare.html
Local evidence: /tmp/timefusion-advisory-refresh-2026-10-21/cursor-{protocol-final,format-red,lifetime,lint}.log. The maintained consumer regression is in src/server/mod.rs, wire_streams_cancels_and_reuses_connection. The draft remains open until integrated validation is complete.
Fork fixture follow-up (
1388ea3): consume each returned row stream before issuing the next FETCH. The maintained unit guards now assert exact first/remaining/exhausted counts instead of response type alone. No assertion or client validation is removed. Standalone fork nextest runs pass all 31 default-feature tests and all 34 pgvector tests. These runs use the fork registry graph; the separate consumer checks exercise TimeFusion's pinned DataFusion and vendored pgwire graph.The consumer now pins immutable Git revision
1388ea37ec8eeefd13b07771f8d0052f164ae7f1. Its integrated release gate passes on frozen TimeFusion commitd8e3f68e: 2,802 native tests, 16 doctests, PGWire smoke, all 85 active e2e tests, formatting, and cargo lint. Seventeen native tests and two e2e tests retain their existing skips. The production Linux image also passes its real PGWire smoke and is published by source fingerprint. No production rollout is claimed.All 14 current-head fork CI jobs pass, including the clean Linux build and base, pgvector, and postgis integrations. Final consumer evidence:
/tmp/timefusion-advisory-refresh-2026-10-21/final-full-signoff.logandfinal-frozen-inputs.json.