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

EQL: Disallow chained comparisons #62567

Merged
merged 7 commits into from
Sep 18, 2020
Merged

EQL: Disallow chained comparisons #62567

merged 7 commits into from
Sep 18, 2020

Conversation

matriv
Copy link
Contributor

@matriv matriv commented Sep 17, 2020

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

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
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-ql (:Query Languages/EQL)

@elasticmachine elasticmachine added the Team:QL (Deprecated) Meta label for query languages team label Sep 17, 2020
@matriv
Copy link
Contributor Author

matriv commented Sep 17, 2020

/cc @jrodewig

| left=defaultExpression comparisonOperator right=defaultExpression #comparison
;

defaultExpression
Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Member

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() {
Copy link
Contributor

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)

@matriv
Copy link
Contributor Author

matriv commented Sep 17, 2020

Btw the new grammar was also checked with LL_EXACT_AMBIG_DETECTION without issues.

new Neg(null, new Literal(null, 3, DataTypes.INTEGER)),
new Literal(null, 4, DataTypes.INTEGER));

assertEquals(new LessThanOrEqual(null, left, right, UTC), expr(comparison));
Copy link
Contributor

@rw-access rw-access Sep 17, 2020

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)"))

Copy link
Contributor

@rw-access rw-access left a comment

Choose a reason for hiding this comment

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

thanks @matriv!

Copy link
Member

@costin costin left a 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
Copy link
Member

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
Copy link
Member

Choose a reason for hiding this comment

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

defaultExpressionDefault -> operatorExpressionDefault

@matriv matriv merged commit 8f94981 into elastic:master Sep 18, 2020
@matriv matriv deleted the fix-61654 branch September 18, 2020 08:00
matriv added a commit that referenced this pull request Sep 18, 2020
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)
@costin costin mentioned this pull request Sep 18, 2020
7 tasks
Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

EQL: ambiguous syntax for chained predicates
6 participants