taozhi8833998 / taozhi8833998/node-sql-parser

TypeScript types disagree with parser output: Select.having, ColumnRefItem.schema, Value.type (PostgreSQL)

Open
#2,656 0 comments 0 reactions 1 assignee View on GitHub

@taozhi8833998 is already working on this.

Since May 7, 2026.

Dominant language
PEG.js
Stars
1k
Forks
244
PR merge metrics
No merged PRs in 30d

Description

Describe the bug
Three places in types.d.ts disagree with what the parser actually emits at runtime, all of which prevent discriminated-union narrowing on the AST in TypeScript:

  1. Select.having is declared any[] | null, but the parser emits a single Binary node (or null).
  2. ColumnRefItem omits a schema?: string field that the parser does emit for namespaced identifiers (schema_a.table.col).
  3. Value.type is declared as string rather than a literal-string union of the actual node-types the parser emits. This blocks node.type === '' narrowing on ExpressionValue because Value overlaps with every other discriminator.

Filing as one issue since they're related (all three force consumers walking the AST into shape coercion or hand-rolled type predicates).

Database Engine
PostgreSQL

To Reproduce

  • node-sql-parser version: 5.4.0

  • node version: tested on Node 22.22.0

    Three runnable repros:

    1. Select.having shape — runtime is a Binary, type says any[]:
  const { Parser } = require('node-sql-parser');
  const ast = new Parser().astify(
    'SELECT * FROM t GROUP BY t.id HAVING count(t.x) > 5',
    { database: 'PostgresQL' }
  );
  console.log('ast.type:', ast.type);                       // 'select' (confirms root is Select)
  console.log('Array.isArray(having):', Array.isArray(ast.having)); // false
  console.log('having.type:', ast.having.type);             // 'binary_expr'
  1. column_ref carries a schema field that's not declared:
  const { Parser } = require('node-sql-parser');
  const ast = new Parser().astify(
    'SELECT * FROM t WHERE actions.foo.bar = 1',
    { database: 'PostgresQL' }
  );
  console.log(JSON.stringify(ast.where.left, null, 2));
  // Prints: { type: 'column_ref', schema: 'actions', table: 'foo', column: 'bar', ... }
  // `ColumnRefItem` in types.d.ts declares only `table` and `column`.
  1. Value.type blocks narrowing — TypeScript-level repro:
  import type { ExpressionValue } from 'node-sql-parser';

  declare const node: ExpressionValue;

  if (node.type === 'binary_expr') {
    // tsc error: Property 'operator' does not exist on type 'Binary | Value'.
    //            Property 'operator' does not exist on type 'Value'.
    const op: string = node.operator;
    console.log(op);
  }

Run with: npx tsc --noEmit --strict --target es2020 --moduleResolution node .ts

Expected behavior
types.d.ts should match the parser's runtime output. The parser is behaving correctly; the types drifted. Suggested type fixes:

  1. Select.having — currently any[] | null, should be Binary | null to match what the parser emits.
  2. ColumnRefItem — currently has no schema field, should declare schema?: string (mirrors BaseFrom.schema?, which is already declared and behaves the same way for FROM
    items).
  3. Value.type — currently string, should be a closed literal-string union of the types the parser actually emits. At minimum:
    type: 'number' | 'bigint' | 'string' | 'single_quote_string'
    | 'double_quote_string' | 'bool' | 'null' | 'date' | 'time'
    | 'timestamp' | 'datetime' | 'hex_string' | 'bit_string';

No runtime changes needed — only types.d.ts.

Screenshots
N/A — repros above produce the evidence in stdout/tsc output.

Additional context

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.