Skip to content

Commit 539cd89

Browse files
committed
fix: fromJSON uses all row keys, pg-wire unknown messages no longer fake terminate
convenience.ts: createFromJSON() used Object.keys(data[0]) for column detection — rows with extra keys had those columns silently dropped. Now unions keys across all rows. pg-wire: unknown frontend messages (extended query protocol Parse/Bind/ Execute/Sync) were returned as { type: "terminate" }, conflating them with real client disconnect. Now returns { type: "skip" } which the handler explicitly ignores without affecting connection lifecycle.
1 parent e9f93a8 commit 539cd89

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

src/convenience.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ export function createFromJSON<T extends Record<string, unknown>>(
1919
return new DataFrame(tableName, new MaterializedExecutor(result));
2020
}
2121

22-
const columns = Object.keys(data[0]);
22+
const columnSet = new Set<string>();
23+
for (const item of data) {
24+
for (const key of Object.keys(item)) columnSet.add(key);
25+
}
26+
const columns = [...columnSet];
2327
const rows: Row[] = data.map(item => {
2428
const row: Row = {};
2529
for (const col of columns) {

src/pg-wire/handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class PgConnectionHandler {
9696
}
9797

9898
private async handleMessage(msg: FrontendMessage): Promise<void> {
99-
if (msg.type === "terminate") return;
99+
if (msg.type === "terminate" || msg.type === "skip") return;
100100

101101
if (msg.type === "query") {
102102
await this.handleQuery(msg.sql);

src/pg-wire/protocol.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ export interface SSLRequest {
3030
type: "ssl_request";
3131
}
3232

33-
export type FrontendMessage = StartupMessage | QueryMessage | TerminateMessage | SSLRequest;
33+
export interface SkipMessage {
34+
type: "skip";
35+
}
36+
37+
export type FrontendMessage = StartupMessage | QueryMessage | TerminateMessage | SSLRequest | SkipMessage;
3438

3539
// ── Parsing ─────────────────────────────────────────────────────────────
3640

@@ -95,8 +99,8 @@ export function parseFrontendMessage(buf: Uint8Array): [FrontendMessage, number]
9599
case 0x58: // 'X' — Terminate
96100
return [{ type: "terminate" }, totalLen];
97101
default:
98-
// Skip unknown messages
99-
return [{ type: "terminate" }, totalLen];
102+
// Skip unknown/unsupported messages (extended query protocol, etc.)
103+
return [{ type: "skip" }, totalLen];
100104
}
101105
}
102106

0 commit comments

Comments
 (0)