mirror of https://github.com/apache/cassandra
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:
parent
8d154ba66f
commit
e0074a31ef
|
@ -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)
|
||||
|
|
|
@ -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 )?
|
||||
|
|
|
@ -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 ] )*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1686,7 +1686,7 @@ FROM +
|
|||
| `(' (`,' )* `)' IN `(' ( ( `,' )* )? `)' +
|
||||
| TOKEN `(' ( `,' )* `)'
|
||||
|
||||
::= `=' | `<' | `>' | `<=' | `>=' | CONTAINS | CONTAINS KEY +
|
||||
::= `=' | `<' | `>' | `<=' | `>=' | CONTAINS | CONTAINS KEY | NOT CONTAINS | NOT CONTAINS KEY +
|
||||
::= (`,' )* +
|
||||
::= ( `,' )* +
|
||||
::= ( ASC | DESC )? +
|
||||
|
|
|
@ -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>)?)*
|
||||
|
|
|
@ -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 ')
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)'");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'");
|
||||
|
|
Loading…
Reference in New Issue