Skip to content

compiler: report an error for an unknown relation in rel.* function arguments - #4686

Open
ritojoao wants to merge 1 commit into
sqlc-dev:mainfrom
ritojoao:unknown-relation-star-arg
Open

ritojoao wants to merge 1 commit into
sqlc-dev:mainfrom
ritojoao:unknown-relation-star-arg

Conversation

@ritojoao

Copy link
Copy Markdown

Fixes #4300

SELECT id, ARRAY_AGG(whatever.*) FROM worker compiles and generates Go code even though whatever is not a relation in scope. PostgreSQL rejects it with missing FROM-clause entry for table "whatever".

This adds a check in the FuncCall branch of outputColumns: when an argument is a qualified star (x.*) and x is not a table, alias, CTE, OLD/NEW RETURNING table, or a relation of an enclosing query, sqlc returns table alias "x" does not exist. This is the same message sqlc already uses for other references to an unknown table alias.

To avoid rejecting valid queries:

  • The relations of the enclosing statement stay visible to nested statements (scalar subqueries, sublinks, subselects in FROM), so SELECT (SELECT ARRAY_AGG(o.*) FROM b) FROM o still compiles. A small outer field on QueryCatalog carries them.
  • Aliases of FROM items that sqlc cannot resolve (for example a set-returning function it does not know) are collected from the statement and accepted.

Tests (endtoend, PostgreSQL engine):

  • agg_unknown_relation: fails before the change, passes after. It has stderr/base.txt and stderr/managed-db.txt and no go/ output.
  • agg_correlated_subquery: must still compile. A first version of the check rejected this query, so the case guards against that.
  • agg_unresolved_func_alias: FROM some_unknown_func() AS u must still compile.

The two positive cases run in the base context only (exec.json), because I could not get them to pass in the managed-db context in my local setup, and a real database rejects an unknown function anyway. I am happy to add managed-db coverage if you can point me to the right way to set it up.

What I ran locally: go vet ./internal/compiler/..., the TestReplay end-to-end tests (base and managed-db, the latter against a local PostgreSQL 18) and the rest of go test ./internal/... and go test --tags=examples ./.... In my environment there was no MySQL, so the tests that need one (TestValidSchema MySQL cases and TestExamplesVet) could not pass and I could not compare them with main.

Not tested or not covered: MySQL and SQLite engines (the check is in shared compiler code, so f(x.*) there goes through it too, but I did not add cases), schema.table.* arguments (skipped), stars nested inside other expressions such as COALESCE(ARRAY_AGG(x.*), ...) (only direct function arguments are checked), and stars in WHERE or HAVING.

Please let me know if you would prefer the check somewhere else. Thank you for sqlc!

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.

Column/table references inside aggregate functions are not validated against the schema

1 participant