/* * Copyright (C) 2012-2015 DataStax Inc. * * Licensed 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 com.datastax.driver.core; import com.datastax.driver.core.utils.CassandraVersion; import com.google.common.collect.ImmutableMap; import org.testng.annotations.Test; import java.nio.ByteBuffer; import static com.datastax.driver.core.Assertions.assertThat; import static com.datastax.driver.core.ClusteringOrder.ASC; import static com.datastax.driver.core.ClusteringOrder.DESC; import static com.datastax.driver.core.DataType.*; import static org.assertj.core.api.Assertions.entry; @CCMConfig(clusterProvider = "createClusterBuilderNoDebouncing") public class TableMetadataTest extends CCMTestsSupport { @Test(groups = "short") public void should_parse_table_without_clustering_columns() { // given String cql = String.format("CREATE TABLE %s.static (\n" + " k text,\n" + " i int,\n" + " m map<text, timeuuid>,\n" + " v int,\n" + " PRIMARY KEY (k)\n" + ");", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("static"); // then assertThat(table).isNotNull().hasName("static").hasNumberOfColumns(4).isNotCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("i").isRegularColumn().hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("m").isRegularColumn().hasType(map(text(), timeuuid())); assertThat(table.getColumns().get(3)).isNotNull().hasName("v").isRegularColumn().hasType(cint()); } @Test(groups = "short") public void should_parse_table_with_clustering_columns() { // given String cql = String.format("CREATE TABLE %s.sparse (\n" + " k text,\n" + " c1 int,\n" + " c2 float,\n" + " l list<text>,\n" + " v int,\n" + " PRIMARY KEY (k, c1, c2)\n" + ") WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC);", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("sparse"); // then assertThat(table).isNotNull().hasName("sparse").hasNumberOfColumns(5).isNotCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c1").isClusteringColumn().hasClusteringOrder(ASC).hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("c2").isClusteringColumn().hasClusteringOrder(DESC).hasType(cfloat()); assertThat(table.getColumns().get(3)).isNotNull().hasName("l").isRegularColumn().hasType(list(text())); assertThat(table.getColumns().get(4)).isNotNull().hasName("v").isRegularColumn().hasType(cint()); } @Test(groups = "short") public void should_parse_counter_table() { // given String cql = String.format("CREATE TABLE %s.counters (\n" + " k text,\n" + " c counter,\n" + " PRIMARY KEY (k)\n" + ");", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("counters"); // then assertThat(table).isNotNull().hasName("counters").hasNumberOfColumns(2).isNotCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c").isRegularColumn().hasType(counter()); } @Test(groups = "short") public void should_parse_compact_static_table() { // given String cql = String.format("CREATE TABLE %s.compact_static (\n" + " k text,\n" + " i int,\n" + " t timeuuid,\n" + " v int,\n" + " PRIMARY KEY (k)\n" + ") WITH COMPACT STORAGE;", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("compact_static"); // then assertThat(table).isNotNull().hasName("compact_static").hasNumberOfColumns(4).isCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("i").isRegularColumn().hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("t").isRegularColumn().hasType(timeuuid()); assertThat(table.getColumns().get(3)).isNotNull().hasName("v").isRegularColumn().hasType(cint()); } @Test(groups = "short") public void should_parse_dense_table() { // given String cql = String.format("CREATE TABLE %s.dense (\n" + " k int,\n" + " c int,\n" + " PRIMARY KEY (k, c)\n" + " ) WITH COMPACT STORAGE;", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("dense"); // then assertThat(table).isNotNull().hasName("dense").hasNumberOfColumns(2).isCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(cint()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c").isClusteringColumn().hasType(cint()); } @Test(groups = "short") public void should_parse_compact_dynamic_table() { // given String cql = String.format("CREATE TABLE %s.compact_dynamic (\n" + " k text,\n" + " c int,\n" + " v timeuuid,\n" + " PRIMARY KEY (k, c)\n" + ") WITH COMPACT STORAGE;", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("compact_dynamic"); // then assertThat(table).isNotNull().hasName("compact_dynamic").hasNumberOfColumns(3).isCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c").isClusteringColumn().hasClusteringOrder(ASC).hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("v").isRegularColumn().hasType(timeuuid()); } @Test(groups = "short") public void should_parse_compact_table_with_multiple_clustering_columns() { // given String cql = String.format("CREATE TABLE %s.compact_composite (\n" + " k text,\n" + " c1 int,\n" + " c2 float,\n" + " c3 double,\n" + " v timeuuid,\n" + " PRIMARY KEY (k, c1, c2, c3)\n" + ") WITH COMPACT STORAGE;", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("compact_composite"); // then assertThat(table).isNotNull().hasName("compact_composite").hasNumberOfColumns(5).isCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c1").isClusteringColumn().hasClusteringOrder(ASC).hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("c2").isClusteringColumn().hasClusteringOrder(ASC).hasType(cfloat()); assertThat(table.getColumns().get(3)).isNotNull().hasName("c3").isClusteringColumn().hasClusteringOrder(ASC).hasType(cdouble()); assertThat(table.getColumns().get(4)).isNotNull().hasName("v").isRegularColumn().hasType(timeuuid()); } @Test(groups = "short") public void should_parse_table_options() { VersionNumber version = TestUtils.findHost(cluster(), 1).getCassandraVersion(); // given String cql; // Cassandra 3.0 + if (version.getMajor() > 2) { cql = String.format("CREATE TABLE %s.with_options (\n" + " k text,\n" + " c1 int,\n" + " c2 int,\n" + " i int,\n" + " PRIMARY KEY (k, c1, c2)\n" + ") WITH CLUSTERING ORDER BY (c1 DESC, c2 ASC)\n" + " AND read_repair_chance = 0.5\n" + " AND dclocal_read_repair_chance = 0.6\n" + " AND speculative_retry = '99.9PERCENTILE'\n" // replicate_on_write not supported anymore in 3.0 + " AND gc_grace_seconds = 42\n" + " AND bloom_filter_fp_chance = 0.01\n" // older caching formats not supported anymore in 3.0 + " AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 10 }\n" + " AND comment = 'My awesome table'\n" + " AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 15 }\n" + " AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor', 'chunk_length_kb' : 128 }\n" + " AND crc_check_chance = 0.5;", // available from C* 3.0 keyspace); // older versions } else { cql = String.format("CREATE TABLE %s.with_options (\n" + " k text,\n" + " c1 int,\n" + " c2 int,\n" + " i int,\n" + " PRIMARY KEY (k, c1, c2)\n" + ") WITH CLUSTERING ORDER BY (c1 DESC, c2 ASC)\n" + " AND read_repair_chance = 0.5\n" + " AND dclocal_read_repair_chance = 0.6\n" + " AND replicate_on_write = true\n" + " AND gc_grace_seconds = 42\n" + " AND bloom_filter_fp_chance = 0.01\n" + " AND caching = 'ALL'\n" + " AND comment = 'My awesome table'\n" + " AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'sstable_size_in_mb' : 15 }\n" + " AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor', 'chunk_length_kb' : 128 };", keyspace); } // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("with_options"); // then assertThat(table).isNotNull().hasName("with_options").hasNumberOfColumns(4).isNotCompactStorage(); assertThat(table.getColumns().get(0)).isNotNull().hasName("k").isPartitionKey().hasType(text()); assertThat(table.getColumns().get(1)).isNotNull().hasName("c1").isClusteringColumn().hasClusteringOrder(DESC).hasType(cint()); assertThat(table.getColumns().get(2)).isNotNull().hasName("c2").isClusteringColumn().hasClusteringOrder(ASC).hasType(cint()); assertThat(table.getColumns().get(3)).isNotNull().hasName("i").isRegularColumn().hasType(cint()); assertThat(table); // Cassandra 3.8 + if (version.getMajor() > 3 || (version.getMajor() == 3 && version.getMinor() >= 8)) { assertThat(table.getOptions().getReadRepairChance()).isEqualTo(0.5); assertThat(table.getOptions().getLocalReadRepairChance()).isEqualTo(0.6); assertThat(table.getOptions().getGcGraceInSeconds()).isEqualTo(42); assertThat(table.getOptions().getBloomFilterFalsePositiveChance()).isEqualTo(0.01); assertThat(table.getOptions().getComment()).isEqualTo("My awesome table"); assertThat(table.getOptions().getCaching()).contains(entry("keys", "ALL")); assertThat(table.getOptions().getCaching()).contains(entry("rows_per_partition", "10")); assertThat(table.getOptions().getCompaction()).contains(entry("class", "org.apache.cassandra.db.compaction.LeveledCompactionStrategy")); assertThat(table.getOptions().getCompaction()).contains(entry("sstable_size_in_mb", "15")); assertThat(table.getOptions().getCompression()).contains(entry("class", "org.apache.cassandra.io.compress.SnappyCompressor")); // sstable_compression becomes class assertThat(table.getOptions().getCompression()).contains(entry("chunk_length_in_kb", "128")); // note the "in" prefix assertThat(table.getOptions().getDefaultTimeToLive()).isEqualTo(0); assertThat(table.getOptions().getSpeculativeRetry()).isEqualTo("99.9PERCENTILE"); assertThat(table.getOptions().getIndexInterval()).isNull(); assertThat(table.getOptions().getMinIndexInterval()).isEqualTo(128); assertThat(table.getOptions().getMaxIndexInterval()).isEqualTo(2048); assertThat(table.getOptions().getReplicateOnWrite()).isTrue(); // default assertThat(table.getOptions().getCrcCheckChance()).isEqualTo(0.5); assertThat(table.getOptions().getExtensions()).isEmpty(); // default assertThat(table.asCQLQuery()) .contains("read_repair_chance = 0.5") .contains("dclocal_read_repair_chance = 0.6") .contains("gc_grace_seconds = 42") .contains("bloom_filter_fp_chance = 0.01") .contains("comment = 'My awesome table'") .contains("'keys' : 'ALL'") .contains("'rows_per_partition' : 10") .contains("'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'") .contains("'sstable_size_in_mb' : 15") .contains("'class' : 'org.apache.cassandra.io.compress.SnappyCompressor'") // sstable_compression becomes class .contains("'chunk_length_in_kb' : 128") // note the "in" prefix .contains("default_time_to_live = 0") .contains("speculative_retry = '99.9PERCENTILE'") .contains("min_index_interval = 128") .contains("max_index_interval = 2048") .contains("crc_check_chance = 0.5") .contains("cdc = false") .doesNotContain(" index_interval") .doesNotContain("replicate_on_write"); // Cassandra 3.0 + } else if (version.getMajor() > 2) { assertThat(table.getOptions().getReadRepairChance()).isEqualTo(0.5); assertThat(table.getOptions().getLocalReadRepairChance()).isEqualTo(0.6); assertThat(table.getOptions().getGcGraceInSeconds()).isEqualTo(42); assertThat(table.getOptions().getBloomFilterFalsePositiveChance()).isEqualTo(0.01); assertThat(table.getOptions().getComment()).isEqualTo("My awesome table"); assertThat(table.getOptions().getCaching()).contains(entry("keys", "ALL")); assertThat(table.getOptions().getCaching()).contains(entry("rows_per_partition", "10")); assertThat(table.getOptions().getCompaction()).contains(entry("class", "org.apache.cassandra.db.compaction.LeveledCompactionStrategy")); assertThat(table.getOptions().getCompaction()).contains(entry("sstable_size_in_mb", "15")); assertThat(table.getOptions().getCompression()).contains(entry("class", "org.apache.cassandra.io.compress.SnappyCompressor")); // sstable_compression becomes class assertThat(table.getOptions().getCompression()).contains(entry("chunk_length_in_kb", "128")); // note the "in" prefix assertThat(table.getOptions().getDefaultTimeToLive()).isEqualTo(0); assertThat(table.getOptions().getSpeculativeRetry()).isEqualTo("99.9PERCENTILE"); assertThat(table.getOptions().getIndexInterval()).isNull(); assertThat(table.getOptions().getMinIndexInterval()).isEqualTo(128); assertThat(table.getOptions().getMaxIndexInterval()).isEqualTo(2048); assertThat(table.getOptions().getReplicateOnWrite()).isTrue(); // default assertThat(table.getOptions().getCrcCheckChance()).isEqualTo(0.5); assertThat(table.getOptions().getExtensions()).isEmpty(); // default assertThat(table.asCQLQuery()) .contains("read_repair_chance = 0.5") .contains("dclocal_read_repair_chance = 0.6") .contains("gc_grace_seconds = 42") .contains("bloom_filter_fp_chance = 0.01") .contains("comment = 'My awesome table'") .contains("'keys' : 'ALL'") .contains("'rows_per_partition' : 10") .contains("'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'") .contains("'sstable_size_in_mb' : 15") .contains("'class' : 'org.apache.cassandra.io.compress.SnappyCompressor'") // sstable_compression becomes class .contains("'chunk_length_in_kb' : 128") // note the "in" prefix .contains("default_time_to_live = 0") .contains("speculative_retry = '99.9PERCENTILE'") .contains("min_index_interval = 128") .contains("max_index_interval = 2048") .contains("crc_check_chance = 0.5") .doesNotContain(" index_interval") .doesNotContain("replicate_on_write") .doesNotContain("cdc"); // 3.8+ // Cassandra 2.1 and 2.2 } else if (version.getMajor() == 2 && version.getMinor() > 0) { // With 2.1 we have different options, the caching option changes and replicate_on_write disappears assertThat(table.getOptions().getReadRepairChance()).isEqualTo(0.5); assertThat(table.getOptions().getLocalReadRepairChance()).isEqualTo(0.6); assertThat(table.getOptions().getGcGraceInSeconds()).isEqualTo(42); assertThat(table.getOptions().getBloomFilterFalsePositiveChance()).isEqualTo(0.01); assertThat(table.getOptions().getComment()).isEqualTo("My awesome table"); assertThat(table.getOptions().getCaching()).contains(entry("keys", "ALL")); assertThat(table.getOptions().getCaching()).contains(entry("rows_per_partition", "ALL")); assertThat(table.getOptions().getCompaction()).contains(entry("class", "org.apache.cassandra.db.compaction.LeveledCompactionStrategy")); assertThat(table.getOptions().getCompaction()).contains(entry("sstable_size_in_mb", "15")); assertThat(table.getOptions().getCompression()).contains(entry("sstable_compression", "org.apache.cassandra.io.compress.SnappyCompressor")); assertThat(table.getOptions().getCompression()).contains(entry("chunk_length_kb", "128")); assertThat(table.getOptions().getDefaultTimeToLive()).isEqualTo(0); assertThat(table.getOptions().getSpeculativeRetry()).isEqualTo("99.0PERCENTILE"); assertThat(table.getOptions().getIndexInterval()).isNull(); assertThat(table.getOptions().getMinIndexInterval()).isEqualTo(128); assertThat(table.getOptions().getMaxIndexInterval()).isEqualTo(2048); assertThat(table.getOptions().getReplicateOnWrite()).isTrue(); // default assertThat(table.getOptions().getExtensions()).isEmpty(); assertThat(table.asCQLQuery()) .contains("read_repair_chance = 0.5") .contains("dclocal_read_repair_chance = 0.6") .contains("gc_grace_seconds = 42") .contains("bloom_filter_fp_chance = 0.01") .contains("comment = 'My awesome table'") .contains("'keys' : 'ALL'") .contains("'rows_per_partition' : 'ALL'") .contains("'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'") .contains("'sstable_size_in_mb' : 15") .contains("'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'") .contains("'chunk_length_kb' : 128") .contains("default_time_to_live = 0") .contains("speculative_retry = '99.0PERCENTILE'") .contains("min_index_interval = 128") .contains("max_index_interval = 2048") .doesNotContain(" index_interval") .doesNotContain("replicate_on_write") .doesNotContain("cdc"); // Cassandra 2.0 } else if (version.getMajor() == 2 && version.getMinor() == 0) { assertThat(table.getOptions().getReadRepairChance()).isEqualTo(0.5); assertThat(table.getOptions().getLocalReadRepairChance()).isEqualTo(0.6); assertThat(table.getOptions().getGcGraceInSeconds()).isEqualTo(42); assertThat(table.getOptions().getBloomFilterFalsePositiveChance()).isEqualTo(0.01); assertThat(table.getOptions().getComment()).isEqualTo("My awesome table"); assertThat(table.getOptions().getCaching()).contains(entry("keys", "ALL")); assertThat(table.getOptions().getCaching()).doesNotContain(entry("rows_per_partition", "ALL")); // 2.1 + assertThat(table.getOptions().getCompaction()).contains(entry("class", "org.apache.cassandra.db.compaction.LeveledCompactionStrategy")); assertThat(table.getOptions().getCompaction()).contains(entry("sstable_size_in_mb", "15")); assertThat(table.getOptions().getCompression()).contains(entry("sstable_compression", "org.apache.cassandra.io.compress.SnappyCompressor")); assertThat(table.getOptions().getCompression()).contains(entry("chunk_length_kb", "128")); assertThat(table.getOptions().getDefaultTimeToLive()).isEqualTo(0); assertThat(table.getOptions().getSpeculativeRetry()).isEqualTo("99.0PERCENTILE"); // default assertThat(table.getOptions().getIndexInterval()).isEqualTo(128); assertThat(table.getOptions().getMinIndexInterval()).isNull(); assertThat(table.getOptions().getMaxIndexInterval()).isNull(); assertThat(table.getOptions().getReplicateOnWrite()).isTrue(); // explicitly set assertThat(table.getOptions().getExtensions()).isEmpty(); assertThat(table.asCQLQuery()) .contains("read_repair_chance = 0.5") .contains("dclocal_read_repair_chance = 0.6") .contains("gc_grace_seconds = 42") .contains("bloom_filter_fp_chance = 0.01") .contains("comment = 'My awesome table'") .contains("caching = 'ALL'") .contains("'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'") .contains("'sstable_size_in_mb' : 15") .contains("'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'") .contains("'chunk_length_kb' : 128") .contains("replicate_on_write = true") .contains("index_interval = 128") .contains("speculative_retry = '99.0PERCENTILE'") .contains("default_time_to_live = 0") .doesNotContain("min_index_interval") // 2.1 + .doesNotContain("max_index_interval") // 2.1 + .doesNotContain("cdc"); // Cassandra 1.2 } else { assertThat(table.getOptions().getReadRepairChance()).isEqualTo(0.5); assertThat(table.getOptions().getLocalReadRepairChance()).isEqualTo(0.6); assertThat(table.getOptions().getGcGraceInSeconds()).isEqualTo(42); assertThat(table.getOptions().getBloomFilterFalsePositiveChance()).isEqualTo(0.01); assertThat(table.getOptions().getComment()).isEqualTo("My awesome table"); assertThat(table.getOptions().getCaching()).contains(entry("keys", "ALL")); assertThat(table.getOptions().getCaching()).doesNotContain(entry("rows_per_partition", "ALL")); // 2.1 + assertThat(table.getOptions().getCompaction()).contains(entry("class", "org.apache.cassandra.db.compaction.LeveledCompactionStrategy")); assertThat(table.getOptions().getCompaction()).contains(entry("sstable_size_in_mb", "15")); assertThat(table.getOptions().getCompression()).contains(entry("sstable_compression", "org.apache.cassandra.io.compress.SnappyCompressor")); assertThat(table.getOptions().getCompression()).contains(entry("chunk_length_kb", "128")); assertThat(table.getOptions().getDefaultTimeToLive()).isEqualTo(0); // default assertThat(table.getOptions().getSpeculativeRetry()).isEqualTo("NONE"); // default assertThat(table.getOptions().getIndexInterval()).isNull(); assertThat(table.getOptions().getMinIndexInterval()).isNull(); assertThat(table.getOptions().getMaxIndexInterval()).isNull(); assertThat(table.getOptions().getReplicateOnWrite()).isTrue(); // explicitly set assertThat(table.getOptions().getExtensions()).isEmpty(); assertThat(table.asCQLQuery()) .contains("read_repair_chance = 0.5") .contains("dclocal_read_repair_chance = 0.6") .contains("gc_grace_seconds = 42") .contains("bloom_filter_fp_chance = 0.01") .contains("comment = 'My awesome table'") .contains("caching = 'ALL'") .contains("'class' : 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'") .contains("'sstable_size_in_mb' : 15") .contains("'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'") .contains("'chunk_length_kb' : 128") .contains("replicate_on_write = true") .doesNotContain("index_interval") // 2.0 .doesNotContain("min_index_interval") // 2.1 + .doesNotContain("max_index_interval") // 2.1 + .doesNotContain("speculative_retry") // 2.0 + .doesNotContain("default_time_to_live") // 2.0 + .doesNotContain("cdc"); } } /** * Validates that metadata is appropriately parsed when using the new compression options format introduced * in 3.0.0-alpha1. Since compression options are parsed as a String map, this should behave exactly as * the old style compression options used in {@link #should_parse_table_options}. * * @jira_ticket CASSANDRA-9424 */ @Test(groups = "short") @CassandraVersion("3.0") public void should_parse_new_compression_options() { // given String cql = String.format("CREATE TABLE %s.new_compression_options (\n" + " k text,\n" + " c1 int,\n" + " c2 int,\n" + " i int,\n" + " PRIMARY KEY (k, c1, c2)\n" + ") WITH CLUSTERING ORDER BY (c1 DESC, c2 ASC)\n" + " AND compression = { 'class' : 'DeflateCompressor', 'chunk_length_in_kb' : 128 };", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("new_compression_options"); // then assertThat(table.getOptions().getCompression()) .contains(entry("class", "org.apache.cassandra.io.compress.DeflateCompressor")) .contains(entry("chunk_length_in_kb", "128")); } @Test(groups = "short") public void should_escape_single_quote_table_comment() { // given String cql = String.format("CREATE TABLE %s.single_quote (\n" + " c1 int PRIMARY KEY\n" + ") WITH comment = 'comment with single quote '' should work'", keyspace); // when session().execute(cql); TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("single_quote"); // then assertThat(table.getOptions().getComment()).isEqualTo("comment with single quote ' should work"); assertThat(table.asCQLQuery()).contains("comment = 'comment with single quote '' should work'"); } @Test(groups = "short") public void should_not_mix_indexes_from_different_tables() { String[] statements = { "CREATE TABLE test_ab (a int PRIMARY KEY, b int);", "CREATE INDEX test_b on test_ab (b);", "CREATE TABLE test_cd (c int PRIMARY KEY, d int);", "CREATE INDEX test_d on test_cd (d);", }; for (String statement : statements) session().execute(statement); TableMetadata table_ab = cluster().getMetadata().getKeyspace(keyspace).getTable("test_ab"); TableMetadata table_cd = cluster().getMetadata().getKeyspace(keyspace).getTable("test_cd"); assertThat(table_ab.getIndexes().size()).isEqualTo(1); assertThat(table_ab.getIndexes()).extracting("name").containsOnly("test_b"); assertThat(table_cd.getIndexes().size()).isEqualTo(1); assertThat(table_cd.getIndexes()).extracting("name").containsOnly("test_d"); } /** * Validates that the 'extensions' option is properly parsed when set on a table. * This value is currently not modifiable via CQL so we fake out a table containing * populated extensions by updating the extensions column in system_schema.tables * and forcing a schema refresh on it. * * @jira_ticket JAVA-938, CASSANDRA-9426 * @test_category metadata */ @Test(groups = "short") @CassandraVersion("3.0") public void should_parse_extensions_from_table_options() throws Exception { // given // create a simple table and retrieve it's metadata from system_schema.tables. String cql = String.format("CREATE TABLE %s.table_with_extensions (\n" + " k text,\n" + " c int,\n" + " v timeuuid,\n" + " PRIMARY KEY (k, c)\n" + ");", keyspace); session().execute(cql); // Manually change column value in system_schema.tables and force a schema refresh on that table. ImmutableMap<String, ByteBuffer> extensions = ImmutableMap.of("Hello", ByteBuffer.wrap("World".getBytes("UTF-8"))); session().execute("update system_schema.tables set extensions=? where keyspace_name=? and table_name=?", extensions, keyspace, "table_with_extensions"); cluster().manager.controlConnection.refreshSchema(SchemaElement.TABLE, keyspace, "table_with_extensions", null); // when retrieving the table's metadata. TableMetadata table = cluster().getMetadata().getKeyspace(keyspace).getTable("table_with_extensions"); // then the table's options should contain populated extensions. assertThat(table.getOptions().getExtensions()).isEqualTo(extensions); } /** * Validates that a table with case-sensitive column names and column names * consisting of (quoted) reserved keywords is correctly parsed * and that the generated CQL is valid. * * @jira_ticket JAVA-1064 * @test_category metadata */ @Test(groups = "short") public void should_parse_table_with_case_sensitive_column_names_and_reserved_keywords() throws Exception { // given String c1 = Metadata.quote("quotes go \"\" here \"\" "); String c2 = Metadata.quote("\\x00\\x25"); String c3 = Metadata.quote("columnfamily"); String c4 = Metadata.quote("select"); String c5 = Metadata.quote("who''s there'? "); String c6 = Metadata.quote("faux )"); String c7 = Metadata.quote("COMPACT STORAGE"); // single partition key String cql1 = String.format("CREATE TABLE %s.\"MyTable1\" (" + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "PRIMARY KEY (%s, %s, %s, %s, %s, %s)" + ")", keyspace, c1, c2, c3, c4, c5, c6, c7, c1, c2, c3, c4, c5, c6); // composite partition key String cql2 = String.format("CREATE TABLE %s.\"MyTable2\" (" + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "%s text, " + "PRIMARY KEY ((%s, %s), %s, %s, %s, %s)" + ")", keyspace, c1, c2, c3, c4, c5, c6, c7, c1, c2, c3, c4, c5, c6); // when execute(cql1, cql2); TableMetadata table1 = cluster().getMetadata().getKeyspace(keyspace).getTable("\"MyTable1\""); TableMetadata table2 = cluster().getMetadata().getKeyspace(keyspace).getTable("\"MyTable2\""); // then assertThat(table1) .hasColumn(c1) .hasColumn(c2) .hasColumn(c3) .hasColumn(c4) .hasColumn(c5) .hasColumn(c6) .hasColumn(c7); assertThat(table1.asCQLQuery()).startsWith(cql1); assertThat(table2) .hasColumn(c1) .hasColumn(c2) .hasColumn(c3) .hasColumn(c4) .hasColumn(c5) .hasColumn(c6) .hasColumn(c7); assertThat(table2.asCQLQuery()).startsWith(cql2); execute( "DROP TABLE \"MyTable1\"", "DROP TABLE \"MyTable2\"", table1.asCQLQuery(), table2.asCQLQuery() ); } }