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

CASSANDRA-19604 Add support for BETWEEN operator #3301

Open
wants to merge 10 commits into
base: trunk
Choose a base branch
from

Conversation

xvade
Copy link

@xvade xvade commented May 10, 2024

Copy link
Contributor

@blerer blerer left a comment

Choose a reason for hiding this comment

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

Nice work! I left a few comments for the parts that could be improved and the ones I forgot to mention before.

src/java/org/apache/cassandra/cql3/Operator.java Outdated Show resolved Hide resolved
src/java/org/apache/cassandra/cql3/Operator.java Outdated Show resolved Hide resolved
@@ -266,6 +266,59 @@ public boolean canBeUsedWith(ColumnsExpression.Kind kind)
return kind != ColumnsExpression.Kind.MAP_ELEMENT;
}
},
BETWEEN(16)
Copy link
Contributor

Choose a reason for hiding this comment

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

I did not thought about it before but I am guessing that BETWEEN is breaking the toString method of Relation and SimpleRestriction. RelationTest contains some tests for the Relation method.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering why BETWEEN(16) is not after 15?

Copy link
Author

@xvade xvade May 14, 2024

Choose a reason for hiding this comment

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

I am wondering why BETWEEN(16) is not after 15?

It seemed that the convention in Operator.java was not super strict about ordering operations numerically, and so I opted to put it with the slices because that seemed like a fitting way of ordering in lieu of by index. It would also make a ton of sense to put it after 15, but I'd be inclined to reorder or renumber the rest of the file to fit the numbering convention if we did that.

Copy link
Contributor

Choose a reason for hiding this comment

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

What you say make sense. There is a separation between the serialization value of an Operator and the enum order. Now, the issue is that people will pick the last number of the list and use the next one for the serialization of the next enum they will add. It is not perfect but I will still put between at the end to avoid this issue that can make people lose time trying to figure out what is going on when they run into an issue with the tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was wondering, maybe we want to add a defensive unit test that will check the numbers used and break if someone does something wrong or when they add a new operator (they will have to update it)?

@Test
   public void testOperatorBinaryRepresentation() 
   {
       int[] expectedValues = {0, 4, 3, 1, 2, 7, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15};
       Operator[] operators = Operator.values();

       assertEquals("Number of operators has changed", expectedValues.length, operators.length);

       for (int i = 0; i < operators.length; i++) 
       {
           assertEquals("Operator " + operators[i].name() + " has incorrect value", expectedValues[i], operators[i].getValue());
       }
   }

This test will fail if the number of operators or the b value of any operator is changed. It will also fail if a new operator is added but does not take the next number in line. We can add a comment for people to update it when it fails on new operator addition.

@xvade xvade force-pushed the between branch 3 times, most recently from eb4203f to 7ae6453 Compare May 20, 2024 19:09
Copy link
Contributor

@ekaterinadimitrova2 ekaterinadimitrova2 left a comment

Choose a reason for hiding this comment

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

Overall looks great, I left some very tiny comments.
Question: I see you updated the ticket about NOT BETWEEN, do you plan to add it later?

@@ -390,17 +390,17 @@ def test_complete_in_update(self):
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey ",
choices=[',', ')'])
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey) ",
choices=['=', '<=', '>=', '<', '>'])
choices=['=', '<=', '>=', 'BETWEEN', '<', '>'])
Copy link
Contributor

Choose a reason for hiding this comment

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

We do not support BETWEEN in UPDATE?

Copy link
Author

Choose a reason for hiding this comment

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

Oops!

Copy link
Contributor

Choose a reason for hiding this comment

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

We discuss that with @ekaterinadimitrova2 . The issue is that this part is common to all the statements using the WHERE clause.

Copy link
Contributor

@blerer blerer left a comment

Choose a reason for hiding this comment

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

I have added 2 changes proposals here

Comment on lines 1814 to 1815
| K_BETWEEN literals=betweenLiterals
{ $clauses.add(Relation.multiColumn(ids, Operator.BETWEEN, literals)); }
Copy link
Contributor

Choose a reason for hiding this comment

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

The current change support literals (BETWEEN 1 AND 2) but not markers (BETWEEN ? AND ?).

src/antlr/Parser.g Show resolved Hide resolved
@@ -114,6 +115,7 @@ public static Relation mapElement(ColumnIdentifier identifier, Term.Raw rawKey,
public static Relation multiColumn(List<ColumnIdentifier> identifiers, Operator operator, Term.Raw rawTerm)
{
assert operator != Operator.IN;
assert operator != Operator.BETWEEN;
Copy link
Contributor

Choose a reason for hiding this comment

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

you can combine them in a single assertion assert operator != Operator.IN && operator != Operator.BETWEEN;

@@ -266,6 +266,59 @@ public boolean canBeUsedWith(ColumnsExpression.Kind kind)
return kind != ColumnsExpression.Kind.MAP_ELEMENT;
}
},
BETWEEN(16)
Copy link
Contributor

Choose a reason for hiding this comment

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

What you say make sense. There is a separation between the serialization value of an Operator and the enum order. Now, the issue is that people will pick the last number of the list and use the next one for the serialization of the next enum they will add. It is not perfect but I will still put between at the end to avoid this issue that can make people lose time trying to figure out what is going on when they run into an issue with the tests.

@xvade xvade force-pushed the between branch 2 times, most recently from 1c51f92 to af04297 Compare May 28, 2024 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants