Skip to content

Create scope mapping for views#3379

Merged
nicktobey merged 8 commits intomainfrom
nicktobey/view
Jan 23, 2026
Merged

Create scope mapping for views#3379
nicktobey merged 8 commits intomainfrom
nicktobey/view

Conversation

@nicktobey
Copy link
Copy Markdown
Contributor

@nicktobey nicktobey commented Jan 15, 2026

This is a partial fix for dolthub/dolt/issues/10297

When parsing a subquery alias, we create a new column id for each column in the SQA schema. The scope mapping is a dictionary on the SQA node that maps those column ids onto the expressions within the subquery that determine their values, and is used in some optimizations. For example, in order to push a filter into a subquery, we need to use the scope mapping to replace any GetFields that were pointing to the SQA with the expressions those fields map to. If for whatever reason the SQA doesn't have a scope mapping, we can't perform that optimization.

We parse views by recursively calling the parser on the view definition. This works but it means that the original parser doesn't have any references to the expressions inside the view, which prevents us from creating the scope mapping.

This PR attempts to fix this. Instead of defining the SQA columns in the original parser (where we no longer have access to the view's scope), we now create the columns while parsing the view, and attach them to the scope object for the view definition. Then we store that scope in a field on the Builder, so that the original parser can copy them into its own scope.

This feels hacky, but was the best way I could think of to generate the scope mappings and ensure they're visible outside the view.

Copy link
Copy Markdown
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever approach, one suggestion to make it less error prone.

colId columnId
tabId sql.TableId
colId columnId
subqueryScope *scope
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple way to make this significantly less hacky and prone to error would be to create a clone of the builder in resolveView, and return the scope it obtained during building as one of the results of resolveView. Then the main builder never has this field set to a value that's inappropriate to the context, e.g. when parsing two views in the same query. It also guards against the case of views that themselves contain views recursively (which you should make sure you have a test for). Also make sure to document the purpose of this field in the struct, as it's pretty mysterious otherwise. Also recommend calling it resolveViewScope or similar.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to remove the field entirely by passing the scope as a return value.

@nicktobey nicktobey merged commit 1dbd097 into main Jan 23, 2026
8 checks passed
@nicktobey nicktobey deleted the nicktobey/view branch January 23, 2026 04:40
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.

2 participants