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

Fix parentheses behaviour #131

Merged
merged 4 commits into from
Jul 22, 2020
Merged

Fix parentheses behaviour #131

merged 4 commits into from
Jul 22, 2020

Conversation

asdine
Copy link
Collaborator

@asdine asdine commented Jul 19, 2020

This PR changes how parentheses were parsed by the parser. Previously, they were considered as lists of expressions, which after evaluation turned into an array. This behaviour prevented us from using parentheses as arithmetic sub expressions.

Before:

genji> select ((10 + 5 + 5) * 4) / 2;
{
  "((10 + 5 + 5) * 4) / 1": null
}
genji> select ((10 + 5 + 5) * 4);
{
  "((10 + 5 + 5) * 4)": [
    null
  ]
}

After:

genji> select ((10 + 5 + 5) * 4) / 2;
{
  "((10 + 5 + 5) * 4) / 1": 40
}
genji> select ((10 + 5 + 5) * 4);
{
  "((10 + 5 + 5) * 4)": 80
}

Copy link
Collaborator

@yaziine yaziine left a comment

Choose a reason for hiding this comment

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

Only one question otherwise it looks good 👍

Comment on lines +125 to +126
// It hides the underlying operator, if any, from the parser
// so that it doesn't get reordered by precedence.
Copy link
Collaborator

Choose a reason for hiding this comment

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

What does that mean exactly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In SQL, operators are ordered by precedence, for example, * has higher precedence than +, which means it must be evaluated first:

3 + 4 * 2
# 4 * 2 is evaluated first
3 + 8
# then + is evaluated
11

If you want to avoid that, you can use parentheses

(3 + 4) * 2
# 3 + 4 is evaluated first
7 * 2
# then * is evaluated
14

This behavior is done in the parser, when parsing the expression: https://github.com/genjidb/genji/blob/454cc983db979394c310a5a5df0e1180fb0f1447/sql/parser/expr.go#L30-L78

This function builds a tree based on operator precedence.
To avoid an expression in parentheses to have its precedence analyzed and taken into account by that function (these two lines) we "hide" it by wrapping it in a type that doesn't implement the Operator interface so that in the eye of these two lines, that expression is unary, not binary.

Base automatically changed from simpler-types to master July 22, 2020 12:42
@asdine asdine merged commit 672025a into master Jul 22, 2020
@asdine asdine deleted the fix-parentheses-behavior branch July 22, 2020 13:02
@asdine asdine added this to the v0.7.0 milestone Aug 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants