Add support for NOT operators in WHERE clauses (CASSANDRA-18584)

In addition - Fixed Three Valued Logic

patch by Piotr Kolaczkowski; reviewed by Benjamin Lerer, Ekaterina Dimitrova, Andres de la Pena for CASSANDRA-18584

Co-authored-by: Benjamin Lerer <b.lerer@gmail.com>
Co-authored by: Ekaterina Dimitrova<ekaterina.dimitrova@datastax.com>
This commit is contained in:
Benjamin Lerer 2024-03-21 11:11:10 +01:00 committed by Ekaterina Dimitrova
parent 8d154ba66f
commit e0074a31ef
21 changed files with 1593 additions and 98 deletions

View File

@ -1,4 +1,5 @@
5.1
* Add support for NOT operators in WHERE clauses. Fixed Three Valued Logic (CASSANDRA-18584)
* Allow getendpoints for system tables and make sure getNaturalReplicas work for MetaStrategy (CASSANDRA-19846)
* On upgrade, handle pre-existing tables with unexpected table ids (CASSANDRA-19845)
* Reconfigure CMS before assassinate (CASSANDRA-19768)

View File

@ -940,6 +940,10 @@ bc(syntax)..
| <identifier> IN <variable>
| '(' <identifier> (',' <identifier>)* ')' IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' IN <variable>
| <identifier> NOT IN '(' ( <term> ( ',' <term>)* )? ')'
| <identifier> NOT IN <variable>
| '(' <identifier> (',' <identifier>)* ')' NOT IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' NOT IN <variable>
<option> ::= TIMESTAMP <integer>
| TTL <integer>
@ -993,12 +997,16 @@ bc(syntax)..
<where-clause> ::= <relation> ( AND <relation> )*
<relation> ::= <identifier> <op> <term>
<relation> ::= <identifier> (<op> | NOT CONTAINS ( KEY )?) <term>
| '(' <identifier> (',' <identifier>)* ')' <op> <term-tuple>
| <identifier> IN '(' ( <term> ( ',' <term>)* )? ')'
| <identifier> IN <variable>
| '(' <identifier> (',' <identifier>)* ')' IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' IN <variable>
| <identifier> NOT IN '(' ( <term> ( ',' <term>)* )? ')'
| <identifier> NOT IN <variable>
| '(' <identifier> (',' <identifier>)* ')' NOT IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' NOT IN <variable>
<op> ::= '=' | '<' | '>' | '<=' | '>=' | CONTAINS ( KEY )?
<in-values> ::= (<variable> | '(' ( <term> ( ',' <term> )* )? ')')
@ -1118,9 +1126,11 @@ bc(syntax)..
| '(' <identifier> (',' <identifier>)* ')' <op> <term-tuple>
| <identifier> IN '(' ( <term> ( ',' <term>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| <identifier> NOT IN '(' ( <term> ( ',' <term>)* )? ')'
| '(' <identifier> (',' <identifier>)* ')' NOT IN '(' ( <term-tuple> ( ',' <term-tuple>)* )? ')'
| TOKEN '(' <identifier> ( ',' <identifer>)* ')' <op> <term>
<op> ::= '=' | '<' | '>' | '<=' | '>=' | CONTAINS | CONTAINS KEY
<op> ::= '=' | '<' | '>' | '<=' | '>=' | CONTAINS | CONTAINS KEY | NOT CONTAINS | NOT CONTAINS KEY
<group-by> ::= (<identifier>,)* (<identifier> | <function>)
<order-by> ::= <ordering> ( ',' <odering> )*
<ordering> ::= <identifer> ( ASC | DESC )?

View File

@ -16,6 +16,6 @@ where_clause::= `relation` ( AND `relation` )*
relation::= column_name operator term
'(' column_name ( ',' column_name )* ')' operator tuple_literal
TOKEN '(' column_name# ( ',' column_name )* ')' operator term
operator::= '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | CONTAINS | CONTAINS KEY
operator::= '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | NOT IN | CONTAINS | NOT CONTAINS | CONTAINS KEY | NOT CONTAINS KEY
group_by_clause::= column_name ( ',' column_name )*
ordering_clause::= column_name [ ASC | DESC ] ( ',' column_name [ ASC | DESC ] )*

View File

@ -6,6 +6,7 @@ The following describes the changes in each version of CQL.
* Add support for the BETWEEN operator in WHERE clauses (`19604`)
* Add support for GENERATED PASSWORD clause (`17457`)
* Add support for NOT operator in WHERE clauses ('18584')
== 3.4.7

View File

@ -1686,7 +1686,7 @@ FROM +
| `(' (`,' )* `)' IN `(' ( ( `,' )* )? `)' +
| TOKEN `(' ( `,' )* `)'
::= `=' | `<' | `>' | `<=' | `>=' | CONTAINS | CONTAINS KEY +
::= `=' | `<' | `>' | `<=' | `>=' | CONTAINS | CONTAINS KEY | NOT CONTAINS | NOT CONTAINS KEY +
::= (`,' )* +
::= ( `,' )* +
::= ( ASC | DESC )? +

View File

@ -738,11 +738,11 @@ syntax_rules += r'''
;
<whereClause> ::= <relation> ( "AND" <relation> )*
;
<relation> ::= [rel_lhs]=<cident> ( "[" <term> "]" )? ( "=" | "<" | ">" | "<=" | ">=" | "CONTAINS" ( "KEY" )? ) <term>
<relation> ::= [rel_lhs]=<cident> ( "[" <term> "]" )? ( "=" | "<" | ">" | "<=" | ">=" | "!=" | ( "NOT" )? "CONTAINS" ( "KEY" )? ) <term>
| token="TOKEN" "(" [rel_tokname]=<cident>
( "," [rel_tokname]=<cident> )*
")" ("=" | "<" | ">" | "<=" | ">=") <tokenDefinition>
| [rel_lhs]=<cident> "IN" "(" <term> ( "," <term> )* ")"
| [rel_lhs]=<cident> (( "NOT" )? "IN" ) "(" <term> ( "," <term> )* ")"
| [rel_lhs]=<cident> "BETWEEN" <term> "AND" <term>
;
<selectClause> ::= "DISTINCT"? <selector> ("AS" <cident>)? ("," <selector> ("AS" <cident>)?)*

View File

@ -381,7 +381,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonel",
immediate='ykey ')
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey ",
choices=['=', '<=', '>=', '>', '<', 'BETWEEN', 'CONTAINS', 'IN', '['])
choices=['=', '<=', '>=', '>', '<', '!=', 'BETWEEN', 'CONTAINS', 'IN', 'NOT', '['])
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey = 0.0 ",
choices=['AND', 'IF', ';'])
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey = 0.0 AND ",
@ -397,7 +397,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
choices=['EXISTS', '<quotedName>', '<identifier>'])
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey) <= TOKEN(13) IF EXISTS ",
choices=['>=', '!=', '<=', 'IN', '[', ';', '=', '<', '>', '.', 'CONTAINS'])
choices=['>=', '!=', '<=', 'IN','[', ';', '=', '<', '>', '.', 'CONTAINS'])
self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey) <= TOKEN(13) IF lonelykey ",
choices=['>=', '!=', '<=', 'IN', '=', '<', '>', 'CONTAINS'])
@ -464,7 +464,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
choices=['a', 'b', 'TOKEN('])
self.trycompletions('DELETE FROM twenty_rows_composite_table USING TIMESTAMP 0 WHERE a ',
choices=['<=', '>=', 'BETWEEN', 'CONTAINS', 'IN', '[', '=', '<', '>'])
choices=['<=', '>=', 'BETWEEN', 'CONTAINS', 'IN', 'NOT' , '[', '=', '<', '>', '!='])
self.trycompletions('DELETE FROM twenty_rows_composite_table USING TIMESTAMP 0 WHERE TOKEN(',
immediate='a ')

View File

@ -1756,7 +1756,7 @@ columnCondition returns [ColumnCondition.Raw condition]
// Note: we'll reject duplicates later
: column=cident
( op=relationType t=term { $condition = ColumnCondition.Raw.simpleCondition(column, op, Terms.Raw.of(t)); }
| op=containsOperator t=term { $condition = ColumnCondition.Raw.simpleCondition(column, op, Terms.Raw.of(t)); }
| K_CONTAINS (K_KEY)? t=term { $condition = ColumnCondition.Raw.simpleCondition(column, $K_KEY != null ? Operator.CONTAINS_KEY : Operator.CONTAINS, Terms.Raw.of(t)); }
| K_IN v=singleColumnInValues { $condition = ColumnCondition.Raw.simpleCondition(column, Operator.IN, v); }
| '[' element=term ']'
( op=relationType t=term { $condition = ColumnCondition.Raw.collectionElementCondition(column, element, op, Terms.Raw.of(t)); }
@ -1804,8 +1804,8 @@ relation[WhereClause.Builder clauses]
| K_BETWEEN betweenValues=singleColumnBetweenValues { $clauses.add(Relation.singleColumn(name, Operator.BETWEEN, betweenValues)); }
| K_LIKE t=term { $clauses.add(Relation.singleColumn(name, Operator.LIKE, t)); }
| K_IS K_NOT K_NULL { $clauses.add(Relation.singleColumn(name, Operator.IS_NOT, Constants.NULL_LITERAL)); }
| K_IN inValue=singleColumnInValues { $clauses.add(Relation.singleColumn(name, Operator.IN, inValue)); }
| rt=containsOperator t=term { $clauses.add(Relation.singleColumn(name, rt, t)); }
| rtInOperator=inOperator inValue=singleColumnInValues { $clauses.add(Relation.singleColumn(name, rtInOperator, inValue)); }
| rtContainsOperator=containsOperator t=term { $clauses.add(Relation.singleColumn(name, rtContainsOperator, t)); }
)
| K_TOKEN l=tupleOfIdentifiers
( type=relationType t=term { $clauses.add(Relation.token(l, type, t)); }
@ -1813,7 +1813,7 @@ relation[WhereClause.Builder clauses]
)
| name=cident '[' key=term ']' type=relationType t=term { $clauses.add(Relation.mapElement(name, key, type, t)); }
| ids=tupleOfIdentifiers
( K_IN inValue=multiColumnInValues { $clauses.add(Relation.multiColumn(ids, Operator.IN, inValue)); }
( rt=inOperator inValue=multiColumnInValues { $clauses.add(Relation.multiColumn(ids, rt, inValue)); }
| type=relationType v=multiColumnValue {$clauses.add(Relation.multiColumn(ids, type, v)); }
| K_BETWEEN t1=multiColumnValue K_AND t2=multiColumnValue { $clauses.add(Relation.multiColumn(ids, Operator.BETWEEN, Terms.Raw.of(List.of(t1, t2)))); }
)
@ -1822,6 +1822,12 @@ relation[WhereClause.Builder clauses]
containsOperator returns [Operator o]
: K_CONTAINS { o = Operator.CONTAINS; } (K_KEY { o = Operator.CONTAINS_KEY; })?
| K_NOT K_CONTAINS { o = Operator.NOT_CONTAINS; } (K_KEY { o = Operator.NOT_CONTAINS_KEY; })?
;
inOperator returns [Operator o]
: K_IN { o = Operator.IN; }
| K_NOT K_IN { o = Operator.NOT_IN; }
;
inMarker returns [Terms.Raw marker]

View File

@ -326,7 +326,8 @@ public enum Operator
IN(7)
{
@Override
public Kind kind() {
public Kind kind()
{
return Kind.MULTI_VALUE;
}
@ -408,6 +409,12 @@ public enum Operator
{
return true;
}
@Override
public Operator negate()
{
return NOT_CONTAINS;
}
},
CONTAINS_KEY(6)
{
@ -443,6 +450,12 @@ public enum Operator
{
return true;
}
@Override
public Operator negate()
{
return NOT_CONTAINS_KEY;
}
},
NEQ(8)
{
@ -479,10 +492,17 @@ public enum Operator
return leftOperand == null || type.compareCQL(leftOperand, elements) != 0;
}
@Override
public void restrict(RangeSet<ClusteringElements> rangeSet, List<ClusteringElements> args)
{
assert args.size() == 1;
rangeSet.remove(ClusteringElements.notEqualTo(args.get(0)));
}
@Override
public boolean requiresFilteringOrIndexingFor(ColumnMetadata.Kind columnKind)
{
return !columnKind.isPrimaryKeyKind();
return columnKind != ColumnMetadata.Kind.CLUSTERING;
}
@Override
@ -491,11 +511,23 @@ public enum Operator
return EQ;
}
@Override
public boolean isSupportedByRestrictionsOn(ColumnsExpression expression)
{
return true;
}
@Override
protected boolean isSupportedByReadPath()
{
return false;
}
@Override
public boolean isSlice()
{
return true;
}
},
IS_NOT(9)
{
@ -606,10 +638,143 @@ public enum Operator
return true;
}
},
NOT_IN(16)
{
@Override
public Kind kind()
{
return Kind.MULTI_VALUE;
}
@Override
public String toString()
{
return "NOT IN";
}
@Override
public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
{
return !IN.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean isSatisfiedBy(MultiElementType<?> type, ComplexColumnData leftOperand, ByteBuffer rightOperand)
{
return !IN.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean requiresFilteringOrIndexingFor(ColumnMetadata.Kind columnKind)
{
return columnKind != ColumnMetadata.Kind.CLUSTERING;
}
@Override
public void restrict(RangeSet<ClusteringElements> rangeSet, List<ClusteringElements> args)
{
for (ClusteringElements clustering : args)
rangeSet.remove(ClusteringElements.notEqualTo(clustering));
}
@Override
public Operator negate()
{
return IN;
}
@Override
public boolean isSlice()
{
return true;
}
@Override
public boolean isSupportedByRestrictionsOn(ColumnsExpression expression)
{
return expression.kind() == ColumnsExpression.Kind.SINGLE_COLUMN || expression.kind() == ColumnsExpression.Kind.MULTI_COLUMN;
}
},
NOT_CONTAINS(17)
{
@Override
public String toString()
{
return "NOT CONTAINS";
}
@Override
public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
{
return !CONTAINS.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean isSatisfiedBy(MultiElementType<?> type, ComplexColumnData leftOperand, ByteBuffer rightOperand)
{
return !CONTAINS.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean appliesToColumnValues()
{
return false;
}
@Override
public boolean appliesToCollectionElements()
{
return true;
}
@Override
public Operator negate()
{
return CONTAINS;
}
},
NOT_CONTAINS_KEY(18)
{
@Override
public String toString()
{
return "NOT CONTAINS KEY";
}
@Override
public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
{
return !CONTAINS_KEY.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean isSatisfiedBy(MultiElementType<?> type, ComplexColumnData leftOperand, ByteBuffer rightOperand)
{
return !CONTAINS_KEY.isSatisfiedBy(type, leftOperand, rightOperand);
}
@Override
public boolean appliesToColumnValues()
{
return false;
}
@Override
public boolean appliesToMapKeys()
{
return true;
}
@Override
public Operator negate()
{
return CONTAINS_KEY;
}
},
BETWEEN(19)
{
@Override
public Kind kind() {
public Kind kind()
{
return Kind.TERNARY;
}
@ -773,7 +938,7 @@ public enum Operator
case SINGLE_COLUMN:
ColumnMetadata firstColumn = expression.firstColumn();
AbstractType<?> columnType = firstColumn.type;
if (isSlice())
if (isSlice() && this != Operator.NEQ)
{
if (columnType.referencesDuration())
{

View File

@ -188,11 +188,11 @@ public final class Relation
*/
public SingleRestriction toRestriction(TableMetadata table, VariableSpecifications boundNames)
{
if (operator == Operator.NEQ)
throw invalidRequest("Unsupported '!=' relation: %s", this);
ColumnsExpression columnsExpression = rawExpressions.prepare(table);
if (operator == Operator.NEQ && columnsExpression.kind() == ColumnsExpression.Kind.TOKEN)
throw invalidRequest("Unsupported '!=' relation: %s", this);
// TODO support restrictions on list elements as we do in conditions, then we can probably move below validations
// to ElementExpression prepare/validateColumns
if (columnsExpression.isMapElementExpression())

View File

@ -353,7 +353,7 @@ public final class ColumnCondition
private void validateOperationOnDurations(AbstractType<?> type)
{
if (type.referencesDuration() && operator.isSlice())
if (type.referencesDuration() && operator.isSlice() && operator != Operator.NEQ)
{
checkFalse(type.isCollection(), "Slice conditions are not supported on collections containing durations");
checkFalse(type.isTuple(), "Slice conditions are not supported on tuples containing durations");

View File

@ -277,6 +277,11 @@ public class ClusteringElements extends ForwardingList<ByteBuffer> implements Co
return buildRangeSet(endpoint, false, BoundType.OPEN);
}
public static Range<ClusteringElements> notEqualTo(ClusteringElements endpoint)
{
return Range.closed(endpoint.bottom(), endpoint.top());
}
private static RangeSet<ClusteringElements> buildRangeSet(ClusteringElements endpoint, boolean upperBound, BoundType boundType)
{
TreeRangeSet<ClusteringElements> rangeSet = TreeRangeSet.create();

View File

@ -60,7 +60,7 @@ public final class MergedRestriction implements SingleRestriction
private final boolean isMultiColumn;
/**
* The number of restrictions that require {@code CONTAINS}, {@code CONTAINS_KEY} and Map equality restrictions.
* The number of restrictions that require {@code CONTAINS}, {@code CONTAINS_KEY}, {@code NOT_CONTAINS}, {@code NOT_CONTAINS_KEY} and Map equality restrictions.
*/
private final int containsCount;
@ -124,7 +124,7 @@ public final class MergedRestriction implements SingleRestriction
checkOperator(other);
if (restriction.isContains() != other.isContains())
throw invalidRequest("Collection column %s can only be restricted by CONTAINS, CONTAINS KEY," +
throw invalidRequest("Collection column %s can only be restricted by CONTAINS, CONTAINS KEY, NOT_CONTAINS, NOT_CONTAINS_KEY" +
" or map-entry equality if it already restricted by one of those",
restriction.firstColumn().name);
@ -201,7 +201,7 @@ public final class MergedRestriction implements SingleRestriction
}
/**
* Checks if the restriction operator is a CONTAINS, CONTAINS_KEY or is an equality on a map element.
* Checks if the restriction operator is a CONTAINS, CONTAINS_KEY, NOT_CONTAINS, NOT_CONTAINS_KEY or is an equality on a map element.
* @param restriction the restriction to check
* @return {@code true} if the restriction operator is one of the contains operations, {@code false} otherwise.
*/

View File

@ -110,7 +110,7 @@ final class PartitionKeyRestrictions extends RestrictionSetWrapper
*/
public List<ByteBuffer> values(IPartitioner partitioner, QueryOptions options, ClientState state)
{
// if we need to perform filtering its means that this query is a partition range query and that
// if we need to perform filtering it means that this query is a partition range query and that
// this method should not be called
if (isEmpty() || needFiltering())
throw new IllegalStateException("the query is a partition range query and this method should not be called");

View File

@ -135,15 +135,17 @@ public final class SimpleRestriction implements SingleRestriction
}
/**
* Checks if this restriction operator is a CONTAINS, CONTAINS_KEY or is an equality on a map element.
* Checks if this restriction operator is a CONTAINS, CONTAINS_KEY, NOT_CONTAINS, NOT_CONTAINS_KEY or is an equality on a map element.
* @return {@code true} if the restriction operator is one of the contains operations, {@code false} otherwise.
*/
public boolean isContains()
{
return operator == Operator.CONTAINS
|| operator == Operator.CONTAINS_KEY
|| operator == Operator.CONTAINS_KEY
|| operator == Operator.NOT_CONTAINS
|| operator == Operator.NOT_CONTAINS_KEY
// TODO only map elements supported for now in restrictions
|| columnsExpression.isMapElementExpression();
|| columnsExpression.isMapElementExpression();
}
@Override
@ -217,7 +219,9 @@ public final class SimpleRestriction implements SingleRestriction
@Override
public List<ClusteringElements> values(QueryOptions options)
{
assert operator == Operator.EQ || operator == Operator.IN || operator == Operator.ANN;
assert operator == Operator.EQ ||
operator == Operator.IN ||
operator == Operator.ANN;
return bindAndGetClusteringElements(options);
}
@ -327,7 +331,7 @@ public final class SimpleRestriction implements SingleRestriction
{
case SINGLE_COLUMN:
List<ByteBuffer> buffers = bindAndGet(options);
if (operator == Operator.IN || operator == Operator.BETWEEN)
if (operator.kind() != Operator.Kind.BINARY)
{
filter.add(column, operator, multiInputOperatorValues(column, buffers));
}

View File

@ -734,15 +734,18 @@ public class RowFilter implements Iterable<RowFilter.Expression>
switch (operator)
{
case CONTAINS:
case NOT_CONTAINS:
assert type instanceof CollectionType;
CollectionType<?> ct = (CollectionType<?>)type;
type = ct.kind == CollectionType.Kind.SET ? ct.nameComparator() : ct.valueComparator();
break;
case CONTAINS_KEY:
case NOT_CONTAINS_KEY:
assert type instanceof MapType;
type = ((MapType<?, ?>)type).nameComparator();
break;
case IN:
case NOT_IN:
case BETWEEN:
type = ListType.getInstance(type, false);
break;
@ -783,7 +786,7 @@ public class RowFilter implements Iterable<RowFilter.Expression>
public MapElementExpression(ColumnMetadata column, ByteBuffer key, Operator operator, ByteBuffer value)
{
super(column, operator, value);
assert column.type instanceof MapType && operator == Operator.EQ;
assert column.type instanceof MapType && (operator == Operator.EQ || operator == Operator.NEQ);
this.key = key;
}
@ -836,8 +839,8 @@ public class RowFilter implements Iterable<RowFilter.Expression>
AbstractType<?> nt = mt.nameComparator();
AbstractType<?> vt = mt.valueComparator();
return cql
? String.format("%s[%s] = %s", column.name.toCQLString(), nt.toCQLString(key), vt.toCQLString(value))
: String.format("%s[%s] = %s", column.name.toString(), nt.getString(key), vt.getString(value));
? String.format("%s[%s] %s %s", column.name.toCQLString(), nt.toCQLString(key), operator, vt.toCQLString(value))
: String.format("%s[%s] %s %s", column.name.toString(), nt.getString(key), operator, vt.getString(value));
}
@Override

View File

@ -132,7 +132,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMultiAndSingleColumnRelationMix() throws Throwable
public void testMultiAndSingleColumnRelationMix()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))");
@ -235,7 +235,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testSeveralMultiColumnRelation() throws Throwable
public void testSeveralMultiColumnRelation()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))");
@ -390,11 +390,94 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testNonEqualsRelation() throws Throwable
public void testNonEqualsRelation()
{
createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)");
assertInvalidMessage("Unsupported '!=' relation: (b) != (0)",
"SELECT * FROM %s WHERE a = 0 AND (b) != (0)");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
// Excluding subtrees
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b) != (?)", 0, 0),
row(0, 1, 0),
row(0, 1, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b) != (?)", 0, 1),
row(0, 0, 0),
row(0, 0, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b) != (?)", 0, -1),
row(0, 0, 0),
row(0, 0, 1),
row(0, 1, 0),
row(0, 1, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b) != (?)", 0, 2),
row(0, 0, 0),
row(0, 0, 1),
row(0, 1, 0),
row(0, 1, 1)
);
// Excluding single rows
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) != (?, ?)", 0, -1, -1),
row(0, 0, 0),
row(0, 0, 1),
row(0, 1, 0),
row(0, 1, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) != (?, ?)", 0, 0, 1),
row(0, 0, 0),
row(0, 1, 0),
row(0, 1, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) != (?, ?)", 0, 2, 2),
row(0, 0, 0),
row(0, 0, 1),
row(0, 1, 0),
row(0, 1, 1)
);
// Merging multiple != =
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) != ? AND (b, c) != ?", 0, tuple(0, 1), tuple(1, 0)),
row(0, 0, 0),
row(0, 1, 1)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND b != ? AND (b, c) != ?", 0, 1, tuple(0, 1)),
row(0, 0, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b) != (?) AND (b, c) != ?", 0, 1, tuple(0, 1)),
row(0, 0, 0)
);
// Merging with < <= >= >
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND b < ? AND (b, c) != ?", 0, 1, tuple(0, 1)),
row(0, 0, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND b <= ? AND (b, c) != ?", 0, 0, tuple(0, 1)),
row(0, 0, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND b > ? AND (b, c) != ?", 0, 0, tuple(1, 1)),
row(0, 1, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND b >= ? AND (b, c) != ?", 0, 1, tuple(1, 1)),
row(0, 1, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) < ? AND (b, c) != ?", 0, tuple(0, 2), tuple(0, 1)),
row(0, 0, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) <= ? AND (b, c) != ?", 0, tuple(0, 2), tuple(0, 1)),
row(0, 0, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) > ? AND (b, c) != ?", 0, tuple(0, 0), tuple(1, 1)),
row(0, 0, 1),
row(0, 1, 0)
);
assertRows(execute("SELECT a, b, c FROM %s WHERE a = ? AND (b, c) >= ? AND (b, c) != ?", 0, tuple(0, 1), tuple(1, 1)),
row(0, 0, 1),
row(0, 1, 0)
);
}
@Test
@ -773,7 +856,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMultipleClusteringReversedComponents() throws Throwable
public void testMultipleClusteringReversedComponents()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d)) WITH CLUSTERING ORDER BY (b DESC, c ASC, d DESC)");
@ -1134,7 +1217,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testINWithDuplicateValue() throws Throwable
public void testINWithDuplicateValue()
{
createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2))");
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, 1);
@ -1168,7 +1251,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMixedOrderColumns1() throws Throwable
public void testMixedOrderColumns1()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) WITH " +
" CLUSTERING ORDER BY (b DESC, c ASC, d DESC, e ASC)");
@ -1650,7 +1733,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMixedOrderColumns2() throws Throwable
public void testMixedOrderColumns2()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) WITH " +
"CLUSTERING ORDER BY (b DESC, c ASC, d ASC, e ASC)");
@ -1724,7 +1807,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMixedOrderColumns3() throws Throwable
public void testMixedOrderColumns3()
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b, c)) WITH " +
"CLUSTERING ORDER BY (b DESC, c ASC)");
@ -1760,7 +1843,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMixedOrderColumns4() throws Throwable
public void testMixedOrderColumns4()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) WITH " +
"CLUSTERING ORDER BY (b ASC, c DESC, d DESC, e ASC)");
@ -2120,7 +2203,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
}
@Test
public void testMixedOrderColumnsInReverse() throws Throwable
public void testMixedOrderColumnsInReverse()
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b, c)) WITH CLUSTERING ORDER BY (b ASC, c DESC);");
@ -2156,7 +2239,7 @@ public class SelectMultiColumnRelationTest extends CQLTester
* migrated from cql_tests.py:TestCQL.simple_tuple_query_test()
*/
@Test
public void testSimpleTupleQuery() throws Throwable
public void testSimpleTupleQuery()
{
createTable("create table %s (a int, b int, c int, d int , e int, PRIMARY KEY (a, b, c, d, e))");
@ -2226,4 +2309,477 @@ public class SelectMultiColumnRelationTest extends CQLTester
assertInvalidMessage("Multicolumn IN filters are not supported",
"SELECT * FROM %s WHERE (c2, c3) IN ((?, ?), (?, ?)) ALLOW FILTERING", 1, 0, 2, 0);
}
@Test
public void testNotInRestrictionsWithClustering()
{
createTable("CREATE TABLE %s (pk int, c1 int, c2 int, v int, primary key(pk, c1, c2))");
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 1, 11);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 2, 12);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 3, 13);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 4, 14);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 1, 21);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 2, 22);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 3, 23);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 4, 24);
// empty NOT IN
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ()", 1),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// non existent NOT IN:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ((?, ?))", 1, 2000, 2001),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// existing values in NOT IN, different ways of passing them:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ((0, 2), (0, 3), (1, 1), (1, 4))", 1),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ((?, ?), (?, ?), (?, ?), (?, ?))",
1, 0, 2, 0, 3, 1, 1, 1, 4),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN (?, ?, ?, ?)",
1, tuple(0, 2), tuple(0, 3), tuple(1, 1), tuple(1, 4)),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ?",
1, list(tuple(0, 2), tuple(0, 3), tuple(1, 1), tuple(1, 4))),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Tuples given in arbitrary order:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN (?, ?, ?, ?)",
1, tuple(0, 3), tuple(1, 4), tuple(1, 1), tuple(0, 2)),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Multiple NOT IN:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN (?, ?) AND (c1, c2) NOT IN (?, ?)",
1, tuple(0, 2), tuple(0, 3), tuple(1, 1), tuple(1, 4)),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Multiple NOT IN, mixed markers:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN (?, ?) AND (c1, c2) NOT IN ?",
1, tuple(0, 2), tuple(0, 3), list(tuple(1, 1), tuple(1, 4))),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Multiple NOT IN, mixed markers and values:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) NOT IN ((0, 2), (0, 3)) AND (c1, c2) NOT IN ?",
1, list(tuple(1, 1), tuple(1, 4))),
row(1, 0, 1, 11),
row(1, 0, 4, 14),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Mixed single-column and multicolumn restrictions:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 NOT IN ? AND (c1, c2) NOT IN ?",
1, list(0), list(tuple(1, 1), tuple(1, 4))),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 NOT IN (?) AND (c1, c2) NOT IN (?, ?)",
1, 0, tuple(1, 1), tuple(1, 4)),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
}
@Test
public void testNotInRestrictionsWithClusteringAndSlices()
{
createTable("CREATE TABLE %s (pk int, c1 int, c2 int, v int, primary key(pk, c1, c2))");
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 1, 11);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 2, 12);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 3, 13);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 4, 14);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 1, 21);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 2, 22);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 3, 23);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 4, 24);
// NOT IN values outside of slice bounds
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(2, 5)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(1, 1)),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// Empty result set
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(1, 3), tuple(1, 4)));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(0, 3), tuple(0, 2), tuple(0, 1)));
// NOT IN values inside slice bounds
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(0, 2)),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(0, 2)),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21),
row(1, 1, 2, 22));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 3)),
row(1, 1, 2, 22),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 3)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 4, 24));
// One NOT IN value exactly the same as the slice bound
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(0, 2), tuple(1, 2)),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(0, 2), tuple(1, 2)),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 1)),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 1)),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// NOT IN with both upper and lower bound
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 0, 3, 13),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 1, 1, 21));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 0, 3, 13),
row(1, 1, 1, 21),
row(1, 1, 2, 22));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 1, 1, 21),
row(1, 1, 2, 22));
// Mixed multi-column NOT IN with single column slice restriction:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 > ? AND (c1, c2) NOT IN (?)",
1, 0, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND (c1, c2) NOT IN (?)",
1, 1, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 < ? AND (c1, c2) NOT IN (?)",
1, 1, tuple(0, 4)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, 0, tuple(0, 4)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, 0, 1, tuple(0, 4)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// Mixed single-column NOT IN with multi-column slice restriction:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND c1 NOT IN (?)",
1, tuple(0, 1), 1),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND c1 NOT IN (?)",
1, tuple(0, 1), 1),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND c1 NOT IN (?)",
1, tuple(1, 3), 1),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND c1 NOT IN (?)",
1, tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND c1 NOT IN (?)",
1, tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) <= ? AND c1 NOT IN (?)",
1, tuple(0, 2), tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
}
@Test
public void testNotInRestrictionsWithMixedOrderClusteringAndSlices()
{
createTable("CREATE TABLE %s (pk int, c1 int, c2 int, v int, primary key(pk, c1, c2)) WITH CLUSTERING ORDER BY (c1 DESC, c2 ASC)");
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 1, 11);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 2, 12);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 3, 13);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 0, 4, 14);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 1, 21);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 2, 22);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 3, 23);
execute("INSERT INTO %s (pk, c1, c2, v) values (?, ?, ?, ?)", 1, 1, 4, 24);
// NOT IN values outside of slice bounds
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(2, 5)),
row(1, 1, 1, 21),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(1, 1)),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// Empty result set
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(1, 3), tuple(1, 4)));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(0, 3), tuple(0, 2), tuple(0, 1)));
// NOT IN values inside slice bounds
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(0, 2)),
row(1, 1, 1, 21),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 2), tuple(0, 2)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 3)),
row(1, 1, 2, 22),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 3)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 4, 24));
// One NOT IN value exactly the same as the slice bound
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(0, 2), tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?, ?)",
1, tuple(1, 2), tuple(0, 2), tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 0, 1, 11),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 1)),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) NOT IN (?)",
1, tuple(1, 1), tuple(1, 1)),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
// NOT IN with both upper and lower bound
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 1, 1, 21),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 1, 1, 21),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) <= ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 2), tuple(1, 2), tuple(0, 4)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
// Mixed multi-column NOT IN with single column slice restriction:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 > ? AND (c1, c2) NOT IN (?)",
1, 0, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND (c1, c2) NOT IN (?)",
1, 1, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 < ? AND (c1, c2) NOT IN (?)",
1, 1, tuple(0, 4)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, 0, tuple(0, 4)),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, 0, 1, tuple(0, 4)),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23),
row(1, 1, 4, 24),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13));
// Mixed single-column NOT IN with multi-column slice restriction:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND c1 NOT IN (?)",
1, tuple(0, 1), 1),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND c1 NOT IN (?)",
1, tuple(0, 1), 1),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND c1 NOT IN (?)",
1, tuple(1, 3), 1),
row(1, 0, 1, 11),
row(1, 0, 2, 12),
row(1, 0, 3, 13),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) < ? AND c1 NOT IN (?)",
1, tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) <= ? AND c1 NOT IN (?)",
1, tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) >= ? AND (c1, c2) <= ? AND c1 NOT IN (?)",
1, tuple(0, 2), tuple(1, 3), 0),
row(1, 1, 1, 21),
row(1, 1, 2, 22),
row(1, 1, 3, 23));
// Mixed single-column and multi column slices with multi column NOT IN:
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND c1 < ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 1), 1, tuple(0, 3)),
row(1, 0, 2, 12),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND (c1, c2) > ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, tuple(0, 1), 0, tuple(0, 3)),
row(1, 0, 2, 12),
row(1, 0, 4, 14));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 > ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, 0, tuple(1, 4), tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND (c1, c2) < ? AND (c1, c2) NOT IN (?)",
1, 1, tuple(1, 4), tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 > ? AND c1 < ? AND (c1, c2) NOT IN (?)",
1, 0, 2, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
assertRows(execute("SELECT * FROM %s WHERE pk = ? AND c1 >= ? AND c1 <= ? AND (c1, c2) NOT IN (?)",
1, 1, 1, tuple(1, 2)),
row(1, 1, 1, 21),
row(1, 1, 3, 23),
row(1, 1, 4, 24));
}
}

View File

@ -38,11 +38,11 @@ public class SelectSingleColumnRelationTest extends CQLTester
createIndex("CREATE INDEX ON %s (d)");
assertInvalidMessage("Collection column 'b' (set<int>) cannot be restricted by a '=' relation",
"SELECT * FROM %s WHERE a = 0 AND b=?", set(0));
"SELECT * FROM %s WHERE a = 0 AND b = ?", set(0));
assertInvalidMessage("Collection column 'c' (list<int>) cannot be restricted by a '=' relation",
"SELECT * FROM %s WHERE a = 0 AND c=?", list(0));
"SELECT * FROM %s WHERE a = 0 AND c = ?", list(0));
assertInvalidMessage("Collection column 'd' (map<int, int>) cannot be restricted by a '=' relation",
"SELECT * FROM %s WHERE a = 0 AND d=?", map(0, 0));
"SELECT * FROM %s WHERE a = 0 AND d = ?", map(0, 0));
}
@Test
@ -65,8 +65,10 @@ public class SelectSingleColumnRelationTest extends CQLTester
"SELECT * FROM %s WHERE c = 0 AND b IN (?)", set(0));
assertInvalidMessage("Collection column 'b' (set<int>) cannot be restricted by a 'BETWEEN' relation",
"SELECT * FROM %s WHERE c = 0 AND b BETWEEN ? AND ?", set(0), set(0));
assertInvalidMessage("Unsupported '!=' relation: b != 5",
"SELECT * FROM %s WHERE c = 0 AND b != 5");
assertInvalidMessage("Collection column 'b' (set<int>) cannot be restricted by a 'NOT IN' relation",
"SELECT * FROM %s WHERE c = 0 AND b NOT IN (?)", set(0));
assertInvalidMessage("Collection column 'b' (set<int>) cannot be restricted by a '!=' relation",
"SELECT * FROM %s WHERE c = 0 AND b != 5");
assertInvalidMessage("Unsupported restriction: b IS NOT NULL",
"SELECT * FROM %s WHERE c = 0 AND b IS NOT NULL");
}
@ -216,7 +218,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testClusteringColumnRelationsWithClusteringOrder() throws Throwable
public void testClusteringColumnRelationsWithClusteringOrder()
{
createTable("CREATE TABLE %s (a text, b int, c int, d int, primary key(a, b, c)) WITH CLUSTERING ORDER BY (b DESC, c ASC);");
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "first", 1, 5, 1);
@ -313,7 +315,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testAllowFilteringWithIndexedColumnAndStaticColumns() throws Throwable
public void testAllowFilteringWithIndexedColumnAndStaticColumns()
{
createTable("CREATE TABLE %s (a int, b int, c int, s int static, PRIMARY KEY(a, b))");
createIndex("CREATE INDEX ON %s(c)");
@ -340,7 +342,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testIndexQueriesOnComplexPrimaryKey() throws Throwable
public void testIndexQueriesOnComplexPrimaryKey()
{
createTable("CREATE TABLE %s (pk0 int, pk1 int, ck0 int, ck1 int, ck2 int, value int, PRIMARY KEY ((pk0, pk1), ck0, ck1, ck2))");
@ -464,7 +466,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testINWithDuplicateValue() throws Throwable
public void testINWithDuplicateValue()
{
createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2))");
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, 1);
@ -480,7 +482,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testLargeClusteringINValues() throws Throwable
public void testLargeClusteringINValues()
{
createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c))");
execute("INSERT INTO %s (k, c, v) VALUES (0, 0, 0)");
@ -595,7 +597,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testLimitWithUnset() throws Throwable
public void testLimitWithUnset()
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k, i) VALUES (1, 1)");
@ -616,12 +618,18 @@ public class SelectSingleColumnRelationTest extends CQLTester
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN ?", unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN(?)", unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN(?,?)", 1, unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k NOT IN ? ALLOW FILTERING", unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k NOT IN(?) ALLOW FILTERING", unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k NOT IN(?,?) ALLOW FILTERING", 1, unset());
// clustering column
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i = ?", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN ?", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN(?)", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN(?,?)", 1, unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE i = ? ALLOW FILTERING", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i NOT IN ?", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i NOT IN(?)", unset());
assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i NOT IN(?,?)", 1, unset());
// indexed column
assertInvalidMessage("Invalid unset value for column s", "SELECT * from %s WHERE s = ?", unset());
// range
@ -670,11 +678,16 @@ public class SelectSingleColumnRelationTest extends CQLTester
assertInvalidMessage("Undefined column name d", "SELECT * FROM %s WHERE d > 0 and d <= 2");
assertInvalidMessage("Undefined column name d", "SELECT * FROM %s WHERE d CONTAINS 0");
assertInvalidMessage("Undefined column name d", "SELECT * FROM %s WHERE d CONTAINS KEY 0");
assertInvalidMessage("Undefined column name d", "SELECT * FROM %s WHERE d NOT CONTAINS 0");
assertInvalidMessage("Undefined column name d", "SELECT * FROM %s WHERE d NOT CONTAINS KEY 0");
assertInvalidMessage("Undefined column name d", "SELECT a AS d FROM %s WHERE d = 0");
assertInvalidMessage("Undefined column name d", "SELECT b AS d FROM %s WHERE d IN (0, 1)");
assertInvalidMessage("Undefined column name d", "SELECT b AS d FROM %s WHERE d NOT IN (0, 1)");
assertInvalidMessage("Undefined column name d", "SELECT b AS d FROM %s WHERE d > 0 and d <= 2");
assertInvalidMessage("Undefined column name d", "SELECT c AS d FROM %s WHERE d CONTAINS 0");
assertInvalidMessage("Undefined column name d", "SELECT c AS d FROM %s WHERE d CONTAINS KEY 0");
assertInvalidMessage("Undefined column name d", "SELECT c AS d FROM %s WHERE d NOT CONTAINS 0");
assertInvalidMessage("Undefined column name d", "SELECT c AS d FROM %s WHERE d NOT CONTAINS KEY 0");
assertInvalidMessage("Undefined column name d", "SELECT d FROM %s WHERE a = 0");
assertInvalidMessage("Undefined column name d", "SELECT d FROM %s WHERE b BETWEEN 0 AND 0");
}
@ -695,13 +708,18 @@ public class SelectSingleColumnRelationTest extends CQLTester
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b <= ?", udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b BETWEEN ? AND ?", udt, udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b IN (?)", udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b NOT IN (?)", udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b LIKE ?", udt);
assertInvalidMessage("Unsupported '!=' relation: b != {a: 0}",
"SELECT * FROM %s WHERE b != {a: 0}", udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b != {a: 0}", udt);
assertInvalidMessage(msg, "SELECT * FROM %s WHERE b != {a: 0}", udt);
assertInvalidMessage("Unsupported restriction: b IS NOT NULL",
"SELECT * FROM %s WHERE b IS NOT NULL", udt);
assertInvalidMessage("Cannot use CONTAINS on non-collection column b",
"SELECT * FROM %s WHERE b CONTAINS ?", udt);
assertInvalidMessage("Cannot use NOT CONTAINS on non-collection column b",
"SELECT * FROM %s WHERE b NOT CONTAINS ?", udt);
assertInvalidMessage("Cannot use NOT CONTAINS on non-collection column b",
"SELECT * FROM %s WHERE b NOT CONTAINS ?", udt);
}
@Test
@ -739,7 +757,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testInRestrictionsWithAllowFiltering() throws Throwable
public void testInRestrictionsWithAllowFiltering()
{
createTable("CREATE TABLE %s (pk1 int, pk2 int, c text, s int static, v int, primary key((pk1, pk2), c))");
execute("INSERT INTO %s (pk1, pk2, c, s, v) values (?, ?, ?, ?, ?)", 1, 0, "5", 1, 3);
@ -792,7 +810,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testInRestrictionsWithAllowFilteringAndOrdering() throws Throwable
public void testInRestrictionsWithAllowFilteringAndOrdering()
{
createTable("CREATE TABLE %s (pk int, c text, v int, primary key(pk, c)) WITH CLUSTERING ORDER BY (c DESC)");
execute("INSERT INTO %s (pk, c, v) values (?, ?, ?)", 1, "0", 5);
@ -839,7 +857,7 @@ public class SelectSingleColumnRelationTest extends CQLTester
}
@Test
public void testSliceRestrictionWithNegativeClusteringColumnValues() throws Throwable
public void testSliceRestrictionWithNegativeClusteringColumnValues()
{
createTable("CREATE TABLE %s (pk int, c int, v int, PRIMARY KEY (pk, c))");
@ -861,4 +879,453 @@ public class SelectSingleColumnRelationTest extends CQLTester
row(1, -2, -2),
row(1, -1, -1));
}
@Test
public void testClusteringSlicesWithNotIn()
{
createTable("CREATE TABLE %s (a text, b int, c int, d int, primary key(a, b, c))");
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 1, 4, 1);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 5, 2);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 6, 3);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 7, 4);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 3, 8, 5);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 3, 9, 6);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 4, 1, 7);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 4, 2, 8);
// restrict first clustering column by NOT IN
assertRows(execute("select * from %s where a = ? and b not in ?", "key", list(2, 4, 5)),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in (?, ?, ?)", "key", 2, 4, 5),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
// use different order of items in NOT IN list:
assertRows(execute("select * from %s where a = ? and b not in (?, ?, ?)", "key", 5, 2, 4),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in (?, ?, ?)", "key", 5, 4, 2),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
// restrict last clustering column by NOT IN
assertRows(execute("select * from %s where a = ? and b = ? and c not in ?", "key", 2, list(5, 6)),
row("key", 2, 7, 4));
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?, ?)", "key", 2, 5, 6),
row("key", 2, 7, 4));
// empty NOT IN should have no effect:
assertRows(execute("select * from %s where a = ? and b = ? and c not in ?", "key", 2, list()),
row("key", 2, 5, 2),
row("key", 2, 6, 3),
row("key", 2, 7, 4));
assertRows(execute("select * from %s where a = ? and b = ? and c not in ()", "key", 2),
row("key", 2, 5, 2),
row("key", 2, 6, 3),
row("key", 2, 7, 4));
// NOT IN value that doesn't match any data should have no effect:
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?)", "key", 2, 0),
row("key", 2, 5, 2),
row("key", 2, 6, 3),
row("key", 2, 7, 4));
// Duplicate NOT IN values:
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?, ?)", "key", 2, 5, 5),
row("key", 2, 6, 3),
row("key", 2, 7, 4));
// mix NOT IN and '<' and '<=' comparison on the same column
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2, 5), 1)); // empty
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2, 5), 3),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 2),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 3),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 10),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
// mix NOT IN and '>' and '>=' comparison on the same column
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 2),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 2),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 4),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 0),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
// mix NOT IN and range slice
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(2), 1, 4),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ? and b < ?", "key", list(2), 1, 4),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b <= ?", "key", list(2), 1, 4),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ? and b <= ?", "key", list(2), 1, 4),
row("key", 1, 4, 1),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
// Collision between a slice bound and NOT IN value:
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2), 2),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 2),
row("key", 3, 8, 5),
row("key", 3, 9, 6),
row("key", 4, 1, 7),
row("key", 4, 2, 8));
// NOT IN value outside the slice range:
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(0), 2, 4),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(10), 2, 4),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
// multiple NOT IN on the same column, use different ways of passing a list
assertRows(execute("select * from %s where a = ? and b not in ? and b not in ?", "key", list(1, 2), list(4)),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in (?, ?) and b not in (?)", "key", 1, 2, 4),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
assertRows(execute("select * from %s where a = ? and b not in (?, ?) and b not in ?", "key", 1, 2, list(4)),
row("key", 3, 8, 5),
row("key", 3, 9, 6));
// mix IN and NOT IN
assertRows(execute("select * from %s where a = ? and b in ? and c not in ?", "key", list(2, 3), list(5, 6, 9)),
row("key", 2, 7, 4),
row("key", 3, 8, 5));
}
@Test
public void testClusteringSlicesWithNotInAndReverseOrdering()
{
createTable("CREATE TABLE %s (a text, b int, c int, d int, primary key(a, b, c)) with clustering order by (b desc, c desc)");
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 1, 4, 1);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 5, 2);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 6, 3);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 2, 7, 4);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 3, 8, 5);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 3, 9, 6);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 4, 1, 7);
execute("insert into %s (a, b, c, d) values (?, ?, ?, ?)", "key", 4, 2, 8);
// restrict first clustering column by NOT IN
assertRows(execute("select * from %s where a = ? and b not in ?", "key", list(2, 4, 5)),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in (?, ?, ?)", "key", 2, 4, 5),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
// restrict last clustering column by NOT IN
assertRows(execute("select * from %s where a = ? and b = ? and c not in ?", "key", 2, list(5, 6)),
row("key", 2, 7, 4));
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?, ?)", "key", 2, 5, 6),
row("key", 2, 7, 4));
// empty NOT IN should have no effect:
assertRows(execute("select * from %s where a = ? and b = ? and c not in ?", "key", 2, list()),
row("key", 2, 7, 4),
row("key", 2, 6, 3),
row("key", 2, 5, 2));
assertRows(execute("select * from %s where a = ? and b = ? and c not in ()", "key", 2),
row("key", 2, 7, 4),
row("key", 2, 6, 3),
row("key", 2, 5, 2));
// NOT IN value that doesn't match any data should have no effect:
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?)", "key", 2, 0),
row("key", 2, 7, 4),
row("key", 2, 6, 3),
row("key", 2, 5, 2));
// Duplicate NOT IN values:
assertRows(execute("select * from %s where a = ? and b = ? and c not in (?, ?)", "key", 2, 5, 5),
row("key", 2, 7, 4),
row("key", 2, 6, 3));
// mix NOT IN and '<' and '<=' comparison on the same column
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2, 5), 1)); // empty
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2, 5), 3),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 2),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 3),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b <= ?", "key", list(2), 10),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
// mix NOT IN and '>' and '>=' comparison on the same column
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 1),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 2),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 2),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 4),
row("key", 4, 2, 8),
row("key", 4, 1, 7));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ?", "key", list(2), 0),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
// mix NOT IN and range slice
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(2), 1, 4),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ? and b < ?", "key", list(2), 1, 4),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b <= ?", "key", list(2), 1, 4),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b >= ? and b <= ?", "key", list(2), 1, 4),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5),
row("key", 1, 4, 1));
// Collision between a slice bound and NOT IN value:
assertRows(execute("select * from %s where a = ? and b not in ? and b < ?", "key", list(2), 2),
row("key", 1, 4, 1));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ?", "key", list(2), 2),
row("key", 4, 2, 8),
row("key", 4, 1, 7),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
// NOT IN value outside the slice range:
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(0), 2, 4),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in ? and b > ? and b < ?", "key", list(10), 2, 4),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
// multiple NOT IN on the same column, use different ways of passing a list
assertRows(execute("select * from %s where a = ? and b not in ? and b not in ?", "key", list(1, 2), list(4)),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in (?, ?) and b not in (?)", "key", 1, 2, 4),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
assertRows(execute("select * from %s where a = ? and b not in (?, ?) and b not in ?", "key", 1, 2, list(4)),
row("key", 3, 9, 6),
row("key", 3, 8, 5));
// mix IN and NOT IN
assertRows(execute("select * from %s where a = ? and b in ? and c not in ?", "key", list(2, 3), list(5, 6, 9)),
row("key", 3, 8, 5),
row("key", 2, 7, 4));
}
@Test
public void testNotInRestrictionsWithAllowFiltering()
{
createTable("CREATE TABLE %s (pk int, c int, v int, primary key(pk, c))");
execute("insert into %s (pk, c, v) values (?, ?, ?)", 1, 1, 1);
execute("insert into %s (pk, c, v) values (?, ?, ?)", 1, 2, 2);
execute("insert into %s (pk, c, v) values (?, ?, ?)", 1, 3, 3);
execute("insert into %s (pk, c, v) values (?, ?, ?)", 1, 4, 4);
execute("insert into %s (pk, c, v) values (?, ?, ?)", 1, 5, 5);
// empty NOT IN set
assertRows(execute("select * from %s where pk = ? and v not in ? allow filtering", 1, list()),
row(1, 1, 1),
row(1, 2, 2),
row(1, 3, 3),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in () allow filtering", 1),
row(1, 1, 1),
row(1, 2, 2),
row(1, 3, 3),
row(1, 4, 4),
row(1, 5, 5));
// NOT IN with values that don't match any data
assertRows(execute("select * from %s where pk = ? and v not in (?, ?) allow filtering", 1, -6, 20),
row(1, 1, 1),
row(1, 2, 2),
row(1, 3, 3),
row(1, 4, 4),
row(1, 5, 5));
// NOT IN that excludes a few values
assertRows(execute("select * from %s where pk = ? and v not in ? allow filtering", 1, list(2, 3)),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in (?, ?) allow filtering", 1, 2, 3),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
// NOT IN with one-sided slice filters:
assertRows(execute("select * from %s where pk = ? and v not in ? and v < ? allow filtering", 1, list(2, 3), 5),
row(1, 1, 1),
row(1, 4, 4));
assertRows(execute("select * from %s where pk = ? and v not in ? and v < ? allow filtering", 1, list(2, 3, 10), 5),
row(1, 1, 1),
row(1, 4, 4));
assertRows(execute("select * from %s where pk = ? and v not in ? and v <= ? allow filtering", 1, list(2, 3), 5),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in ? and v <= ? allow filtering", 1, list(2, 3, 10), 5),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? allow filtering", 1, list(2, 3), 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? allow filtering", 1, list(0, 2, 3), 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in ? and v >= ? allow filtering", 1, list(2, 3), 1),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
assertRows(execute("select * from %s where pk = ? and v not in ? and v >= ? allow filtering", 1, list(0, 2, 3), 1),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
// NOT IN with range filters:
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? and v < ? allow filtering", 1, list(2, 3), 1, 4)); // empty
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? and v < ? allow filtering", 1, list(2, 3), 1, 4)); // empty
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? and v < ? allow filtering", 1, list(2, 3), 0, 5),
row(1, 1, 1),
row(1, 4, 4));
assertRows(execute("select * from %s where pk = ? and v not in ? and v >= ? and v < ? allow filtering", 1, list(2, 3), 1, 4),
row(1, 1, 1));
assertRows(execute("select * from %s where pk = ? and v not in ? and v > ? and v <= ? allow filtering", 1, list(2, 3), 1, 4),
row(1, 4, 4));
assertRows(execute("select * from %s where pk = ? and v not in ? and v >= ? and v <= ? allow filtering", 1, list(2, 3), 1, 4),
row(1, 1, 1),
row(1, 4, 4));
// more than one NOT IN clause
assertRows(execute("select * from %s where pk = ? and v not in ? and v not in ? allow filtering", 1, list(2), list(3)),
row(1, 1, 1),
row(1, 4, 4),
row(1, 5, 5));
}
@Test
public void testNonEqualsRelationWithFiltering()
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 2);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 3, 3);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? ALLOW FILTERING", 0, 0),
row(0, 1),
row(0, 2),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? ALLOW FILTERING", 0, 1),
row(0, 0),
row(0, 2),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? ALLOW FILTERING", 0, -1),
row(0, 0),
row(0, 1),
row(0, 2),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? ALLOW FILTERING", 0, 5),
row(0, 0),
row(0, 1),
row(0, 2),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? AND c != ? ALLOW FILTERING", 0, 1, 2),
row(0, 0),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? AND c < ? ALLOW FILTERING", 0, 1, 2),
row(0, 0)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? AND c <= ? ALLOW FILTERING", 0, 1, 2),
row(0, 0),
row(0, 2)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? AND c > ? ALLOW FILTERING", 0, 2, 0),
row(0, 1),
row(0, 3)
);
assertRows(execute("SELECT a, b FROM %s WHERE a = ? AND c != ? AND c >= ? ALLOW FILTERING", 0, 2, 1),
row(0, 1),
row(0, 3)
);
}
}

View File

@ -32,10 +32,9 @@ import org.apache.cassandra.cql3.restrictions.StatementRestrictions;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.index.internal.CassandraIndex;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.apache.cassandra.utils.ByteBufferUtil.EMPTY_BYTE_BUFFER;
import static org.apache.cassandra.utils.ByteBufferUtil.bytes;
import static org.junit.Assert.*;
/**
@ -301,7 +300,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.select_key_in_test()
*/
@Test
public void testSelectKeyIn() throws Throwable
public void testSelectKeyIn()
{
createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int)");
@ -635,7 +634,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.token_range_test()
*/
@Test
public void testTokenRange() throws Throwable
public void testTokenRange()
{
createTable(" CREATE TABLE %s (k int PRIMARY KEY, c int, v int)");
@ -668,7 +667,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.count_test()
*/
@Test
public void testSelectCount() throws Throwable
public void testSelectCount()
{
createTable(" CREATE TABLE %s (kind text, time int, value1 int, value2 int, PRIMARY KEY(kind, time))");
@ -691,7 +690,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.range_query_test()
*/
@Test
public void testRangeQuery() throws Throwable
public void testRangeQuery()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, f text, PRIMARY KEY (a, b, c, d, e) )");
@ -765,7 +764,7 @@ public class SelectTest extends CQLTester
* Migrated from cql_tests.py:TestCQL.bug_4882_test()
*/
@Test
public void testDifferentOrdering() throws Throwable
public void testDifferentOrdering()
{
createTable(" CREATE TABLE %s ( k int, c1 int, c2 int, v int, PRIMARY KEY (k, c1, c2) ) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)");
@ -910,7 +909,7 @@ public class SelectTest extends CQLTester
* Migrated from cql_tests.py:TestCQL.ticket_5230_test()
*/
@Test
public void testMultipleClausesOnPrimaryKey() throws Throwable
public void testMultipleClausesOnPrimaryKey()
{
createTable("CREATE TABLE %s (key text, c text, v text, PRIMARY KEY(key, c))");
@ -930,7 +929,7 @@ public class SelectTest extends CQLTester
{
createTable("CREATE TABLE %s (key text PRIMARY KEY)");
// We just want to make sure this doesn 't NPE server side
// We just want to make sure this doesn't NPE server side
assertInvalid("select * from %s where token(key) > token(int(3030343330393233)) limit 1");
}
@ -938,7 +937,7 @@ public class SelectTest extends CQLTester
* Migrated from cql_tests.py:TestCQL.clustering_order_and_functions_test()
*/
@Test
public void testFunctionsWithClusteringDesc() throws Throwable
public void testFunctionsWithClusteringDesc()
{
createTable("CREATE TABLE %s ( k int, t timeuuid, PRIMARY KEY (k, t) ) WITH CLUSTERING ORDER BY (t DESC)");
@ -1026,7 +1025,7 @@ public class SelectTest extends CQLTester
* Migrated from cql_tests.py:TestCQL.select_distinct_with_deletions_test()
*/
@Test
public void testSelectDistinctWithDeletions() throws Throwable
public void testSelectDistinctWithDeletions()
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, c int, v int)");
@ -1127,7 +1126,7 @@ public class SelectTest extends CQLTester
* Migrated from cql_tests.py:TestCQL.bug_6327_test()
*/
@Test
public void testSelectInClauseAtOne() throws Throwable
public void testSelectInClauseAtOne()
{
createTable("CREATE TABLE %s ( k int, v int, PRIMARY KEY (k, v))");
@ -1144,7 +1143,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.select_count_paging_test()
*/
@Test
public void testSelectCountPaging() throws Throwable
public void testSelectCountPaging()
{
createTable("create table %s (field1 text, field2 timeuuid, field3 boolean, primary key(field1, field2))");
createIndex("create index on %s (field3)");
@ -1161,7 +1160,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.clustering_order_in_test()
*/
@Test
public void testClusteringOrder() throws Throwable
public void testClusteringOrder()
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY ((a, b), c) ) with clustering order by (c desc)");
@ -1180,7 +1179,7 @@ public class SelectTest extends CQLTester
* migrated from cql_tests.py:TestCQL.bug7105_test()
*/
@Test
public void testSelectInFinalColumn() throws Throwable
public void testSelectInFinalColumn()
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b))");
@ -1380,17 +1379,34 @@ public class SelectTest extends CQLTester
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE c CONTAINS 2");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE c NOT CONTAINS 2");
assertRows(execute("SELECT * FROM %s WHERE c CONTAINS 2 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE c CONTAINS 2 AND c CONTAINS 3 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(execute("SELECT * FROM %s WHERE c NOT CONTAINS 2 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)),
row(2, 3, list(3, 6), set(6, 12), map(3, 6)));
assertRows(execute("SELECT * FROM %s WHERE c NOT CONTAINS 2 AND c NOT CONTAINS 3 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE c CONTAINS 2 AND c NOT CONTAINS 3 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
// Checks filtering for sets
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE d CONTAINS 4");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE d NOT CONTAINS 4");
assertRows(execute("SELECT * FROM %s WHERE d CONTAINS 4 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
@ -1398,26 +1414,71 @@ public class SelectTest extends CQLTester
assertRows(execute("SELECT * FROM %s WHERE d CONTAINS 4 AND d CONTAINS 6 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(execute("SELECT * FROM %s WHERE d NOT CONTAINS 4 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)),
row(2, 3, list(3, 6), set(6, 12), map(3, 6)));
assertRows(execute("SELECT * FROM %s WHERE d NOT CONTAINS 4 AND d NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE d CONTAINS 4 AND d NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
// Checks filtering for maps
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE e CONTAINS 2");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE e NOT CONTAINS 2");
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS 2 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE e NOT CONTAINS 2 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)),
row(2, 3, list(3, 6), set(6, 12), map(3, 6)));
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE e NOT CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(2, 3, list(3, 6), set(6, 12), map(3, 6)));
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS 2 AND e NOT CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(execute("SELECT * FROM %s WHERE e[1] = 6 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
execute("INSERT INTO %s (a, b, c, d, e) VALUES (1, 2, [1, 6], {2, 12}, {1: 6})");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (1, 3, [3, 2], {6, 4}, {3: 2})");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (1, 4, [1, 2], {2, 4}, {1: 2})");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (2, 3, [3, 6], {6, 12}, {3: 6})");
assertRows(execute("SELECT * FROM %s WHERE e[1] != 6 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertEmpty(execute("SELECT * FROM %s WHERE e[1] != 6 AND e[3] != 2 ALLOW FILTERING"));
assertEmpty(execute("SELECT * FROM %s WHERE e[1] = 6 AND e[3] = 2 ALLOW FILTERING"));
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS KEY 1 AND e[1] != 6 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS KEY 1 AND e CONTAINS 2 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS KEY 1 AND e NOT CONTAINS 2 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE c CONTAINS 2 AND d CONTAINS 4 AND e CONTAINS KEY 3 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(execute("SELECT * FROM %s WHERE c CONTAINS 2 AND d CONTAINS 4 AND e NOT CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
});
// Checks filtering with null
@ -1434,6 +1495,19 @@ public class SelectTest extends CQLTester
assertInvalidMessage("Invalid null value for e[1]",
"SELECT * FROM %s WHERE e[1] = null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column c",
"SELECT * FROM %s WHERE c NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column d",
"SELECT * FROM %s WHERE d NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column e",
"SELECT * FROM %s WHERE e NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column e",
"SELECT * FROM %s WHERE e NOT CONTAINS KEY null ALLOW FILTERING");
assertInvalidMessage("Invalid null map key for column e",
"SELECT * FROM %s WHERE e[null] != 2 ALLOW FILTERING");
assertInvalidMessage("Invalid null value for e[1]",
"SELECT * FROM %s WHERE e[1] != null ALLOW FILTERING");
// Checks filtering with unset
assertInvalidMessage("Invalid unset value for column c",
"SELECT * FROM %s WHERE c CONTAINS ? ALLOW FILTERING",
@ -1453,6 +1527,25 @@ public class SelectTest extends CQLTester
assertInvalidMessage("Invalid unset value for e[1]",
"SELECT * FROM %s WHERE e[1] = ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column c",
"SELECT * FROM %s WHERE c NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column d",
"SELECT * FROM %s WHERE d NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column e",
"SELECT * FROM %s WHERE e NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column e",
"SELECT * FROM %s WHERE e NOT CONTAINS KEY ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset map key for column e",
"SELECT * FROM %s WHERE e[?] != 2 ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for e[1]",
"SELECT * FROM %s WHERE e[1] != ? ALLOW FILTERING",
unset());
}
@Test
@ -1554,6 +1647,9 @@ public class SelectTest extends CQLTester
assertInvalidMessage("Map-entry predicates on frozen map column e are not supported",
"SELECT * FROM %s WHERE e[1] = 6 ALLOW FILTERING");
assertInvalidMessage("Map-entry predicates on frozen map column e are not supported",
"SELECT * FROM %s WHERE e[1] != 6 ALLOW FILTERING");
assertRows(execute("SELECT * FROM %s WHERE e CONTAINS KEY 1 AND e CONTAINS 2 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
@ -1639,7 +1735,7 @@ public class SelectTest extends CQLTester
}
@Test
public void testCKQueryWithValueOver64K() throws Throwable
public void testCKQueryWithValueOver64K()
{
createTable("CREATE TABLE %s (a text, b text, PRIMARY KEY (a, b))");
@ -1922,42 +2018,80 @@ public class SelectTest extends CQLTester
assertRows(execute("SELECT * FROM %s WHERE b >= 4 AND c CONTAINS 2 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE b < 0 AND c NOT CONTAINS 2");
assertRows(
execute("SELECT * FROM %s WHERE a > 0 AND b <= 3 AND c CONTAINS 2 AND c CONTAINS 3 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(
execute("SELECT * FROM %s WHERE a > 0 AND b <= 3 AND c NOT CONTAINS 1 AND c NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
// Checks filtering for sets
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE a = 1 AND d CONTAINS 4");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE a = 1 AND d NOT CONTAINS 4");
assertRows(execute("SELECT * FROM %s WHERE d CONTAINS 4 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE d NOT CONTAINS 4 ALLOW FILTERING"),
row(2, 3, list(3, 6), set(6, 12), map(3, 6)),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE d CONTAINS 4 AND d CONTAINS 6 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(execute("SELECT * FROM %s WHERE d NOT CONTAINS 4 AND d NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
// Checks filtering for maps
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE e CONTAINS 2");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE e NOT CONTAINS 2");
assertRows(execute("SELECT * FROM %s WHERE a < 2 AND b >= 3 AND e CONTAINS 2 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE a < 2 AND b >= 3 AND e NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE a = 1 AND e CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE a = 1 AND e NOT CONTAINS KEY 3 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE a in (1) AND b in (2) AND e[1] = 6 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE a in (1) AND b in (2) AND e[1] != 2 ALLOW FILTERING"),
row(1, 2, list(1, 6), set(2, 12), map(1, 6)));
assertRows(execute("SELECT * FROM %s WHERE a = 1 AND e CONTAINS KEY 1 AND e CONTAINS 2 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(execute("SELECT * FROM %s WHERE a = 1 AND e CONTAINS KEY 1 AND e NOT CONTAINS 6 ALLOW FILTERING"),
row(1, 4, list(1, 2), set(2, 4), map(1, 2)));
assertRows(
execute("SELECT * FROM %s WHERE a >= 1 AND b in (3) AND c CONTAINS 2 AND d CONTAINS 4 AND e CONTAINS KEY 3 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
assertRows(
execute("SELECT * FROM %s WHERE a >= 1 AND b in (3) AND c CONTAINS 2 AND d CONTAINS 4 AND e NOT CONTAINS KEY 1 ALLOW FILTERING"),
row(1, 3, list(3, 2), set(6, 4), map(3, 2)));
});
// Checks filtering with null
@ -1973,6 +2107,19 @@ public class SelectTest extends CQLTester
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[null] = 2 ALLOW FILTERING");
assertInvalidMessage("Invalid null value for e[1]",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[1] = null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column c",
"SELECT * FROM %s WHERE a > 1 AND c NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column d",
"SELECT * FROM %s WHERE b < 1 AND d NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e NOT CONTAINS null ALLOW FILTERING");
assertInvalidMessage("Invalid null value for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e NOT CONTAINS KEY null ALLOW FILTERING");
assertInvalidMessage("Invalid null map key for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[null] != 2 ALLOW FILTERING");
assertInvalidMessage("Invalid null value for e[1]",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[1] != null ALLOW FILTERING");
// Checks filtering with unset
assertInvalidMessage("Invalid unset value for column c",
@ -1993,6 +2140,24 @@ public class SelectTest extends CQLTester
assertInvalidMessage("Invalid unset value for e[1]",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[1] = ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column c",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND c NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column d",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND d NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e NOT CONTAINS ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e NOT CONTAINS KEY ? ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset map key for column e",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[?] != 2 ALLOW FILTERING",
unset());
assertInvalidMessage("Invalid unset value for e[1]",
"SELECT * FROM %s WHERE a >= 1 AND b < 1 AND e[1] != ? ALLOW FILTERING",
unset());
}
@Test
@ -2157,12 +2322,26 @@ public class SelectTest extends CQLTester
assertRows(execute("SELECT * FROM %s WHERE a = 21 AND b CONTAINS 2 ALLOW FILTERING"),
row(21, list(2, 3), 24));
assertRows(execute("SELECT * FROM %s WHERE a = 21 AND b NOT CONTAINS 2 ALLOW FILTERING"),
row(21, list(3, 3), 34));
assertInvalidMessage("Clustering column restrictions require the use of secondary indices" +
" or filtering for map-element restrictions and for the following operators: CONTAINS, CONTAINS KEY, LIKE, ANN",
"SELECT * FROM %s WHERE a = 21 AND b CONTAINS 2");
assertInvalidMessage("Clustering column restrictions require the use of secondary indices or " +
"filtering for map-element restrictions and for the following operators: CONTAINS, " +
"CONTAINS KEY, LIKE, ANN, NOT CONTAINS, NOT CONTAINS KEY",
"SELECT * FROM %s WHERE b NOT CONTAINS 2");
assertRows(execute("SELECT * FROM %s WHERE b CONTAINS 2 ALLOW FILTERING"),
row(21, list(2, 3), 24));
assertRows(execute("SELECT * FROM %s WHERE b NOT CONTAINS 2 ALLOW FILTERING"),
row(11, list(1, 3), 14),
row(21, list(3, 3), 34));
assertInvalidMessage("Clustering column restrictions require the use of secondary indices" +
" or filtering for map-element restrictions and for the following operators: CONTAINS, CONTAINS KEY, LIKE, ANN",
"SELECT * FROM %s WHERE b CONTAINS 2");
@ -2171,6 +2350,8 @@ public class SelectTest extends CQLTester
row(11, list(1, 3), 14),
row(21, list(2, 3), 24),
row(21, list(3, 3), 34));
assertRows(execute("SELECT * FROM %s WHERE b NOT CONTAINS 3 ALLOW FILTERING"));
});
// non-first clustering column
@ -2184,12 +2365,28 @@ public class SelectTest extends CQLTester
assertRows(execute("SELECT * FROM %s WHERE a = 21 AND c CONTAINS 2 ALLOW FILTERING"),
row(21, 22, list(2, 3), 24));
assertRows(execute("SELECT * FROM %s WHERE a = 21 AND c NOT CONTAINS 2 ALLOW FILTERING"),
row(21, 22, list(3, 3), 34));
assertInvalidMessage("Clustering column restrictions require the use of secondary indices" +
" or filtering for map-element restrictions and for the following operators: CONTAINS, CONTAINS KEY, LIKE, ANN",
"SELECT * FROM %s WHERE a = 21 AND c CONTAINS 2");
assertInvalidMessage("Clustering column restrictions require the use of secondary indices or filtering" +
" for map-element restrictions and for the following operators: CONTAINS, CONTAINS KEY, LIKE, " +
"ANN, NOT CONTAINS, NOT CONTAINS KEY",
"SELECT * FROM %s WHERE a = 21 AND c NOT CONTAINS 2");
assertRows(execute("SELECT * FROM %s WHERE b > 20 AND c CONTAINS 2 ALLOW FILTERING"),
row(21, 22, list(2, 3), 24));
assertRows(execute("SELECT * FROM %s WHERE b > 20 AND c NOT CONTAINS 2 ALLOW FILTERING"),
row(21, 22, list(3, 3), 34));
assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
"SELECT * FROM %s WHERE b > 20 AND c NOT CONTAINS 2");
assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
"SELECT * FROM %s WHERE b > 20 AND c CONTAINS 2");
@ -2197,6 +2394,8 @@ public class SelectTest extends CQLTester
row(11, 12, list(1, 3), 14),
row(21, 22, list(2, 3), 24),
row(21, 22, list(3, 3), 34));
assertEmpty(execute("SELECT * FROM %s WHERE c NOT CONTAINS 3 ALLOW FILTERING"));
});
createTable("CREATE TABLE %s (a int, b int, c frozen<map<text, text>>, d int, PRIMARY KEY (a, b, c))");
@ -2208,8 +2407,15 @@ public class SelectTest extends CQLTester
beforeAndAfterFlush(() -> {
assertRows(execute("SELECT * FROM %s WHERE b > 20 AND c CONTAINS KEY '2' ALLOW FILTERING"),
row(21, 22, map("2", "3"), 24));
assertRows(execute("SELECT * FROM %s WHERE b > 20 AND c NOT CONTAINS KEY '2' ALLOW FILTERING"),
row(21, 22, map("3", "3"), 34));
assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
"SELECT * FROM %s WHERE b > 20 AND c CONTAINS KEY '2'");
assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
"SELECT * FROM %s WHERE b > 20 AND c NOT CONTAINS KEY '2'");
});
}
@ -2241,6 +2447,9 @@ public class SelectTest extends CQLTester
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE pk CONTAINS KEY 1");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE,
"SELECT * FROM %s WHERE pk NOT CONTAINS KEY 1");
beforeAndAfterFlush(() -> {
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk CONTAINS KEY 1 ALLOW FILTERING"),
row(map(1, 2), 1, 1),
@ -2262,6 +2471,23 @@ public class SelectTest extends CQLTester
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk CONTAINS KEY 1 AND ck = 1 AND v = 3 ALLOW FILTERING"),
row(map(1, 2, 3, 4), 1, 3));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk NOT CONTAINS KEY 1 ALLOW FILTERING"),
row(map(5, 6), 5, 5),
row(map(7, 8), 6, 6));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk CONTAINS KEY 1 AND pk NOT CONTAINS 4 ALLOW FILTERING"),
row(map(1, 2), 1, 1),
row(map(1, 2), 2, 2));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk NOT CONTAINS KEY 1 AND pk CONTAINS 8 ALLOW FILTERING"),
row(map(7, 8), 6, 6));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk NOT CONTAINS KEY 1 AND pk NOT CONTAINS 8 ALLOW FILTERING"),
row(map(5, 6), 5, 5));
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk NOT CONTAINS KEY 1 AND v = 5 ALLOW FILTERING"),
row(map(5, 6), 5, 5));
});
}
@ -2343,8 +2569,16 @@ public class SelectTest extends CQLTester
row(21, 22, 23, list(2, 4)),
row(21, 25, 26, list(2, 7)));
assertRows(executeFilteringOnly("SELECT a, b, c, d FROM %s WHERE b > 20 AND d CONTAINS 2 AND d contains 4"),
assertRows(executeFilteringOnly("SELECT a, b, c, d FROM %s WHERE b > 20 AND d NOT CONTAINS 2"),
row(31, 32, 33, list(3, 4)));
assertRows(executeFilteringOnly("SELECT a, b, c, d FROM %s WHERE b > 20 AND d CONTAINS 2 AND d CONTAINS 4"),
row(21, 22, 23, list(2, 4)));
assertRows(executeFilteringOnly("SELECT a, b, c, d FROM %s WHERE b > 20 AND d NOT CONTAINS 2 AND d CONTAINS 4"),
row(31, 32, 33, list(3, 4)));
assertRows(executeFilteringOnly("SELECT a, b, c, d FROM %s WHERE b > 20 AND d NOT CONTAINS 2 AND d NOT CONTAINS 4"));
});
}
@ -2413,7 +2647,7 @@ public class SelectTest extends CQLTester
* Check select with ith different column order. See CASSANDRA-10988
*/
@Test
public void testClusteringOrderWithSlice() throws Throwable
public void testClusteringOrderWithSlice()
{
// non-compound, ASC order
createTable("CREATE TABLE %s (a text, b int, PRIMARY KEY (a, b)) WITH CLUSTERING ORDER BY (b ASC)");
@ -2844,7 +3078,7 @@ public class SelectTest extends CQLTester
}
@Test
public void testWithDistinctAndJsonAsColumnName() throws Throwable
public void testWithDistinctAndJsonAsColumnName()
{
createTable("CREATE TABLE %s (distinct int, json int, value int, PRIMARY KEY(distinct, json))");
execute("INSERT INTO %s (distinct, json, value) VALUES (0, 0, 0)");
@ -2947,6 +3181,9 @@ public class SelectTest extends CQLTester
assertRows(execute("SELECT * FROM %s WHERE m IN ({1:1s, 2:2s}, {1:1s, 3:3s}) ALLOW FILTERING"),
row(0, map(1, Duration.from("1s"), 2, Duration.from("2s"))),
row(2, map(1, Duration.from("1s"), 3, Duration.from("3s"))));
assertRows(execute("SELECT * FROM %s WHERE m NOT CONTAINS 1s ALLOW FILTERING"),
row(1, map(2, Duration.from("2s"), 3, Duration.from("3s"))));
}
else
{
@ -3066,30 +3303,41 @@ public class SelectTest extends CQLTester
beforeAndAfterFlush(() -> {
// lists
assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE l NOT CONTAINS 4 ALLOW FILTERING"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND l CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND l NOT CONTAINS 4 ALLOW FILTERING"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 2 ALLOW FILTERING"), row(1, 0), row(0, 0));
assertEmpty(execute("SELECT k, v FROM %s WHERE l CONTAINS 6 ALLOW FILTERING"));
// sets
assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'a' ALLOW FILTERING" ), row(0, 0), row(0, 2));
assertRowsIgnoringOrder(execute("SELECT k, v FROM %s WHERE s NOT CONTAINS 'a' ALLOW FILTERING" ), row(0, 1), row(1, 1));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND s CONTAINS 'a' ALLOW FILTERING"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND s NOT CONTAINS 'a' ALLOW FILTERING" ), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'd' ALLOW FILTERING"), row(1, 1));
assertEmpty(execute("SELECT k, v FROM %s WHERE s CONTAINS 'e' ALLOW FILTERING"));
assertRows(execute("SELECT k, v FROM %s WHERE s NOT CONTAINS 'a' AND s NOT CONTAINS 'c' ALLOW FILTERING"), row(1, 1));
// maps
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(1, 1), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE m NOT CONTAINS 1 ALLOW FILTERING"), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m NOT CONTAINS 1 ALLOW FILTERING"), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 2 ALLOW FILTERING"), row(0, 1));
assertEmpty(execute("SELECT k, v FROM %s WHERE m CONTAINS 4 ALLOW FILTERING"));
assertEmpty(execute("SELECT k, v FROM %s WHERE m NOT CONTAINS 1 AND m NOT CONTAINS 3 ALLOW FILTERING"));
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS KEY 'a' ALLOW FILTERING"), row(1, 1), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE m NOT CONTAINS KEY 'a' ALLOW FILTERING"), row(1, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS KEY 'a' ALLOW FILTERING"), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m NOT CONTAINS KEY 'a' ALLOW FILTERING"), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS KEY 'c' ALLOW FILTERING"), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m NOT CONTAINS KEY 'c' ALLOW FILTERING"), row(0, 0), row(0, 1));
});
}
@Test
public void testMixedTTLOnColumns() throws Throwable
public void testMixedTTLOnColumns()
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k) VALUES (2);");
@ -3108,14 +3356,14 @@ public class SelectTest extends CQLTester
if ( i % 2 == 0) // Every odd row has a null i/ttl
assertTrue(row.getInt("name_ttl") >= 90 && row.getInt("name_ttl") <= 100);
else
assertTrue(row.has("name_ttl") == false);
assertFalse(row.has("name_ttl"));
i++;
}
}
@Test
public void testMixedTTLOnColumnsWide() throws Throwable
public void testMixedTTLOnColumnsWide()
{
createTable("CREATE TABLE %s (k int, c int, i int, PRIMARY KEY (k, c))");
execute("INSERT INTO %s (k, c) VALUES (2, 2);");
@ -3138,14 +3386,14 @@ public class SelectTest extends CQLTester
if ( i % 2 == 0) // Every odd row has a null i/ttl
assertTrue(row.getInt("name_ttl") >= 90 && row.getInt("name_ttl") <= 100);
else
assertTrue(row.has("name_ttl") == false);
assertFalse(row.has("name_ttl"));
i++;
}
}
@Test // CASSANDRA-14989
public void testTokenFctAcceptsValidArguments() throws Throwable
public void testTokenFctAcceptsValidArguments()
{
createTable("CREATE TABLE %s (k1 uuid, k2 text, PRIMARY KEY ((k1, k2)))");
execute("INSERT INTO %s (k1, k2) VALUES (uuid(), 'k2')");
@ -3219,7 +3467,7 @@ public class SelectTest extends CQLTester
}
@Test
public void testQuotedMapTextData() throws Throwable
public void testQuotedMapTextData()
{
createTable("CREATE TABLE " + KEYSPACE + ".t1 (id int, data text, PRIMARY KEY (id))");
createTable("CREATE TABLE " + KEYSPACE + ".t2 (id int, data map<int, text>, PRIMARY KEY (id))");
@ -3232,7 +3480,7 @@ public class SelectTest extends CQLTester
}
@Test
public void testQuotedSimpleCollectionsData() throws Throwable
public void testQuotedSimpleCollectionsData()
{
createTable("CREATE TABLE " + KEYSPACE + ".t3 (id int, set_data set<text>, list_data list<text>, tuple_data tuple<int, text>, PRIMARY KEY (id))");
@ -3244,7 +3492,7 @@ public class SelectTest extends CQLTester
}
@Test
public void testQuotedUDTData() throws Throwable
public void testQuotedUDTData()
{
createType("CREATE TYPE " + KEYSPACE + ".random (data text)");
createTable("CREATE TABLE " + KEYSPACE + ".t4 (id int, udt_data frozen<random>, PRIMARY KEY (id))");
@ -3268,12 +3516,12 @@ public class SelectTest extends CQLTester
assertInvalidMessage("Collection column 'm' (map<text, text>) cannot be restricted by a '>' relation",
"SELECT * FROM %s WHERE m > {'lmn' : 'f'} AND m['lmn'] = 'foo2'");
assertInvalidMessage("Collection column fm can only be restricted by CONTAINS, CONTAINS KEY," +
" or map-entry equality if it already restricted by one of those",
assertInvalidMessage("Collection column fm can only be restricted by CONTAINS, CONTAINS KEY, NOT_CONTAINS, " +
"NOT_CONTAINS_KEY or map-entry equality if it already restricted by one of those",
"SELECT * FROM %s WHERE fm > {'lmn' : 'f'} AND fm CONTAINS 'foo'");
assertInvalidMessage("Collection column fm can only be restricted by CONTAINS, CONTAINS KEY," +
" or map-entry equality if it already restricted by one of those",
assertInvalidMessage("Collection column fm can only be restricted by CONTAINS, CONTAINS KEY, NOT_CONTAINS, " +
"NOT_CONTAINS_KEY or map-entry equality if it already restricted by one of those",
"SELECT * FROM %s WHERE fm > {'lmn' : 'f'} AND fm CONTAINS KEY 'lmn'");
assertInvalidMessage("Map-entry predicates on frozen map column fm are not supported",

View File

@ -18,6 +18,7 @@
package org.apache.cassandra.index.sai.cql;
import org.apache.cassandra.cql3.restrictions.StatementRestrictions;
import org.junit.Test;
import org.apache.cassandra.index.sai.SAITester;
@ -41,4 +42,34 @@ public class TokenRangeReadTest extends SAITester
assertRows(execute("SELECT * FROM %s WHERE token(k1) >= token(1) AND token(k1) <= token(1) AND v1 = '1'"), row(1, "1"));
});
}
@Test
public void testTokenRangeWithNotContains() throws Throwable
{
createTable("CREATE TABLE %s (k1 int, v1 set<text>, PRIMARY KEY (k1))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
execute("INSERT INTO %S(k1, v1) values(1, {'a', 'b', 'c'})");
execute("INSERT INTO %S(k1, v1) values(2, {'a', 'd'})");
beforeAndAfterFlush(() -> {
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT k1 FROM %s WHERE v1 NOT CONTAINS 'd'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT k1 FROM %s WHERE token(k1) >= token(1) AND token(k1) <= token(1) AND v1 NOT CONTAINS 'z'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT k1 FROM %s WHERE token(k1) >= token(2) AND token(k1) <= token(2) AND v1 NOT CONTAINS 'z'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT k1 FROM %s WHERE token(k1) > token(2) AND token(k1) <= token(2) AND v1 NOT CONTAINS 'z'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT k1 FROM %s WHERE token(k1) >= token(2) AND token(k1) < token(2) AND v1 NOT CONTAINS 'z'");
});
}
@Test
public void testInvalidOperatorTokenRangeRead() throws Throwable
{
createTable("CREATE TABLE %s (k1 int, v1 set<text>, PRIMARY KEY (k1))");
createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName()));
execute("INSERT INTO %S(k1, v1) values(1, {'a', 'b', 'c'})");
execute("INSERT INTO %S(k1, v1) values(2, {'a', 'd'})");
assertInvalidMessage("Unsupported '!=' relation: token(k1) != 'token(2)","SELECT k1 FROM %s WHERE token(k1) != 'token(2)'");
}
}

View File

@ -69,9 +69,7 @@ public class UnindexedExpressionsTest extends SAITester
// The IS NOT operator is only valid on materialized views
assertInvalidMessage("Unsupported restriction:", "SELECT pk FROM %s WHERE val1 = 1 AND val2 is not null");
// The != operator is currently not supported at all
assertInvalidMessage("Unsupported '!=' relation: val2 != '22'", "SELECT pk FROM %s WHERE val1 = 1 AND val2 != '22'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT pk FROM %s WHERE val1 = 1 AND val2 != '22'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT pk FROM %s WHERE val1 = 1 AND val2 < '22'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT pk FROM %s WHERE val1 = 1 AND val2 <= '11'");
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, "SELECT pk FROM %s WHERE val1 = 1 AND val2 >= '11'");