http://git-wip-us.apache.org/repos/asf/cassandra/blob/01115f72/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java new file mode 100644 index 0000000..552e39e --- /dev/null +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java @@ -0,0 +1,962 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.cql3.validation.operations; + +import org.junit.Test; + +import org.apache.cassandra.cql3.CQLTester; + +import static org.junit.Assert.assertEquals; + +public class SelectMultiColumnRelationTest extends CQLTester +{ + @Test + public void testSingleClusteringInvalidQueries() throws Throwable + { + for (String compactOption : new String[] { "", " WITH COMPACT STORAGE" }) + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + compactOption); + + assertInvalidSyntax("SELECT * FROM %s WHERE () = (?, ?)", 1, 2); + assertInvalidMessage("b cannot be restricted by more than one relation if it includes an Equal", + "SELECT * FROM %s WHERE a = 0 AND (b) = (?) AND (b) > (?)", 0, 0); + assertInvalidMessage("More than one restriction was found for the start bound on b", + "SELECT * FROM %s WHERE a = 0 AND (b) > (?) AND (b) > (?)", 0, 1); + assertInvalidMessage("Multi-column relations can only be applied to clustering columns but was applied to: a", + "SELECT * FROM %s WHERE (a, b) = (?, ?)", 0, 0); + } + } + + @Test + public void testMultiClusteringInvalidQueries() throws Throwable + { + for (String compactOption : new String[] { "", " WITH COMPACT STORAGE" }) + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption); + + assertInvalidSyntax("SELECT * FROM %s WHERE a = 0 AND (b, c) > ()"); + assertInvalidMessage("Expected 2 elements in value tuple, but got 3: (?, ?, ?)", + "SELECT * FROM %s WHERE a = 0 AND (b, c) > (?, ?, ?)", 1, 2, 3); + assertInvalidMessage("Invalid null value in condition for column c", + "SELECT * FROM %s WHERE a = 0 AND (b, c) > (?, ?)", 1, null); + + // Wrong order of columns + assertInvalidMessage("Clustering columns must appear in the PRIMARY KEY order in multi-column relations: (d, c, b) = (?, ?, ?)", + "SELECT * FROM %s WHERE a = 0 AND (d, c, b) = (?, ?, ?)", 0, 0, 0); + assertInvalidMessage("Clustering columns must appear in the PRIMARY KEY order in multi-column relations: (d, c, b) > (?, ?, ?)", + "SELECT * FROM %s WHERE a = 0 AND (d, c, b) > (?, ?, ?)", 0, 0, 0); + + // Wrong number of values + assertInvalidMessage("Expected 3 elements in value tuple, but got 2: (?, ?)", + "SELECT * FROM %s WHERE a=0 AND (b, c, d) IN ((?, ?))", 0, 1); + assertInvalidMessage("Expected 3 elements in value tuple, but got 5: (?, ?, ?, ?, ?)", + "SELECT * FROM %s WHERE a=0 AND (b, c, d) IN ((?, ?, ?, ?, ?))", 0, 1, 2, 3, 4); + + // Missing first clustering column + assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted as preceding column \"b\" is not restricted", + "SELECT * FROM %s WHERE a = 0 AND (c, d) = (?, ?)", 0, 0); + assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted as preceding column \"b\" is not restricted", + "SELECT * FROM %s WHERE a = 0 AND (c, d) > (?, ?)", 0, 0); + + // Nulls + assertInvalidMessage("Invalid null value in condition for columns: [b, c, d]", + "SELECT * FROM %s WHERE a = 0 AND (b, c, d) IN ((?, ?, ?))", 1, 2, null); + + // Wrong type for 'd' + assertInvalid("SELECT * FROM %s WHERE a = 0 AND (b, c, d) = (?, ?, ?)", 1, 2, "foobar"); + assertInvalid("SELECT * FROM %s WHERE a = 0 AND b = (?, ?, ?)", 1, 2, 3); + + // Mix single and tuple inequalities + assertInvalidMessage("Mixing single column relations and multi column relations on clustering columns is not allowed", + "SELECT * FROM %s WHERE a = 0 AND (b, c, d) > (?, ?, ?) AND b < ?", 0, 1, 0, 1); + assertInvalidMessage("Mixing single column relations and multi column relations on clustering columns is not allowed", + "SELECT * FROM %s WHERE a = 0 AND (b, c, d) > (?, ?, ?) AND c < ?", 0, 1, 0, 1); + assertInvalidMessage("Mixing single column relations and multi column relations on clustering columns is not allowed", + "SELECT * FROM %s WHERE a = 0 AND b > ? AND (b, c, d) < (?, ?, ?)", 1, 1, 1, 0); + assertInvalidMessage("Mixing single column relations and multi column relations on clustering columns is not allowed", + "SELECT * FROM %s WHERE a = 0 AND c > ? AND (b, c, d) < (?, ?, ?)", 1, 1, 1, 0); + + assertInvalidMessage("Multi-column relations can only be applied to clustering columns but was applied to: a", + "SELECT * FROM %s WHERE (a, b, c, d) IN ((?, ?, ?, ?))", 0, 1, 2, 3); + assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted as preceding column \"b\" is not restricted", + "SELECT * FROM %s WHERE (c, d) IN ((?, ?))", 0, 1); + + assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)", + "SELECT * FROM %s WHERE a = ? AND b > ? AND (c, d) IN ((?, ?))", 0, 0, 0, 0); + + assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)", + "SELECT * FROM %s WHERE a = ? AND b > ? AND (c, d) > (?, ?)", 0, 0, 0, 0); + assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)", + "SELECT * FROM %s WHERE a = ? AND (c, d) > (?, ?) AND b > ? ", 0, 0, 0, 0); + assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column", + "SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) AND (b) < (?) AND (c) < (?)", 0, 0, 0, 0, 0); + assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column", + "SELECT * FROM %s WHERE a = ? AND (c) < (?) AND (b, c) > (?, ?) AND (b) < (?)", 0, 0, 0, 0, 0); + assertInvalidMessage("Clustering column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)", + "SELECT * FROM %s WHERE a = ? AND (b) < (?) AND (c) < (?) AND (b, c) > (?, ?)", 0, 0, 0, 0, 0); + + assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column", + "SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) AND (c) < (?)", 0, 0, 0, 0); + } + } + + @Test + public void testMultiAndSingleColumnRelationMix() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) = (?, ?)", 0, 1, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b IN (?, ?) and (c, d) = (?, ?)", 0, 0, 1, 0, 0), + row(0, 0, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) IN ((?))", 0, 1, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b IN (?, ?) and (c) IN ((?))", 0, 0, 1, 0), + row(0, 0, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) IN ((?), (?))", 0, 1, 0, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) IN ((?, ?))", 0, 1, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) IN ((?, ?), (?, ?))", 0, 1, 0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b IN (?, ?) and (c, d) IN ((?, ?), (?, ?))", 0, 0, 1, 0, 0, 1, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) > (?, ?)", 0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b IN (?, ?) and (c, d) > (?, ?)", 0, 0, 1, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) > (?, ?) and (c) <= (?) ", 0, 1, 0, 0, 1), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) >= (?, ?) and (c, d) < (?, ?)", 0, 1, 0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d = ?", 0, 0, 1, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) IN ((?, ?), (?, ?)) and d = ?", 0, 0, 1, 0, 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) = (?) and d = ?", 0, 0, 1, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d IN (?, ?)", 0, 0, 1, 0, 2), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) = (?) and d IN (?, ?)", 0, 0, 1, 0, 2), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d >= ?", 0, 0, 1, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and d < 1 and (b, c) = (?, ?) and d >= ?", 0, 0, 1, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and d < 1 and (b, c) IN ((?, ?), (?, ?)) and d >= ?", 0, 0, 1, 0, 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0)); + } + } + + @Test + public void testSeveralMultiColumnRelation() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) = (?, ?)", 0, 1, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?), (?)) and (c, d) = (?, ?)", 0, 0, 1, 0, 0), + row(0, 0, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c) IN ((?))", 0, 1, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?),(?)) and (c) IN ((?))", 0, 0, 1, 0), + row(0, 0, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c) IN ((?), (?))", 0, 1, 0, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) IN ((?, ?))", 0, 1, 0, 0), + row(0, 1, 0, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) IN ((?, ?), (?, ?))", 0, 1, 0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?), (?)) and (c, d) IN ((?, ?), (?, ?))", 0, 0, 1, 0, 0, 1, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) > (?, ?)", 0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?),(?)) and (c, d) > (?, ?)", 0, 0, 1, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) > (?, ?) and (c) <= (?) ", 0, 1, 0, 0, 1), + row(0, 1, 1, 0), + row(0, 1, 1, 1)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) >= (?, ?) and (c, d) < (?, ?)", 0, 1, 0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d = ?", 0, 0, 1, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) IN ((?, ?), (?, ?)) and d = ?", 0, 0, 1, 0, 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (d) < (1) and (b, c) = (?, ?) and (d) >= (?)", 0, 0, 1, 0), + row(0, 0, 1, 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (d) < (1) and (b, c) IN ((?, ?), (?, ?)) and (d) >= (?)", 0, 0, 1, 0, 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0)); + } + } + + @Test + public void testSinglePartitionInvalidQueries() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)" + compactOption); + assertInvalidMessage("Multi-column relations can only be applied to clustering columns but was applied to: a", + "SELECT * FROM %s WHERE (a) > (?)", 0); + assertInvalidMessage("Multi-column relations can only be applied to clustering columns but was applied to: a", + "SELECT * FROM %s WHERE (a) = (?)", 0); + assertInvalidMessage("Multi-column relations can only be applied to clustering columns but was applied to: b", + "SELECT * FROM %s WHERE (b) = (?)", 0); + } + } + + @Test + public void testSingleClustering() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + compactOption); + + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 0); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 0); + + // Equalities + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 1), + row(0, 1, 0) + ); + + // Same but check the whole tuple can be prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = ?", 0, tuple(1)), + row(0, 1, 0) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 3)); + + // Inequalities + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0), + row(0, 1, 0), + row(0, 2, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 1), + row(0, 1, 0), + row(0, 2, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 2), + row(0, 0, 0), + row(0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1), + row(0, 0, 0), + row(0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?) AND (b) < (?)", 0, 0, 2), + row(0, 1, 0) + ); + } + } + + @Test + public void testNonEqualsRelation() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)" + compactOption); + assertInvalidMessage("Unsupported \"!=\" relation: (b) != (0)", + "SELECT * FROM %s WHERE a = 0 AND (b) != (0)"); + } + } + + @Test + public void testMultipleClustering() throws Throwable + { + for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1); + + // Empty query + assertEmpty(execute("SELECT * FROM %s WHERE a = 0 AND (b, c, d) IN ()")); + + // Equalities + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + // Same with whole tuple prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = ?", 0, tuple(1)), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?)", 0, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + // Same with whole tuple prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = ?", 0, tuple(1, 1)), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) = (?, ?, ?)", 0, 1, 1, 1), + row(0, 1, 1, 1) + ); + + // Same with whole tuple prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) = ?", 0, tuple(1, 1, 1)), + row(0, 1, 1, 1) + ); + + // Inequalities + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?)", 0, 1, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) >= (?, ?)", 0, 1, 0), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?)", 0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) >= (?, ?, ?)", 0, 1, 1, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) < (?, ?)", 0, 0, 1), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) <= (?, ?)", 0, 0, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) < (?, ?, ?)", 0, 0, 1, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) <= (?, ?, ?)", 0, 0, 1, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b) < (?)", 0, 0, 1, 0, 1), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c) < (?, ?)", 0, 0, 1, 1, 1, 1), + row(0, 1, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c, d) < (?, ?, ?)", 0, 0, 1, 1, 1, 1, 0), + row(0, 1, 0, 0) + ); + + // Same with whole tuple prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > ? AND (b, c, d) < ?", 0, tuple(0, 1, 1), tuple(1, 1, 0)), + row(0, 1, 0, 0) + ); + + // reversed + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?) ORDER BY b DESC, c DESC, d DESC", 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?) ORDER BY b DESC, c DESC, d DESC", 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) >= (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 1, 0), + row(0, 1, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) >= (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 1, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?) ORDER BY b DESC, c DESC, d DESC", 0, 1), + row(0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?) ORDER BY b DESC, c DESC, d DESC", 0, 1), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 1, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) < (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) <= (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1), + row(0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) < (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) <= (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1), + row(0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b) < (?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 0, 1), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c) < (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1, 1, 1), + row(0, 1, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c, d) < (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1, 1, 1, 0), + row(0, 1, 0, 0) + ); + + // IN + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 0, 1, 0, 0, 1, 1), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + // same query but with whole tuple prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?)", 0, tuple(0, 1, 0), tuple(0, 1, 1)), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + // same query but with whole IN list prepared + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN ?", 0, list(tuple(0, 1, 0), tuple(0, 1, 1))), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + // same query, but reversed order for the IN values + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?)", 0, tuple(0, 1, 1), tuple(0, 1, 0)), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) IN ((?, ?))", 0, 0, 1), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?))", 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE a = ? and (b) IN ()", 0)); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN ((?, ?)) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN () ORDER BY b DESC, c DESC, d DESC", 0)); + + // IN on both partition key and clustering key + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 1, 1); + + assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) AND (b, c, d) IN (?, ?)", 0, 1, tuple(0, 1, 0), tuple(0, 1, 1)), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(1, 0, 1, 0), + row(1, 0, 1, 1) + ); + + // same but with whole IN lists prepared + assertRows(execute("SELECT * FROM %s WHERE a IN ? AND (b, c, d) IN ?", list(0, 1), list(tuple(0, 1, 0), tuple(0, 1, 1))), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(1, 0, 1, 0), + row(1, 0, 1, 1) + ); + + // same query, but reversed order for the IN values + assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) AND (b, c, d) IN (?, ?)", 1, 0, tuple(0, 1, 1), tuple(0, 1, 0)), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(1, 0, 1, 0), + row(1, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) and (b, c) IN ((?, ?))", 0, 1, 0, 1), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(1, 0, 1, 0), + row(1, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) and (b) IN ((?))", 0, 1, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 0), + row(0, 0, 1, 1), + row(1, 0, 0, 0), + row(1, 0, 1, 0), + row(1, 0, 1, 1) + ); + } + } + + @Test + public void testMultipleClusteringReversedComponents() throws Throwable + { + for (String compactOption : new String[]{"", " COMPACT STORAGE AND"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d)) WITH" + compactOption + " CLUSTERING ORDER BY (b DESC, c ASC, d DESC)"); + + // b and d are reversed in the clustering order + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0); + + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0), + row(0, 1, 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 0), + row(0, 1, 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 1), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1), + row(0, 1, 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 1, 1, 1, 0, 1, 1), + row(0, 1, 1, 1), + row(0, 0, 1, 1) + ); + + // same query, but reversed order for the IN values + assertRows(execute("SELECT * FROM %s WHERE a=? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 0, 1, 1, 1, 1, 1), + row(0, 1, 1, 1), + row(0, 0, 1, 1) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?, ?, ?, ?, ?)", + 0, tuple(1, 0, 0), tuple(1, 1, 1), tuple(1, 1, 0), tuple(0, 0, 0), tuple(0, 1, 1), tuple(0, 1, 0)), + row(0, 1, 0, 0), + row(0, 1, 1, 1), + row(0, 1, 1, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN (?)", 0, tuple(0, 1)), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN (?)", 0, tuple(0, 0)), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) IN ((?))", 0, 0), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 1, 0) + ); + + // preserve pre-6875 behavior (even though the query result is technically incorrect) + assertEmpty(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?)", 0, 1, 0)); + } + } + + @Test + public void testMultipleClusteringWithIndex() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d))"); + createIndex("CREATE INDEX ON %s (b)"); + createIndex("CREATE INDEX ON %s (e)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 1, 0, 1); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 1, 1, 2); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 1, 0, 1); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 1, 1, 2); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, 0, 0); + assertRows(execute("SELECT * FROM %s WHERE (b) = (?)", 1), + row(0, 1, 0, 0, 0), + row(0, 1, 1, 0, 1), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b, c) = (?, ?)", 1, 1); + assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) ALLOW FILTERING", 1, 1), + row(0, 1, 1, 0, 1), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b, c) = (?, ?) AND e = ?", 1, 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) AND e = ? ALLOW FILTERING", 1, 1, 2), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b) IN ((?)) AND e = ?", 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?)) AND e = ? ALLOW FILTERING", 1, 2), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ?", 0, 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ? ALLOW FILTERING", 0, 1, 2), + row(0, 0, 1, 1, 2), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b, c) IN ((?, ?)) AND e = ?", 0, 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b, c) IN ((?, ?)) AND e = ? ALLOW FILTERING", 0, 1, 2), + row(0, 0, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b, c) IN ((?, ?), (?, ?)) AND e = ?", 0, 1, 1, 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b, c) IN ((?, ?), (?, ?)) AND e = ? ALLOW FILTERING", 0, 1, 1, 1, 2), + row(0, 0, 1, 1, 2), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b) >= (?) AND e = ?", 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b) >= (?) AND e = ? ALLOW FILTERING", 1, 2), + row(0, 1, 1, 1, 2)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ?", 1, 1, 2); + assertRows(execute("SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ? ALLOW FILTERING", 1, 1, 2), + row(0, 1, 1, 1, 2)); + } + + @Test + public void testMultiplePartitionKeyAndMultiClusteringWithIndex() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, f int, PRIMARY KEY ((a, b), c, d, e))"); + createIndex("CREATE INDEX ON %s (c)"); + createIndex("CREATE INDEX ON %s (f)"); + + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 0, 1); + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 1, 2); + + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 0, 0, 3); + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 0, 4); + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 1, 5); + + execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 2, 0, 0, 5); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c) = (?)"); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) = (?) ALLOW FILTERING", 0, 1), + row(0, 0, 1, 0, 0, 3), + row(0, 0, 1, 1, 0, 4), + row(0, 0, 1, 1, 1, 5)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c, d) = (?, ?)", 0, 1, 1); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) = (?, ?) ALLOW FILTERING", 0, 1, 1), + row(0, 0, 1, 1, 0, 4), + row(0, 0, 1, 1, 1, 5)); + + assertInvalidMessage("Partition key parts: b must be restricted as other parts are", + "SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) ALLOW FILTERING", 0, 1, 1); + + assertInvalidMessage("Partition key parts: b must be restricted as other parts are", + "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) ALLOW FILTERING", 0, 1, 1); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c) IN ((?)) AND f = ?", 0, 1, 5); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?)) AND f = ? ALLOW FILTERING", 0, 1, 5), + row(0, 0, 1, 1, 1, 5)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c) IN ((?), (?)) AND f = ?", 0, 1, 2, 5); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?), (?)) AND f = ? ALLOW FILTERING", 0, 1, 2, 5), + row(0, 0, 1, 1, 1, 5), + row(0, 0, 2, 0, 0, 5)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) AND f = ?", 0, 1, 0, 3); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) AND f = ? ALLOW FILTERING", 0, 1, 0, 3), + row(0, 0, 1, 0, 0, 3)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c) >= (?) AND f = ?", 0, 1, 5); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) >= (?) AND f = ? ALLOW FILTERING", 0, 1, 5), + row(0, 0, 1, 1, 1, 5), + row(0, 0, 2, 0, 0, 5)); + + assertInvalidMessage("Cannot execute this query as it might involve data filtering", + "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) AND f = ?", 0, 1, 1, 5); + assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) AND f = ? ALLOW FILTERING", 0, 1, 1, 5), + row(0, 0, 1, 1, 1, 5), + row(0, 0, 2, 0, 0, 5)); + } + + @Test + public void testINWithDuplicateValue() throws Throwable + { + for (String compactOption : new String[] { "", " WITH COMPACT STORAGE" }) + { + createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2))" + compactOption); + execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, 1); + + assertRows(execute("SELECT * FROM %s WHERE k1 IN (?, ?) AND (k2) IN ((?), (?))", 1, 1, 1, 2), + row(1, 1, 1)); + assertRows(execute("SELECT * FROM %s WHERE k1 = ? AND (k2) IN ((?), (?))", 1, 1, 1), + row(1, 1, 1)); + } + } + + @Test + public void testWithUnsetValues() throws Throwable + { + createTable("CREATE TABLE %s (k int, i int, j int, s text, PRIMARY KEY(k,i,j))"); + createIndex("CREATE INDEX s_index ON %s (s)"); + + assertInvalidMessage("Invalid unset value for tuple field number 0", + "SELECT * from %s WHERE (i, j) = (?,?) ALLOW FILTERING", unset(), 1); + assertInvalidMessage("Invalid unset value for tuple field number 0", + "SELECT * from %s WHERE (i, j) IN ((?,?)) ALLOW FILTERING", unset(), 1); + assertInvalidMessage("Invalid unset value for tuple field number 1", + "SELECT * from %s WHERE (i, j) > (1,?) ALLOW FILTERING", unset()); + assertInvalidMessage("Invalid unset value for tuple (i,j)", + "SELECT * from %s WHERE (i, j) = ? ALLOW FILTERING", unset()); + assertInvalidMessage("Invalid unset value for tuple (j)", + "SELECT * from %s WHERE i = ? AND (j) > ? ALLOW FILTERING", 1, unset()); + assertInvalidMessage("Invalid unset value for tuple (i,j)", + "SELECT * from %s WHERE (i, j) IN (?, ?) ALLOW FILTERING", unset(), tuple(1, 1)); + assertInvalidMessage("Invalid unset value for in(i,j)", + "SELECT * from %s WHERE (i, j) IN ? ALLOW FILTERING", unset()); + } + + /** + * Check select on tuple relations, see CASSANDRA-8613 + * migrated from cql_tests.py:TestCQL.simple_tuple_query_test() + */ + @Test + public void testSimpleTupleQuery() throws Throwable + { + createTable("create table %s (a int, b int, c int, d int , e int, PRIMARY KEY (a, b, c, d, e))"); + + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 2, 0, 0, 0)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 1, 0, 0, 0)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 0, 0, 0)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 2, 2, 2)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 3, 3, 3)"); + execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)"); + + assertRows(execute("SELECT * FROM %s WHERE b=0 AND (c, d, e) > (1, 1, 1) ALLOW FILTERING"), + row(0, 0, 2, 2, 2), + row(0, 0, 3, 3, 3)); + } + }
http://git-wip-us.apache.org/repos/asf/cassandra/blob/01115f72/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java new file mode 100644 index 0000000..e788095 --- /dev/null +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java @@ -0,0 +1,504 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.cql3.validation.operations; + +import org.junit.Test; + +import org.apache.cassandra.cql3.CQLTester; + +import static org.junit.Assert.assertTrue; + +public class SelectOrderByTest extends CQLTester +{ + @Test + public void testNormalSelectionOrderSingleClustering() throws Throwable + { + for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption); + 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); + + assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0, 0, 0), + row(0, 1, 1), + row(0, 2, 2) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0), + row(0, 2, 2), + row(0, 1, 1), + row(0, 0, 0) + ); + + // order by the only column in the selection + assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2)); + + assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + + // order by a column not in the selection + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2)); + + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + } + } + + @Test + public void testFunctionSelectionOrderSingleClustering() throws Throwable + { + for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"}) + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption); + 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); + + // order by the only column in the selection + assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2)); + + assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + + // order by a column not in the selection + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2)); + + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0); + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0); + } + } + + @Test + public void testFieldSelectionOrderSingleClustering() throws Throwable + { + String type = createType("CREATE TYPE %s (a int)"); + + for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"}) + { + createTable("CREATE TABLE %s (a int, b int, c frozen<" + type + " >, PRIMARY KEY (a, b))" + descOption); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 0, 0); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 1, 1); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 2, 2); + + // order by a column not in the selection + assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2)); + + assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + + assertRows(execute("SELECT blobAsInt(intAsBlob(c.a)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0)); + dropTable("DROP TABLE %s"); + } + } + + @Test + public void testNormalSelectionOrderMultipleClustering() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))"); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5); + + assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0, 0, 0, 0), + row(0, 0, 1, 1), + row(0, 0, 2, 2), + row(0, 1, 0, 3), + row(0, 1, 1, 4), + row(0, 1, 2, 5) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0), + row(0, 1, 2, 5), + row(0, 1, 1, 4), + row(0, 1, 0, 3), + row(0, 0, 2, 2), + row(0, 0, 1, 1), + row(0, 0, 0, 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0), + row(0, 1, 2, 5), + row(0, 1, 1, 4), + row(0, 1, 0, 3), + row(0, 0, 2, 2), + row(0, 0, 1, 1), + row(0, 0, 0, 0) + ); + + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0); + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0); + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0); + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0); + assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY d ASC", 0); + + // select and order by b + assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(0), row(0), row(1), row(1), row(1)); + assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0), + row(1), row(1), row(1), row(0), row(0), row(0)); + + // select c, order by b + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2), row(0), row(1), row(2)); + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0), row(2), row(1), row(0)); + + // select c, order by b, c + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0), + row(0), row(1), row(2), row(0), row(1), row(2)); + assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0), + row(2), row(1), row(0), row(2), row(1), row(0)); + + // select d, order by b, c + assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0), + row(0), row(1), row(2), row(3), row(4), row(5)); + assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0), + row(5), row(4), row(3), row(2), row(1), row(0)); + } + + @Test + public void testFunctionSelectionOrderMultipleClustering() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))"); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5); + + assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c ASC", 0); + assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c DESC", 0); + assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0); + assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0); + assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY d ASC", 0); + + // select and order by b + assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(0), row(0), row(1), row(1), row(1)); + assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(1), row(1), row(1), row(0), row(0), row(0)); + + assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0, 0), row(0, 0), row(0, 0), row(1, 1), row(1, 1), row(1, 1)); + assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(1, 1), row(1, 1), row(1, 1), row(0, 0), row(0, 0), row(0, 0)); + + // select c, order by b + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0), + row(0), row(1), row(2), row(0), row(1), row(2)); + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0), + row(2), row(1), row(0), row(2), row(1), row(0)); + + // select c, order by b, c + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0), + row(0), row(1), row(2), row(0), row(1), row(2)); + assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0), + row(2), row(1), row(0), row(2), row(1), row(0)); + + // select d, order by b, c + assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0), + row(0), row(1), row(2), row(3), row(4), row(5)); + assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0), + row(5), row(4), row(3), row(2), row(1), row(0)); + + } + + /** + * Check ORDER BY support in SELECT statement + * migrated from cql_tests.py:TestCQL.order_by_test() + */ + @Test + public void testSimpleOrderBy() throws Throwable + { + createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c)) WITH COMPACT STORAGE"); + + for (int i = 0; i < 10; i++) + execute("INSERT INTO %s (k, c, v) VALUES (0, ?, ?)", i, i); + + assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c DESC"), + row(9), row(8), row(7), row(6), row(5), row(4), row(3), row(2), row(1), row(0)); + + createTable("CREATE TABLE %s (k int, c1 int, c2 int, v int, PRIMARY KEY (k, c1, c2)) WITH COMPACT STORAGE"); + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 2; j++) + execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, ?, ?, ?)", i, j, i * 2 + j); + + assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY c DESC"); + assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY c2 DESC"); + assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY k DESC"); + + assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c1 DESC"), + row(7), row(6), row(5), row(4), row(3), row(2), row(1), row(0)); + + assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c1"), + row(0), row(1), row(2), row(3), row(4), row(5), row(6), row(7)); + } + + /** + * More ORDER BY checks (#4160) + * migrated from cql_tests.py:TestCQL.more_order_by_test() + */ + @Test + public void testMoreOrderBy() throws Throwable + { + createTable("CREATE TABLE %s (row text, number int, string text, PRIMARY KEY(row, number)) WITH COMPACT STORAGE "); + + execute("INSERT INTO %s (row, number, string) VALUES ('row', 1, 'one')"); + execute("INSERT INTO %s (row, number, string) VALUES ('row', 2, 'two')"); + execute("INSERT INTO %s (row, number, string) VALUES ('row', 3, 'three')"); + execute("INSERT INTO %s (row, number, string) VALUES ('row', 4, 'four')"); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number < 3 ORDER BY number ASC"), + row(1), row(2)); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number >= 3 ORDER BY number ASC"), + row(3), row(4)); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number < 3 ORDER BY number DESC"), + row(2), row(1)); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number >= 3 ORDER BY number DESC"), + row(4), row(3)); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number > 3 ORDER BY number DESC"), + row(4)); + + assertRows(execute("SELECT number FROM %s WHERE row='row' AND number <= 3 ORDER BY number DESC"), + row(3), row(2), row(1)); + } + + /** + * Check we don't allow order by on row key (#4246) + * migrated from cql_tests.py:TestCQL.order_by_validation_test() + */ + @Test + public void testInvalidOrderBy() throws Throwable + { + createTable("CREATE TABLE %s( k1 int, k2 int, v int, PRIMARY KEY (k1, k2))"); + + execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 0, 0, 0); + execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, 1); + execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 2, 2, 2); + + assertInvalid("SELECT * FROM %s ORDER BY k2"); + } + + /** + * Check that order-by works with IN (#4327) + * migrated from cql_tests.py:TestCQL.order_by_with_in_test() + */ + @Test + public void testOrderByForInClause() throws Throwable + { + createTable("CREATE TABLE %s (my_id varchar, col1 int, value varchar, PRIMARY KEY (my_id, col1))"); + + execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key1', 1, 'a')"); + execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key2', 3, 'c')"); + execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key3', 2, 'b')"); + execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key4', 4, 'd')"); + + assertRows(execute("SELECT col1 FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"), + row(1), row(2), row(3)); + + assertRows(execute("SELECT col1, my_id FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"), + row(1, "key1"), row(2, "key3"), row(3, "key2")); + + assertRows(execute("SELECT my_id, col1 FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"), + row("key1", 1), row("key3", 2), row("key2", 3)); + } + + /** + * Test reversed comparators + * migrated from cql_tests.py:TestCQL.reversed_comparator_test() + */ + @Test + public void testReversedComparator() throws Throwable + { + createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c)) WITH CLUSTERING ORDER BY (c DESC);"); + + for(int i =0; i < 10; i++) + execute("INSERT INTO %s (k, c, v) VALUES (0, ?, ?)", i, i); + + assertRows(execute("SELECT c, v FROM %s WHERE k = 0 ORDER BY c ASC"), + row(0, 0), row(1, 1), row(2, 2), row(3, 3), row(4, 4), + row(5, 5), row(6, 6), row(7, 7), row(8, 8), row(9, 9)); + + assertRows(execute("SELECT c, v FROM %s WHERE k = 0 ORDER BY c DESC"), + row(9, 9), row(8, 8), row(7, 7), row(6, 6), row(5, 5), + row(4, 4), row(3, 3), row(2, 2), row(1, 1), row(0, 0)); + + createTable("CREATE TABLE %s (k int, c1 int, c2 int, v text, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)"); + + for(int i = 0; i < 10; i++) + for(int j = 0; j < 10; j++) + execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, ?, ?, ?)", i, j, String.format("%d%d", i, j)); + + assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC, c2 ASC"); + assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 DESC, c2 DESC"); + + Object[][] expectedRows = new Object[100][]; + for(int i = 0; i < 10; i++) + for(int j = 9; j >= 0; j--) + expectedRows[i * 10 + (9 - j)] = row(i, j, String.format("%d%d", i, j)); + + assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC"), + expectedRows); + + assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC, c2 DESC"), + expectedRows); + + for(int i = 9; i >= 0; i--) + for(int j = 0; j < 10; j++) + expectedRows[(9 - i) * 10 + j] = row(i, j, String.format("%d%d", i, j)); + + assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 DESC, c2 ASC"), + expectedRows); + + assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c2 DESC, c1 ASC"); + } + + /** + * Migrated from cql_tests.py:TestCQL.multiordering_test() + */ + @Test + public void testMultiordering() throws Throwable + { + createTable("CREATE TABLE %s (k text, c1 int, c2 int, PRIMARY KEY (k, c1, c2) ) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)"); + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + execute("INSERT INTO %s (k, c1, c2) VALUES ('foo', ?, ?)", i, j); + + assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo'"), + row(0, 1), row(0, 0), row(1, 1), row(1, 0)); + + assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 ASC, c2 DESC"), + row(0, 1), row(0, 0), row(1, 1), row(1, 0)); + + assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 DESC, c2 ASC"), + row(1, 0), row(1, 1), row(0, 0), row(0, 1)); + + assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c2 DESC"); + assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c2 ASC"); + assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 ASC, c2 ASC"); + } + + /** + * Migrated from cql_tests.py:TestCQL.in_with_desc_order_test() + */ + @Test + public void testSelectInStatementWithDesc() throws Throwable + { + createTable("CREATE TABLE %s (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2))"); + execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 0)"); + execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 1)"); + execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 2)"); + + assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 DESC"), + row(0, 0, 2), + row(0, 0, 0)); + } + + /** + * Test that columns don't need to be selected for ORDER BY when there is a IN (#4911), + * migrated from cql_tests.py:TestCQL.in_order_by_without_selecting_test() + */ + @Test + public void testInOrderByWithoutSelecting() throws Throwable + { + createTable("CREATE TABLE %s (k int, c1 int, c2 int, v int, PRIMARY KEY (k, c1, c2))"); + + execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 0, 0)"); + execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 1, 1)"); + execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 2, 2)"); + execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 0, 3)"); + execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 1, 4)"); + execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 2, 5)"); + + assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0)"), + row(0, 0, 0, 0), + row(0, 0, 2, 2)); + assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 ASC, c2 ASC"), + row(0, 0, 0, 0), + row(0, 0, 2, 2)); + + // check that we don 't need to select the column on which we order + assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0)"), + row(0), + row(2)); + assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 ASC"), + row(0), + row(2)); + assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 DESC"), + row(2), + row(0)); + + assertRows(execute("SELECT v FROM %s WHERE k IN (1, 0)"), + row(0), + row(1), + row(2), + row(3), + row(4), + row(5)); + + assertRows(execute("SELECT v FROM %s WHERE k IN (1, 0) ORDER BY c1 ASC"), + row(0), + row(1), + row(2), + row(3), + row(4), + row(5)); + + // we should also be able to use functions in the select clause (additional test for CASSANDRA - 8286) + Object[][] results = getRows(execute("SELECT writetime(v) FROM %s WHERE k IN (1, 0) ORDER BY c1 ASC")); + + // since we don 't know the write times, just assert that the order matches the order we expect + assertTrue(isFirstIntSorted(results)); + } + + private boolean isFirstIntSorted(Object[][] rows) + { + for (int i = 1; i < rows.length; i++) + { + Long prev = (Long)rows[i-1][0]; + Long curr = (Long)rows[i][0]; + + if (prev > curr) + return false; + } + + return true; + } +}