Skip to content

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.

() -> 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 matriv requested review from costin and rw-access September 17, 2020 16:50
@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