| /* |
| * 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.entities; |
| |
| import java.util.Arrays; |
| |
| import org.junit.Test; |
| |
| import org.apache.cassandra.cql3.CQLTester; |
| |
| import static junit.framework.Assert.assertNull; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| public class StaticColumnsTest extends CQLTester |
| { |
| |
| /** |
| * Migrated from cql_tests.py:TestCQL.static_columns_test() |
| */ |
| @Test |
| public void testStaticColumns() throws Throwable |
| { |
| createTable("CREATE TABLE %s ( k int, p int, s int static, v int, PRIMARY KEY (k, p))"); |
| |
| execute("INSERT INTO %s(k, s) VALUES (0, 42)"); |
| |
| assertRows(execute("SELECT * FROM %s"), row(0, null, 42, null)); |
| |
| // Check that writetime works (//7081) -- we can't predict the exact value easily so |
| // we just check that it's non zero |
| Object[][] row = getRows(execute("SELECT s, writetime(s) FROM %s WHERE k=0")); |
| assertEquals(42, row[0][0]); |
| assertTrue((Long)row[0][1] > 0); |
| |
| execute("INSERT INTO %s (k, p, s, v) VALUES (0, 0, 12, 0)"); |
| execute("INSERT INTO %s (k, p, s, v) VALUES (0, 1, 24, 1)"); |
| |
| // Check the static columns in indeed "static" |
| assertRows(execute("SELECT * FROM %s"), row(0, 0, 24, 0), row(0, 1, 24, 1)); |
| |
| // Check we do correctly get the static column value with a SELECT *, even |
| // if we're only slicing part of the partition |
| assertRows(execute("SELECT * FROM %s WHERE k=0 AND p=0"), row(0, 0, 24, 0)); |
| assertRows(execute("SELECT * FROM %s WHERE k=0 AND p=1"), row(0, 1, 24, 1)); |
| |
| // Test for IN on the clustering key (//6769) |
| assertRows(execute("SELECT * FROM %s WHERE k=0 AND p IN (0, 1)"), row(0, 0, 24, 0), row(0, 1, 24, 1)); |
| |
| // Check things still work if we don't select the static column. We also want |
| // this to not request the static columns internally at all, though that part |
| // require debugging to assert |
| assertRows(execute("SELECT p, v FROM %s WHERE k=0 AND p=1"), row(1, 1)); |
| |
| // Check selecting only a static column with distinct only yield one value |
| // (as we only query the static columns) |
| assertRows(execute("SELECT DISTINCT s FROM %s WHERE k=0"), row(24)); |
| // But without DISTINCT, we still get one result per row |
| assertRows(execute("SELECT s FROM %s WHERE k=0"),row(24),row(24)); |
| // but that querying other columns does correctly yield the full partition |
| assertRows(execute("SELECT s, v FROM %s WHERE k=0"),row(24, 0),row(24, 1)); |
| assertRows(execute("SELECT s, v FROM %s WHERE k=0 AND p=1"),row(24, 1)); |
| assertRows(execute("SELECT p, s FROM %s WHERE k=0 AND p=1"), row(1, 24)); |
| assertRows(execute("SELECT k, p, s FROM %s WHERE k=0 AND p=1"),row(0, 1, 24)); |
| |
| // Check that deleting a row don't implicitely deletes statics |
| execute("DELETE FROM %s WHERE k=0 AND p=0"); |
| assertRows(execute("SELECT * FROM %s"),row(0, 1, 24, 1)); |
| |
| // But that explicitely deleting the static column does remove it |
| execute("DELETE s FROM %s WHERE k=0"); |
| assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 1)); |
| |
| // Check we can add a static column ... |
| execute("ALTER TABLE %s ADD s2 int static"); |
| assertRows(execute("SELECT * FROM %s"), row(0, 1, null, null, 1)); |
| execute("INSERT INTO %s (k, p, s2, v) VALUES(0, 2, 42, 2)"); |
| assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 42, 1), row(0, 2, null, 42, 2)); |
| // ... and that we can drop it |
| execute("ALTER TABLE %s DROP s2"); |
| assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 1), row(0, 2, null, 2)); |
| } |
| |
| /** |
| * Migrated from cql_tests.py:TestCQL.static_columns_with_2i_test() |
| */ |
| @Test |
| public void testStaticColumnsWithSecondaryIndex() throws Throwable |
| { |
| createTable(" CREATE TABLE %s (k int, p int, s int static, v int, PRIMARY KEY (k, p) ) "); |
| |
| createIndex("CREATE INDEX ON %s (v)"); |
| |
| execute("INSERT INTO %s (k, p, s, v) VALUES (0, 0, 42, 1)"); |
| execute("INSERT INTO %s (k, p, v) VALUES (0, 1, 1)"); |
| execute("INSERT INTO %s (k, p, v) VALUES (0, 2, 2)"); |
| |
| assertRows(execute("SELECT * FROM %s WHERE v = 1"), row(0, 0, 42, 1), row(0, 1, 42, 1)); |
| assertRows(execute("SELECT p, s FROM %s WHERE v = 1"), row(0, 42), row(1, 42)); |
| assertRows(execute("SELECT p FROM %s WHERE v = 1"), row(0), row(1)); |
| // We don't support that |
| assertInvalid("SELECT s FROM %s WHERE v = 1"); |
| } |
| |
| /** |
| * Migrated from cql_tests.py:TestCQL.static_columns_with_distinct_test() |
| */ |
| @Test |
| public void testStaticColumnsWithDistinct() throws Throwable |
| { |
| createTable("CREATE TABLE %s( k int, p int, s int static, PRIMARY KEY (k, p) ) "); |
| |
| execute("INSERT INTO %s (k, p) VALUES (1, 1)"); |
| execute("INSERT INTO %s (k, p) VALUES (1, 2)"); |
| |
| assertRows(execute("SELECT k, s FROM %s"), row(1, null), row(1, null)); |
| assertRows(execute("SELECT DISTINCT k, s FROM %s"), row(1, null)); |
| |
| Object[][] rows = getRows(execute("SELECT DISTINCT s FROM %s WHERE k=1")); |
| assertNull(rows[0][0]); |
| |
| assertEmpty(execute("SELECT DISTINCT s FROM %s WHERE k=2")); |
| |
| execute("INSERT INTO %s (k, p, s) VALUES (2, 1, 3)"); |
| execute("INSERT INTO %s (k, p) VALUES (2, 2)"); |
| |
| assertRows(execute("SELECT k, s FROM %s"), row(1, null), row(1, null), row(2, 3), row(2, 3)); |
| assertRows(execute("SELECT DISTINCT k, s FROM %s"), row(1, null), row(2, 3)); |
| rows = getRows(execute("SELECT DISTINCT s FROM %s WHERE k=1")); |
| assertNull(rows[0][0]); |
| assertRows(execute("SELECT DISTINCT s FROM %s WHERE k=2"), row(3)); |
| |
| assertInvalid("SELECT DISTINCT s FROM %s"); |
| |
| // paging to test for CASSANDRA-8108 |
| execute("TRUNCATE %s"); |
| for (int i = 0; i < 10; i++) |
| for (int j = 0; j < 10; j++) |
| execute("INSERT INTO %s (k, p, s) VALUES (?, ?, ?)", i, j, i); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s FROM %s")); |
| checkDistinctRows(rows, true, 0, 10, 0, 10); |
| |
| String keys = "0, 1, 2, 3, 4, 5, 6, 7, 8, 9"; |
| rows = getRows(execute("SELECT DISTINCT k, s FROM %s WHERE k IN (" + keys + ")")); |
| checkDistinctRows(rows, false, 0, 10, 0, 10); |
| |
| // additional testing for CASSANRA-8087 |
| createTable("CREATE TABLE %s( k int, c1 int, c2 int, s1 int static, s2 int static, PRIMARY KEY (k, c1, c2))"); |
| |
| for (int i = 0; i < 10; i++) |
| for (int j = 0; j < 5; j++) |
| for (int k = 0; k < 5; k++) |
| execute("INSERT INTO %s (k, c1, c2, s1, s2) VALUES (?, ?, ?, ?, ?)", i, j, k, i, i + 1); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s")); |
| checkDistinctRows(rows, true, 0, 10, 0, 10); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s2 FROM %s")); |
| checkDistinctRows(rows, true, 0, 10, 1, 11); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s LIMIT 10")); |
| checkDistinctRows(rows, true, 0, 10, 0, 10); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s WHERE k IN (" + keys + ")")); |
| checkDistinctRows(rows, false, 0, 10, 0, 10); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s2 FROM %s WHERE k IN (" + keys + ")")); |
| checkDistinctRows(rows, false, 0, 10, 1, 11); |
| |
| rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s WHERE k IN (" + keys + ")")); |
| checkDistinctRows(rows, true, 0, 10, 0, 10); |
| } |
| |
| void checkDistinctRows(Object[][] rows, boolean sort, int... ranges) |
| { |
| assertTrue(ranges.length % 2 == 0); |
| |
| int numdim = ranges.length / 2; |
| int[] from = new int[numdim]; |
| int[] to = new int[numdim]; |
| |
| for (int i = 0, j = 0; i < ranges.length && j < numdim; i+= 2, j++) |
| { |
| from[j] = ranges[i]; |
| to[j] = ranges[i+1]; |
| } |
| |
| //sort the rows |
| for (int i = 0; i < numdim; i++) |
| { |
| int[] vals = new int[rows.length]; |
| for (int j = 0; j < rows.length; j++) |
| vals[j] = (Integer)rows[j][i]; |
| |
| if (sort) |
| Arrays.sort(vals); |
| |
| for (int j = from[i]; j < to[i]; j++) |
| assertEquals(j, vals[j - from[i]]); |
| } |
| } |
| |
| /** |
| * Test LIMIT when static columns are present (#6956), |
| * migrated from cql_tests.py:TestCQL.static_with_limit_test() |
| */ |
| @Test |
| public void testStaticColumnsWithLimit() throws Throwable |
| { |
| createTable(" CREATE TABLE %s (k int, s int static, v int, PRIMARY KEY (k, v))"); |
| |
| execute("INSERT INTO %s (k, s) VALUES(0, 42)"); |
| for (int i = 0; i < 4; i++) |
| execute("INSERT INTO %s(k, v) VALUES(0, ?)", i); |
| |
| assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 1"), |
| row(0, 0, 42)); |
| assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 2"), |
| row(0, 0, 42), |
| row(0, 1, 42)); |
| assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 3"), |
| row(0, 0, 42), |
| row(0, 1, 42), |
| row(0, 2, 42)); |
| } |
| |
| /** |
| * Test for bug of #7455, |
| * migrated from cql_tests.py:TestCQL.static_with_empty_clustering_test() |
| */ |
| @Test |
| public void testStaticColumnsWithEmptyClustering() throws Throwable |
| { |
| createTable("CREATE TABLE %s (pkey text, ckey text, value text, static_value text static, PRIMARY KEY(pkey, ckey))"); |
| |
| execute("INSERT INTO %s (pkey, static_value) VALUES ('partition1', 'static value')"); |
| execute("INSERT INTO %s (pkey, ckey, value) VALUES('partition1', '', 'value')"); |
| |
| assertRows(execute("SELECT * FROM %s"), |
| row("partition1", "", "static value", "value")); |
| } |
| |
| /** |
| * Migrated from cql_tests.py:TestCQL.alter_clustering_and_static_test() |
| */ |
| @Test |
| public void testAlterClusteringAndStatic() throws Throwable |
| { |
| createTable("CREATE TABLE %s (bar int, PRIMARY KEY (bar))"); |
| |
| // We shouldn 't allow static when there is not clustering columns |
| assertInvalid("ALTER TABLE %s ADD bar2 text static"); |
| } |
| |
| /** |
| * Ensure that deleting and compacting a static row that should be purged doesn't throw. |
| * This is a test for #11988. |
| */ |
| @Test |
| public void testStaticColumnPurging() throws Throwable |
| { |
| createTable("CREATE TABLE %s (pkey text, ckey text, value text, static_value text static, PRIMARY KEY(pkey, ckey)) WITH gc_grace_seconds = 0"); |
| |
| execute("INSERT INTO %s (pkey, ckey, static_value, value) VALUES (?, ?, ?, ?)", "k1", "c1", "s1", "v1"); |
| |
| flush(); |
| |
| execute("DELETE static_value FROM %s WHERE pkey = ?", "k1"); |
| |
| flush(); |
| |
| compact(); |
| |
| assertRows(execute("SELECT * FROM %s"), row("k1", "c1", null, "v1")); |
| } |
| } |