fix(postgres): preserve NOT LIKE quantifiers during generation#7611
fix(postgres): preserve NOT LIKE quantifiers during generation#7611bialkou wants to merge 1 commit intotobymao:mainfrom
Conversation
georgesittas
left a comment
There was a problem hiding this comment.
Hey @bialkou, thanks for raising this issue & submitting a PR.
It seems like there's indeed a bug, but the approach here isn't quite right. The root issue in main today is that the two syntactical forms produce the same AST, despite their semantics being different:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT a NOT LIKE ALL (b)") == sqlglot.parse_one("SELECT NOT a LIKE ALL (b)")
TrueThis means that the parser's logic is erroneous, not the generator's. What you did here simply trades one bug for the other, because we'll get the other syntax now for the two inputs when converting their ASTs to SQL.
I think we want to address the issue by adding a new optional arg, "negate": False in Like (and ILike), which is used to:
- Preserve the original
ALL/ANYintent in the AST itself; an alternative is to flip the quantifier (e.g., fromALLtoANY) when there is a negation, but that results in a lossy conversion because we now lose the original intent - Help distinguish between
x NOT LIKE ALLandNOT x LIKE ALLat the AST level - Give the generator enough information to emit correct SQL for both forms
In the parser logic, I think you'd need to modify _negate_range to set the arg for Like (and ILike) instead of blindly wrapping the node with a Not. And finally, in the corresponding generator methods you now have to respect the negate arg, by emitting the corresponding NOT.
fca63de to
a8045b0
Compare
|
Thanks! That makes sense. So, based on your suggestions, I made the following changes:
The TPC-H fixture changes only update the expected optimized SQL output to match the new canonical "NOT LIKE" generation. The original TPC-H input queries are unchanged. |
Fixes PostgreSQL generation for quantified NOT LIKE/NOT ILIKE expressions.
sqlglot represents x NOT LIKE ALL (...) as Not(Like(..., All(...))). The generator emits NOT x LIKE ALL (...), which is wrong for PostgreSQL and can change query results.
The fix preserves native NOT LIKE / NOT ILIKE quantified syntax when the dialect supports LIKE quantifiers, while keeping explicit external negation unchanged:
Tests: