Skip to content

Table-qualified column references in WHERE silently match zero rows (except TEXT primary-key equality) #156

Description

@mkhairi

Tested against: origin/main @ 09b8d9de (post-v0.3.0 main head, 2026-07-05)

Severity: High — standard SQL predicates return wrong empty results with no error; every ORM emits exactly this shape.

Summary

A WHERE predicate that qualifies the column with its own table name — "t"."col" = ... or t.col = ... — matches zero rows, silently. The identical unqualified predicate matches correctly. The single exception: qualified equality on a TEXT primary key works. Qualified predicates on non-PK columns and qualified range predicates on any column all return empty result sets.

Repro

CREATE COLLECTION r25 (id TEXT PRIMARY KEY, label TEXT, score FLOAT) WITH (engine='document_strict');
INSERT INTO r25 (id, label, score) VALUES ('r1', 'alpha', 7);

SELECT id FROM r25 WHERE label = 'alpha';            -- r1        <- correct
SELECT id FROM r25 WHERE "r25"."label" = 'alpha';    -- (0 rows)  <- WRONG
SELECT id FROM r25 WHERE r25.label = 'alpha';        -- (0 rows)  <- WRONG (bare qualifier too)
SELECT id FROM r25 WHERE "r25"."id" = 'r1';          -- r1        <- the one exception (TEXT PK equality)
SELECT id FROM r25 WHERE "r25"."score" >= 5;         -- (0 rows)  <- WRONG (qualified range)

Expected

"table"."column" and table.column references resolve identically to the bare column when the qualifier names the statement's own FROM target — the baseline PostgreSQL identifier-resolution contract the pgwire surface advertises.

Files (best-guess)

  • WHERE-clause column resolution in the SQL planner — qualified identifiers fail to bind to the collection's columns (and the miss is treated as no-match instead of an unknown-column error), with a special case that happens to catch TEXT PK equality

Operational context

Every major ORM qualifies generated predicates (WHERE "orders"."status" = ...) as a matter of course. Against this surface, all such filters — lookups, conditional counts, uniqueness checks — silently return empty, which reads as "no data" rather than as an error. A wrong-results bug of the quietest kind.

Activity

  1. farhan-syah commented on Jul 6, 2026

    @farhan-syah
    Member

    Fixed in commit 820c357.

    Root cause: t.col in a WHERE clause was compared against the literal field name t.col instead of being resolved to col, so it silently matched nothing.

    Fix: the qualifier is now stripped correctly, and referencing a table/alias that doesn't actually exist now returns a real error instead of a silent empty result.

  2. added
    type:bugA defect — broken, incorrect, or lost data
    sev:1-criticalData loss, corruption, security, or crash; no workaround
    area:sqlParser, planner, SQL semantics
    sev:2-highMajor functionality broken; no acceptable workaround
    and removed
    sev:1-criticalData loss, corruption, security, or crash; no workaround
    on Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:sqlParser, planner, SQL semanticssev:2-highMajor functionality broken; no acceptable workaroundtype:bugA defect — broken, incorrect, or lost data

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions