-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
EQL: Disallow chained comparisons #62567
Conversation
Expressions like `1 = 2 = 3 = 4` or `1 < 2 = 3 >= 4` were treated with leftmost priority: ((1 = 2) = 3) = 4 which can lead to confusing results. Since such expressions don't make so much change for EQL filters we disallow them in the parser to prevent unexpected results from their bad usage. Major DBs like PostgreSQL and Oracle also disallow them in their SQL syntax. (counter example would be MySQL which interprets them as we did before with leftmost priority). Fixes: elastic#61654
Pinging @elastic/es-ql (:Query Languages/EQL) |
/cc @jrodewig |
| left=defaultExpression comparisonOperator right=defaultExpression #comparison | ||
; | ||
|
||
defaultExpression |
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.
Please let me know of a better suggestion for this name as I really couldn't come up with one.
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.
looks like these are all arithmetic, so maybe arithmeticExpression
?
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 opt for operators (operatorExpression
) since the block contains arithmetic and comparison operators, the latter being logical not arithmetic.
@@ -221,4 +221,25 @@ public void testInEmptySet() { | |||
expectThrows(ParsingException.class, "Expected syntax error", | |||
() -> expr("name in ()")); | |||
} | |||
|
|||
public void testChainedComparisons() { |
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.
Can you add a test for something like 1 * 2 <= 3 * 4
, just to make sure these operators are still playing nicely with precedence for other operators. Even better would be to verify the AST matches this: (1 * 2) <= (3 * 4)
Btw the new grammar was also checked with |
new Neg(null, new Literal(null, 3, DataTypes.INTEGER)), | ||
new Literal(null, 4, DataTypes.INTEGER)); | ||
|
||
assertEquals(new LessThanOrEqual(null, left, right, UTC), expr(comparison)); |
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.
could also do this, although it doesn't make assertions on what the underlying trees are, just that they are equivalent
assertEquals(expr("1 * -2 <= -3 * 4"), expr("(1 * -2) <= (-3 * 4)"))
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 @matriv!
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.
lgtm
| left=defaultExpression comparisonOperator right=defaultExpression #comparison | ||
; | ||
|
||
defaultExpression |
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 opt for operators (operatorExpression
) since the block contains arithmetic and comparison operators, the latter being logical not arithmetic.
; | ||
|
||
defaultExpression | ||
: primaryExpression predicate? #defaultExpressionDefault |
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.
defaultExpressionDefault
-> operatorExpressionDefault
Expressions like `1 = 2 = 3 = 4` or `1 < 2 = 3 >= 4` were treated with leftmost priority: ((1 = 2) = 3) = 4 which can lead to confusing results. Since such expressions don't make so much change for EQL filters we disallow them in the parser to prevent unexpected results from their bad usage. Major DBs like PostgreSQL and Oracle also disallow them in their SQL syntax. (counter example would be MySQL which interprets them as we did before with leftmost priority). Fixes: #61654 (cherry picked from commit 8f94981)
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.
LGTM
Expressions like
1 = 2 = 3 = 4
or1 < 2 = 3 >= 4
were treated withleftmost priority: ((1 = 2) = 3) = 4 which can lead to confusing
results. Since such expressions don't make so much change for EQL
filters we disallow them in the parser to prevent unexpected results
from their bad usage.
Major DBs like PostgreSQL and Oracle also disallow them in their SQL
syntax. (counter example would be MySQL which interprets them as we did
before with leftmost priority).
Fixes: #61654