Repository navigation
Register the aliases of table functions and MATCH_RECOGNIZE - #13
Merged
Merged
Conversation
`build_scope` dropped the alias of an aliased table function FROM item such as `my_func(x) AS g`: it registered nothing, so `g.y` could not resolve. The alias is now registered as a virtual source, as for an aliased UNNEST, and a column list on the alias becomes the source's columns. An aliased MATCH_RECOGNIZE item is now registered as its alias, a source with no scope of its own. The alias hides the input relation, which is still built and reported one depth below the item, the way the items inside an aliased parenthesized join are. The hiding is shared through `hide_names`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uUGFKsqsLyKC6tprkPgFp
The conditions of a parenthesized join that is the input of an aliased MATCH_RECOGNIZE may use the names the alias hides, so they are reported as skipped, as inside an aliased join, instead of being neither scoped nor reported. Adds tests for the exact skipped clauses, a name collision with the hidden input, a parenthesized-join input, an unaliased MATCH_RECOGNIZE, a table function without a column list, and the lineage of an aliased table function's column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uUGFKsqsLyKC6tprkPgFp
ravenac95
commented
Oct 6, 2026
ravenac95
left a comment
Member
Author
There was a problem hiding this comment.
DRY-focused review. 0 Critical, 1 Important, 2 Minor.
Spec compliance was not assessed: no Linear issue (out of scope for this pass). polyglot has no REVIEW.md; severities follow the code-reviewer taxonomy.
Generated by Claude Code
An aliased parenthesized join and an aliased MATCH_RECOGNIZE both registered their inner relations, hid them, and registered the item as a non-scope derived-table source under its alias. That sequence now lives in add_behind_alias, which absorbs hide_names; each caller passes only the closure that registers its inner relations. Reporting the join conditions behind an alias through `skipped` moves into skip_join_conditions, so the reason they stay unscoped is stated once. In the resolver, identifier_names replaces the three copies of the column-alias-to-name mapping used for aliased UNNEST, table functions and Hive LATERAL VIEW. Behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uUGFKsqsLyKC6tprkPgFp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
build_scopelost two kinds of aliased FROM items:my_func(x) AS gis parsed asAlias(Function).add_table_to_scoperecursed into the innerFunction, which registers nothing, so the alias was dropped andg.ycould not resolve.MATCH_RECOGNIZE.t MATCH_RECOGNIZE (...) AS mwas not handled at all: the whole item was reported throughScopeVisitor::skippedand nothing was registered, som.colcould not resolve either.This builds on #12 (now merged), which registers the relations inside parenthesized joins.
The change
Alias(Function)is now registered as a virtual source, the same way an aliasedUNNESTalready was; the function's arguments are reported throughskipped. In the resolver, the source's columns are the alias's column list (my_func(x) AS g(y, z)), or unknown when the alias has none (one sharedtable_function_output_columnshelper for both resolver paths).MATCH_RECOGNIZE. An aliasedMATCH_RECOGNIZEis registered as its alias withSourceKind::DerivedTableandis_scope = false, like an aliased parenthesized join. It is not registered asVirtualbecause lineage scans a virtual source's whole expression for column references, which would pick up theMEASURES/DEFINEpattern-variable references such asA.tstampas if they were real columns.ScopeVisitor::referenceatdepth + 1, before theMATCH_RECOGNIZEitself, but it adds no entry toScope::sourcesand a laterLATERALitem does not see it.skipped(through the sharedfor_each_join_condition) instead of getting subquery scopes.PARTITION BY,ORDER BY,MEASURESandDEFINEclauses are reported viaskipped. An unaliasedMATCH_RECOGNIZEis still reported whole throughskipped.MATCH_RECOGNIZEpaths through ahide_nameshelper.Behaviour changes visible to callers
qualify_columnsnow qualifies a reference to an aliased table function's column:SELECT x, y FROM t, my_func(t.x) AS g(y)becomesSELECT t.x AS x, g.y AS y FROM t, MY_FUNC(t.x) AS g(y).g.yto the function's arguments, under a synthetic_Nsource name (e.g._0.y) like other virtual sources, withsource_alias = "g".SELECT a FROM t, my_func(t.x) AS gno longer assumesaist.a.Known gaps, left for follow-up
qualify_columns, lineage'sget_source_name, and the ordered-source helpers do not yet recogniseAlias(Function)orMatchRecognize, sog.*and*miss those items' columns.MATCH_RECOGNIZEafter an aliased table (t AS x MATCH_RECOGNIZE (...)) or an aliased derived table, so those shapes cannot be tested yet.Tests
scope::tests::test_aliased_table_function_is_a_virtual_source:AS g, baregandAS g(y, z)registergas a virtual source, with the arguments skipped.scope::tests::test_aliased_match_recognize_hides_its_input(Snowflake and Oracle): the alias is a non-scopeDerivedTable; the input is reported atdepth + 1before the item; exactly the four clauses are skipped; an input that shares a name with an earlier source hides it only inside the item; a parenthesized-join input's condition is skipped and not scoped; an unaliasedMATCH_RECOGNIZEis still reported whole; a laterLATERALitem sees the alias but not the input.qualify_columns::tests::test_qualify_aliased_table_function_columns: with and without a column list.lineage::tests::test_lineage_aliased_table_function_is_a_virtual_source:g.ymaps to_0.y(virtual, aliasg), witht.xdownstream.Local CI
Run on the final tree with
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0:cargo fmt --all -- --check: cleanmake check-consistency: OK (15 tests, project consistent)cargo clippy -p polyglot-sql-ffi --all-targets --no-deps -- -D warnings: cleancargo clippy -p polyglot-sql-wasm --lib --no-deps -- -D warnings: cleanmake test-rust-verify-core: all greencargo test --lib -p polyglot-sqlprints no warnings. The first commit also passes the lib tests on its own (1342 passed).🤖 Generated with Claude Code
https://claude.ai/code/session_016uUGFKsqsLyKC6tprkPgFp
Generated by Claude Code