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]