Skip to content

bug: a FROM item's own identity is not in scope — SELECT * over a subquery returns the wrong columns, and a column cannot be qualified by its alias #724

Description

@dpsiderius

Priority: highest of this batch. The first half is a silent wrong answer.

Two symptoms, one theme: what a FROM item is (its output columns, its alias)
never reaches the resolver, so both star expansion and alias-qualified
references fall back to the underlying table.

1a — SELECT * over a FROM-subquery ignores the subquery entirely. Returns
the base table's columns, in table order, with no error:

$ sqlite3 t.db "CREATE TABLE t(v TEXT, a TEXT); INSERT INTO t VALUES('v1','a1'),('v2','a2');"

SELECT * FROM (SELECT a FROM t) s          oracle: a1 / a2          ours: v1|a1 / v2|a2
SELECT * FROM (SELECT v FROM t) s          oracle: v1 / v2          ours: v1|a1 / v2|a2
SELECT * FROM (SELECT a AS z FROM t) s     oracle: a1 / a2          ours: v1|a1 / v2|a2
SELECT * FROM (SELECT a, v FROM t) s       oracle: a1|v1 / a2|v2    ours: v1|a1 / v2|a2
SELECT s.a FROM (SELECT a FROM t) s        oracle: a1 / a2          ours: a1 / a2     (correct)
SELECT count(*) FROM (SELECT a FROM t) s   oracle: 2                ours: 2           (correct)

Note the fourth row: column order comes from the base table too, so a caller
reading by position gets values from the wrong column with no type error to
hint at it. Naming columns explicitly works, so only the star form is affected.

1b — a column cannot be qualified by its table alias. The alias is
accepted; references through it are not:

SELECT a FROM t AS k        oracle: 7    ours: 7                          (correct)
SELECT k.a FROM t AS k      oracle: 7    ours: error: unknown column "k.a"

This is the normal way to write a join, and #709 (PR #720) just made join
column naming correct, which makes the gap conspicuous.

Suspected cause (both halves): star expansion resolves against the FROM
item's underlying table schema rather than its output schema, and the resolver
registers FROM items only under their table name. #708's reviewers also found a
column_index(..).unwrap_or(0) fallback in resolve_subquery_schemas that maps
an unresolvable name to index 0 instead of erroring — audit it in the same pass,
since a silent index-0 fallback is how 1a stays invisible.

Scope: star expansion uses the FROM item's output column list (post-alias,
post-projection); the resolver binds each FROM item under its alias as well as
its table name, with SQLite's shadowing (SELECT t.a FROM t AS k is an error in
SQLite — verify and match). Remove unwrap_or(0)-style silent fallbacks on
these paths. Oracle-diff the matrix above plus: subquery with an expression
column, nested subqueries, subquery joined to a real table, SELECT s.*,
alias-qualified in WHERE/ORDER BY/GROUP BY, both sides of a join, and an
alias equal to another table's name.

Complexity

Estimate: medium-large
Reasoning: The rule is fully specified by the oracle so there
is no design question; the work is threading the output schema and alias to the
resolver and the star-expansion site, which is the same shape of problem #709
solved for joins and can likely reuse output_column_names_joined.

Refs: 013/Req-3, #708, #709, #718, #720

Activity

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions