-
Notifications
You must be signed in to change notification settings - Fork 573
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
fix(presto): fix DELETE DML statement for presto/trino #3466
fix(presto): fix DELETE DML statement for presto/trino #3466
Conversation
sqlglot/dialects/presto.py
Outdated
for column in expression.find_all(exp.Column): | ||
if column.table == table_alias: | ||
del column.args["table"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if getting rid of the table
like this is safe / correct. Eg. what happens if there's a db or catalog? We would probably need to do expression.transform(transforms.unqualify_columns)
on the filter child.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont know what happens if there's a db or catalog. Can you explain it, please?
I think each column belongs to a table, so a column only have a table_alias (or table name) stored into column.table property. I will correct the table name case.
Edit: Maybe transforms.unqualify_columns
work like a charm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont know what happens if there's a db or catalog. Can you explain it, please?
Previously we were only popping off the column's table
, and I was wondering if this could lead to an inconsistent state where a column that original had a fully-qualified name (catalog
, db
, table
, this
) would only get its table
removed.
This probably can't happen for the columns of the table we're deleting from, since you'd qualify the columns of that table using only the alias, so there's no catalog/db. But it could happen for columns of other tables, eg. referenced in a subquery inside of the WHERE
clause:
DELETE FROM db.t1 AS t1 WHERE NOT t1.c IN (SELECT db.t2.c FROM db.t2 LEFT JOIN db.t3 USING (id));
Btw, the current approach will also unqualify db.t2.c
here, which could make the subquery ambiguous, e.g. if c
existed in both t2
and t3
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I got it.
Btw, the current approach will laso unqualify db.t2.c here, which could make the subquery ambiguous, e.g. if c existed in both t2 and t3.
Is there any function to fully qualify the catalog/db/table to the column? After that we can just remove the alias and thing should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is only used to aid the transpilation, which is best-effort, I think I'd just keep what you have but move the unqualify_columns
transformation inside the branch that checks if there is an alias. We don't want to always unqualify columns, right? We only need it if the target table is aliased.
That way, we won't deal with the case I described above when transpiling to presto/trino, but that's ok I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @tobymao can you also take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@georgesittas Should we always remove table alias, and always keep the fully qualified column?
Prototype code seems to my first version:
table_alias = table.alias
if table_alias:
del table.args["alias"]
for column in expression.find_all(exp.Column):
if column.table == table_alias and not column.catalog and not column.db:
del column.args["table"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll get this in and do a quick refactor, will share with you in a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Jo <46752250+georgesittas@users.noreply.github.com>
Thanks a lot for these PRs @viplazylmht 👍 |
Context
Documentation
Reproduce
Prerequisite
Test DELETE DML statement
So, when transpiling, we have to handle the delete_sql to make Presto/Trino happy.
Solution
Test
Discussion
Should we raise an error if there is more than one table to be deleted when transpiling to presto/trino dialect?