Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement row alias expressions (INSERT ... VALUES (...) AS new_tbl ON DUPLICATE x = new_tbl.x) #2534

Merged
merged 4 commits into from
Jun 7, 2024

Conversation

nicktobey
Copy link
Contributor

@nicktobey nicktobey commented Jun 5, 2024

When inserting values, the user can specify names for both the source table and columns which are used in ON DUPLICATE expressions. It looks like either of the below options:

INSERT INTO tbl VALUES (1, 2) AS tbl_new ON DUPLICATE KEY b = tbl_new.b;

INSERT INTO tbl VALUES (1, 2) AS tbl_new(a_new, b_new) ON DUPLICATE KEY b = b_new;

This replaces the previous (now-deprecated) syntax:

INSERT INTO tbl VALUES (1, 2) ON DUPLICATE KEY b = VALUES(b);

Supporting both syntaxes together was non-trivial because it means there's now two different ways to refer to the same column. While he had an existing way to "redirect" one column name to another, this only worked for unqualified names (no table name), and it overrode the normal name resolution rules, which meant we would fail to detect cases that should be seen as ambiguous.

Previously, we would implement references to the inserted values by using a special table named "__new_ins". I implemented this by keeping that as the default, but using the row alias instead of one was provided. We then create a map from the destination table names to column aliases, and use that map to rewrite expressions that appear inside the VALUES() function.

Copy link

github-actions bot commented Jun 5, 2024

Additional work is required for integration with Dolt.
Additional work is required for integration with DoltgreSQL.

@nicktobey nicktobey force-pushed the nicktobey/row-alias branch 2 times, most recently from c167e84 to 2ce30b5 Compare June 6, 2024 16:17
…e inserted rows), add that name to the scope instead of the default "__new_ins"
@nicktobey nicktobey force-pushed the nicktobey/row-alias branch from 6d4cfc1 to 88f20f3 Compare June 6, 2024 23:36
@nicktobey nicktobey marked this pull request as ready for review June 6, 2024 23:56
@nicktobey
Copy link
Contributor Author

Fixes dolthub/dolt#7638

Copy link
Contributor

@max-hoffman max-hoffman left a comment

Choose a reason for hiding this comment

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

LGTM, I don't love making ON DUP EXPRS more complicated, but there aren't a lot of faster practical alternatives. Like most of the complexity around INSERTs, we should probably do something that reorders/normalizes insert value ordering to avoid extra complexity in the rest of analysis.

Comment on lines 50 to 51
insertTableAlias string
insertColumnAliases map[string]string
Copy link
Contributor

Choose a reason for hiding this comment

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

can we limit these variables to a single scope? the rest of these objects explicitly outlive a single query

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Limited it to two scopes (insert scope and combined scope)

v.Name.Qualifier.Name = ast.NewTableIdent(OnDupValuesPrefix)
v.Name.Qualifier.Name = ast.NewTableIdent(b.insertTableAlias)
if len(b.insertColumnAliases) > 0 {
v.Name.Name = ast.NewColIdent(b.insertColumnAliases[v.Name.Name.String()])
Copy link
Contributor

Choose a reason for hiding this comment

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

strings to lower?

// The to-be-inserted values can be referenced via the provided alias.
c.table = b.insertTableAlias
if len(b.insertColumnAliases) > 0 {
aliasColumnName := b.insertColumnAliases[c.col]
Copy link
Contributor

Choose a reason for hiding this comment

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

strings to lower?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lowered the string on insert into the map.

b.insertColumnAliases = make(map[string]string)
for i, destColumn := range columns {
sourceColumn := aliasedValues.Columns[i].String()
b.insertColumnAliases[destColumn] = sourceColumn
Copy link
Contributor

Choose a reason for hiding this comment

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

lower strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link

github-actions bot commented Jun 7, 2024

Additional work is required for integration with Dolt.

1 similar comment
Copy link

github-actions bot commented Jun 7, 2024

Additional work is required for integration with Dolt.

@nicktobey nicktobey merged commit 3a90cae into main Jun 7, 2024
8 checks passed
@nicktobey nicktobey deleted the nicktobey/row-alias branch June 7, 2024 23:29
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