Skip to content

fix(ddl): scan SQL code, not literals, in the query-function router - #350

Closed
EnRaiha wants to merge 1 commit into
mainfrom
fix/qf-router-literal-scan
Closed

EnRaiha wants to merge 1 commit into
mainfrom
fix/qf-router-literal-scan

Conversation

@EnRaiha

@EnRaiha EnRaiha commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Why

query_functions::router::try_dispatch picked a query function with
sql.to_uppercase().contains(...) over the raw statement, so any keyword
inside a string literal, quoted identifier, or comment hijacked the statement.
Any statement that does not parse as typed DDL and whose text contains one of
six substrings failed with a misleading 42601, found while replaying a
knowledge-graph backfill:

SQL before
INSERT INTO kg (id) VALUES ('tmp_verify_balance_x') VERIFY_BALANCE requires (collection, column)
INSERT INTO kg (id) VALUES ('tmp_plain_x') OK
INSERT INTO kg (id) VALUES ('tmp_z', 'verify_balance') (keyword in a label) hijacked
INSERT INTO kg { id: 'tmp_verify_balance_y', ... } (brace form) OK

Issue: #349.

What

  • add scan_code: blanks '...' (with '' escapes), "...", --, and
    /* */ before the keyword checks; all other characters pass through verbatim
  • extract recognized_function (the routing decision) so it is testable;
    try_dispatch matches on it; recognition order unchanged; a real
    SELECT VERIFY_BALANCE(...) still routes

Tests

  • unit tests in query_functions::router now pin the routing decision
    (recognized_function): literal, escaped quote, quoted identifier, line and
    block comment, token fusion, first-keyword order, and real calls
  • wire regression in nodedb/tests/wire/cases/router_misroute_literals.rs
    (value_carrying_verify_balance_does_not_misroute): a parenthesised INSERT
    whose value carries the token stores verbatim — the brace form is intercepted
    before the router, so it cannot guard this — and the anchored call still
    reaches the function arm
  • local: cargo test -p nodedb --lib query_functions::router -> 9 passed;
    cargo test -p nodedb --test wire value_carrying_verify_balance_does_not_misroute
    -> 1 passed
  • CI: static gates pass; the Test Suite workflow runs only with the run-ci
    label (.github/workflows/ci.yml gates it), so it reports skipping by design

Survey with c2g on the branch: diff-impact = the decision helper and its call
site; no exported surface change.

Notes

  • Scanner scope: single-quoted literals ('' escapes), quoted identifiers
    (""), -- and /* */ comments. Not handled: nested block comments,
    E-string backslash escapes, and dollar-quoted strings — pre-existing class,
    not regressions of this change.
  • Follow-up, separate refactor: dedupe with the private scanners in
    planner/procedural/executor/core/sql_literal_concat.rs
    (consume_quoted_region, parse_single_quoted_literal) — requires a
    visibility change.

Copilot AI lite review requested due to automatic review settings September 19, 2026 12:23

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

try_dispatch picked a query function with sql.to_uppercase().contains(...) on
the raw statement, so a keyword inside a string literal, quoted identifier, or
comment hijacked the statement and failed with a misleading 42601 - e.g.
INSERT ... VALUES ('tmp_verify_balance_x', ...) answered
"VERIFY_BALANCE requires (collection, column)".

Blank quoted regions and comments before the keyword checks: add scan_code and
route through recognized_function, keeping the pgwire recognition order. Real
SELECT VERIFY_BALANCE(...) calls still route.

Tests pin the routing decision (literals, escapes, comments, unterminated
regions, token fusion, keyword order, real calls) and a wire regression holds
both directions; the wire case seeds with the parenthesised INSERT so it
reaches the router, which the brace form does not.

Issue 349.
@EnRaiha
EnRaiha force-pushed the fix/qf-router-literal-scan branch from 9951a93 to 28cf60d Compare September 19, 2026 14:34
@farhan-syah

Copy link
Copy Markdown
Member

Closing. The fix keeps routing by substring and adds a second quote/comment scanner beside the existing one. The correct fix routes on the parsed function name, so literals, identifiers, and comments cannot match at all. The maintainers will fix #349 in-tree.

@farhan-syah
farhan-syah deleted the fix/qf-router-literal-scan branch September 23, 2026 01:41
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.

3 participants