maedhroz commented on code in PR #3095:
URL: https://github.com/apache/cassandra/pull/3095#discussion_r1588595560


##########
src/java/org/apache/cassandra/cql3/Operator.java:
##########
@@ -324,23 +561,150 @@ public static Operator readFrom(DataInput input) throws 
IOException
           throw new IOException(String.format("Cannot resolve Relation.Type 
from binary representation: %s", b));
     }
 
+
     /**
      * Whether 2 values satisfy this operator (given the type they should be 
compared with).
      */
     public abstract boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer 
leftOperand, ByteBuffer rightOperand);
 
-    public int serializedSize()
+
+    public boolean isSatisfiedBy(CollectionType<?> type, ComplexColumnData 
leftOperand, ByteBuffer rightOperand)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public static int serializedSize()
     {
         return 4;
     }
 
+    public void validateFor(ColumnsExpression expression)
+    {
+        if (!this.canBeUsedWith(expression.kind()))
+            throw invalidRequest("%s cannot be used with %s relations", this, 
expression);
+
+        switch (expression.kind())
+        {
+            case SINGLE_COLUMN:
+                ColumnMetadata firstColumn = expression.firstColumn();
+                AbstractType<?> columnType = firstColumn.type;
+                if (isSlice())
+                {
+                    if (columnType.referencesDuration())
+                    {
+                        checkFalse(columnType.isCollection(), "Slice 
restrictions are not supported on collections containing durations");
+                        checkFalse(columnType.isTuple(), "Slice restrictions 
are not supported on tuples containing durations");
+                        checkFalse(columnType.isUDT(), "Slice restrictions are 
not supported on UDTs containing durations");
+                        throw invalidRequest("Slice restrictions are not 
supported on duration columns");
+                    }
+                }
+                else
+                {
+                    checkFalse(appliesToMapKeys() && !(columnType instanceof 
MapType), "Cannot use %s on non-map column %s", this, firstColumn.name);
+                    checkFalse(appliesToCollectionElements() && 
!columnType.isCollection(), "Cannot use %s on non-collection column %s", this, 
firstColumn.name);
+                }
+
+            case MAP_ELEMENT:
+                ColumnMetadata column = expression.firstColumn();
+                AbstractType<?> type = column.type;
+                if (type.isMultiCell())
+                {
+                    // Non-frozen UDTs don't support any operator
+                    checkFalse(type.isUDT(),
+                               "Non-frozen UDT column '%s' (%s) cannot be 
restricted by any relation",
+                               column.name,
+                               type.asCQL3Type());
+
+                    // We don't support relations against entire collections 
(unless they're frozen), like "numbers = {1, 2, 3}"
+                    checkFalse(type.isCollection()
+                                    && !this.appliesToMapKeys()
+                                    && !this.appliesToCollectionElements()
+                                    && expression.kind() != 
ColumnsExpression.Kind.MAP_ELEMENT,
+                               "Collection column '%s' (%s) cannot be 
restricted by a '%s' relation",
+                               column.name,
+                               type.asCQL3Type(),
+                               this);
+                }
+                break;
+        }
+    }
+
     /**
-     * Checks if this operator is a slice operator.
+     * Checks if the specified expression kind can be used with this operator.
+     * @param kind the expression kind
+     * @return {@code true} if the specified expression kind can be used with 
this operator, {@code false} otherwise.
+     */
+    public boolean canBeUsedWith(ColumnsExpression.Kind kind)
+    {
+        // All operators support single columns
+        return kind == ColumnsExpression.Kind.SINGLE_COLUMN;
+    }
+
+    /**
+     * Checks if this operator applies to non-multicell column values.
+     * @return {@code true} if this operator applies to column values, {@code 
false} otherwise.
+     */
+    public boolean appliesToColumnValues()
+    {
+        return true;
+    }
+
+    /**
+     * Checks if this operator applies to collection elements (from frozen and 
non-frozen collections).
+     * @return {@code true} if this operator applies to collection elements, 
{@code false} otherwise.
+     */
+    public boolean appliesToCollectionElements()
+    {
+        return false;
+    }
+
+    /**
+     * Checks if this operator applies to map keys.
+     * @return {@code true} if this operator applies to map keys, {@code 
false} otherwise.
+     */
+    public boolean appliesToMapKeys()
+    {
+        return false;
+    }
+
+    /**
+     * Restricts the specified range set based on the operator arguments 
(optional operation).
+     * @param rangeSet the range set to restrict
+     * @param args the operator arguments
+     * @return the restricted range set
+     */
+    public RangeSet<ClusteringElements> restrict(RangeSet<ClusteringElements> 
rangeSet, List<ClusteringElements> args)

Review Comment:
   nit: In general, I think it can be a little confusing on a first read that 
`restrict` both returns a `RangeSet` and modifies the passed `rangeSet` in 
place. Not sure what do to about that at the moment, unless we make everything 
operate in-place explicitly and remove the method return value option...



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to