Skip to content

fix: emit Postgres column meta from result.fields (#11) - #12

Merged
ChuTingzj merged 1 commit into
mainfrom
cursor/postgres-meta-columns-6f52
Sep 21, 2026
Merged

ChuTingzj merged 1 commit into
mainfrom
cursor/postgres-meta-columns-6f52

Conversation

@ChuTingzj

@ChuTingzj ChuTingzj commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11 — #11

Summary

Successful Postgres executeSql returned rows with empty columns, so hosts that zip columns[i] onto values[i] produced {} objects.

The mistake

The runner listened for a fields event on pg.Query. node-postgres 8.x never emits fields. Field metadata is on result.fields when row / end fire.

Stdout was:

{"type":"row","values":[...]}
...
{"type":"end","truncated":false}

with no {"type":"meta","columns":[...]}. Host consumeNdjsonResult therefore got columns: [].

MySQL is unchanged: mysql2 still emits fields, and streamMysql still uses that event.

The fix

sandbox/pg-query-stream.js emits meta from result.fields on the first row and/or end (at most once). Zero-row queries that still have a schema get columns on end. A fields listener remains as a no-op fallback for emitters that do fire it.

Tests

Regression coverage uses a mock Query that never emits fields and only provides result.fields:

  • rows present → meta then rows then end
  • zero-row result with a schema → meta then end
  • row + end both carry fields → a single meta
  • legacy fields event still works without duplicating meta
  • MySQL path in execute.js still listens for fields

Runner image / npm

publish-runner.yml publishes on push to main (sandbox/**) or workflow_dispatch. This environment cannot dispatch that workflow (GitHub App 403: Resource not accessible by integration), and this PR is not merged, so GHCR :v1 is not rebuilt from these commits yet.

Test plan

  • pnpm typecheck / pnpm test / pnpm build locally (58 tests, 0 failures)
  • GitHub Actions CI test job green on this PR
  • After merge (or workflow_dispatch of this branch): copy the new digest from the Publish runner image job summary into DEFAULT_SANDBOX_IMAGE + README
  • Then bump package.json to 0.1.4 and tag v0.1.4 when ready to publish npm
Open in Web Open in Cursor 

node-postgres 8.x never emits a Query `fields` event; column names live
on result.fields during row/end. Emit NDJSON meta from those so hosts
get non-empty columns for rowful and zero-row SELECTs. MySQL still uses
the mysql2 fields event.

Co-authored-by: zhangjing <zhangjing798@qq.com>

@ChuTingzj ChuTingzj left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

Fixes #11 correctly. Root cause (listening for non-existent pg 8.x fields event) is real; result.fields on row/end + single meta is the right fix. Regression tests force the no-fields Query shape. Dockerfile includes the new module. No must-fix in code.

Follow-up (ops, not this PR)

GHCR digest / DEFAULT_SANDBOX_IMAGE / npm 0.1.4 still required after merge — consumers on the current digest keep empty Postgres columns until then.

Do not merge from this bot.

if (settled) {
return;
}
emitMeta(result?.fields);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix matches #11. pg 8.x Query does not emit fields; reading result.fields on row/end with metaSent once is the right shape. Zero-row + legacy fields covered. MySQL left on fields event — good.

Order is correct for the host consumer: meta is written before the first row event.

Comment thread sandbox/Dockerfile
RUN npm install --omit=dev && npm cache clean --force

COPY execute.js stream-limit.js session-setup.js secrets.js events.js ./
COPY execute.js stream-limit.js session-setup.js secrets.js events.js pg-query-stream.js ./

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required for the fix to ship in GHCR — without this COPY the container would still run the old inlined path (or fail to resolve ./pg-query-stream.js). Good that it is in the same PR.

Reminder (not a code block): after merge, Publish runner → new digest → bump DEFAULT_SANDBOX_IMAGE + npm 0.1.4. Old digest stays broken for Postgres columns until then.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved: Cursor Bugbot completed successfully with no findings that require human review. No reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@ChuTingzj
ChuTingzj merged commit c09de54 into main Sep 21, 2026
4 checks passed
cursor Bot pushed a commit that referenced this pull request Sep 21, 2026
Regression stacked on the #12 runner fix: pg 8.x Result.fields must
become NDJSON meta columns even when Query never emits a fields event.

Co-authored-by: zhangjing <zhangjing798@qq.com>
ChuTingzj added a commit that referenced this pull request Sep 21, 2026
Pin DEFAULT_SANDBOX_IMAGE to the GHCR digest from Publish runner
after #12 (Postgres meta columns). Bump npm package to 0.1.4.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
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.

Bug: Postgres runner never emits meta columns (listens for non-existent fields event)

2 participants