diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index 9e79d3525b..a9d0ddadbc 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -1975,6 +1975,15 @@ drop_compact_storage_enabled: false # if zero_ttl_on_twcs_enabled is set to false, this property is irrelevant as such statements will fail. #zero_ttl_on_twcs_warned: true +# The default secondary index implementation when CREATE INDEX does not specify one via USING. +# ex. "legacy_local_table" - (default) legacy secondary index, implemented as a hidden table +# ex. "sai" - "storage-attched" index, implemented via optimized SSTable/Memtable-attached indexes +#default_secondary_index: legacy_local_table + +# Whether a default secondary index implementation is allowed. If this is "false", CREATE INDEX must +# specify an index implementation via USING. +#default_secondary_index_enabled: true + # Startup Checks are executed as part of Cassandra startup process, not all of them # are configurable (so you can disable them) but these which are enumerated bellow. # Uncomment the startup checks and configure them appropriately to cover your needs. diff --git a/doc/cql3/CQL.textile b/doc/cql3/CQL.textile index 0073ff7ed3..4f6a4d7338 100644 --- a/doc/cql3/CQL.textile +++ b/doc/cql3/CQL.textile @@ -513,7 +513,8 @@ __Sample:__ bc(sample). CREATE INDEX userIndex ON NerdMovies (user); CREATE INDEX ON Mutants (abilityId); -CREATE INDEX ON users (keys(favs)); +CREATE INDEX ON users (KEYS(favs)); +CREATE INDEX ON users (age) USING 'sai'; CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass'; CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass' WITH OPTIONS = {'storage': '/mnt/ssd/indexes/'}; @@ -521,6 +522,15 @@ The @CREATE INDEX@ statement is used to create a new (automatic) secondary index Attempting to create an already existing index will return an error unless the @IF NOT EXISTS@ option is used. If it is used, the statement will be a no-op if the index already exists. +h4(#usingIndex). Index Types + +The @USING@ keyword optionally specifies an index type. There are two built-in types: + +* legacy_local_table - (default) legacy secondary index, implemented as a hidden local table +* sai - "storage-attched" index, implemented via optimized SSTable/Memtable-attached indexes + +To create a custom index, a fully qualified class name must be specified. + h4(#keysIndex). Indexes on Map Keys When creating an index on a "map column":#map, you may index either the keys or the values. If the column identifier is placed within the @keys()@ function, the index will be on the map keys, allowing you to use @CONTAINS KEY@ in @WHERE@ clauses. Otherwise, the index will be on the map values. diff --git a/doc/modules/cassandra/examples/BNF/create_index_statement.bnf b/doc/modules/cassandra/examples/BNF/create_index_statement.bnf index 6e76947243..322799de1c 100644 --- a/doc/modules/cassandra/examples/BNF/create_index_statement.bnf +++ b/doc/modules/cassandra/examples/BNF/create_index_statement.bnf @@ -1,5 +1,6 @@ create_index_statement::= CREATE [ CUSTOM ] INDEX [ IF NOT EXISTS ] [ index_name ] ON table_name '(' index_identifier ')' - [ USING string [ WITH OPTIONS = map_literal ] ] + [ USING index_type [ WITH OPTIONS = map_literal ] ] index_identifier::= column_name | ( KEYS | VALUES | ENTRIES | FULL ) '(' column_name ')' +index_type::= 'sai' | 'legacy_local_table' | fully_qualified_class_name \ No newline at end of file diff --git a/doc/modules/cassandra/examples/CQL/create_index.cql b/doc/modules/cassandra/examples/CQL/create_index.cql index f84452aa1d..38bdfdff02 100644 --- a/doc/modules/cassandra/examples/CQL/create_index.cql +++ b/doc/modules/cassandra/examples/CQL/create_index.cql @@ -1,6 +1,7 @@ CREATE INDEX userIndex ON NerdMovies (user); CREATE INDEX ON Mutants (abilityId); -CREATE INDEX ON users (keys(favs)); +CREATE INDEX ON users (KEYS(favs)); +CREATE INDEX ON users (age) USING 'sai'; CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass'; CREATE CUSTOM INDEX ON users (email) diff --git a/doc/modules/cassandra/pages/developing/cql/cql_singlefile.adoc b/doc/modules/cassandra/pages/developing/cql/cql_singlefile.adoc index b6a0966cbf..64e71b051c 100644 --- a/doc/modules/cassandra/pages/developing/cql/cql_singlefile.adoc +++ b/doc/modules/cassandra/pages/developing/cql/cql_singlefile.adoc @@ -853,6 +853,11 @@ The `TRUNCATE` statement permanently removes all data from a table. [[createIndexStmt]] ==== CREATE INDEX +The `CREATE INDEX` statement is used to create a new +secondary index for a given (existing) column in a given table. A name +for the index itself can be specified before the `ON` keyword, if +desired. + _Syntax:_ bc(syntax).. + @@ -869,20 +874,26 @@ bc(sample). + CREATE INDEX userIndex ON NerdMovies (user); + CREATE INDEX ON Mutants (abilityId); + CREATE INDEX ON users (keys(favs)); + +CREATE INDEX ON users (age) USING 'sai'; + CREATE CUSTOM INDEX ON users (email) USING `path.to.the.IndexClass'; + CREATE CUSTOM INDEX ON users (email) USING `path.to.the.IndexClass' WITH OPTIONS = \{’storage’: `/mnt/ssd/indexes/'}; -The `CREATE INDEX` statement is used to create a new (automatic) -secondary index for a given (existing) column in a given table. A name -for the index itself can be specified before the `ON` keyword, if -desired. If data already exists for the column, it will be indexed +If data already exists for the column, it will be indexed asynchronously. After the index is created, new data for the column is -indexed automatically at insertion time. +indexed automatically at insertion time. Attempting to create an already +existing index will return an error unless the `IF NOT EXISTS` option is used. +If it is used, the statement will be a no-op if the index already exists. -Attempting to create an already existing index will return an error -unless the `IF NOT EXISTS` option is used. If it is used, the statement -will be a no-op if the index already exists. +[[indexTypes]] +===== Index Types + +The `USING` keyword optionally specifies an index type. There are two built-in types: + +- legacy_local_table - (default) legacy secondary index, implemented as a hidden local table +- sai - "storage-attched" index, implemented via optimized SSTable/Memtable-attached indexes + +To create a custom index, a fully qualified class name must be specified. [[keysIndex]] ===== Indexes on Map Keys diff --git a/doc/modules/cassandra/pages/developing/cql/indexes.adoc b/doc/modules/cassandra/pages/developing/cql/indexes.adoc index 32b45b59f5..20daf072f8 100644 --- a/doc/modules/cassandra/pages/developing/cql/indexes.adoc +++ b/doc/modules/cassandra/pages/developing/cql/indexes.adoc @@ -12,30 +12,37 @@ include::example$BNF/index_name.bnf[] [[create-index-statement]] == CREATE INDEX -Creating a secondary index on a table uses the `CREATE INDEX` statement: +The `CREATE INDEX` statement is used to create a new +secondary index for a given (existing) column in a given table. A name +for the index itself can be specified before the `ON` keyword, if +desired. [source,bnf] ---- include::example$BNF/create_index_statement.bnf[] ---- -For instance: +If data already exists for the column, it will be indexed +asynchronously. After the index is created, new data for the column is +indexed automatically at insertion time. Attempting to create an already +existing index will return an error unless the `IF NOT EXISTS` option is used. +If it is used, the statement will be a no-op if the index already exists. + +*Examples*: [source,cql] ---- include::example$CQL/create_index.cql[] ---- -The `CREATE INDEX` statement is used to create a new (automatic) -secondary index for a given (existing) column in a given table. A name -for the index itself can be specified before the `ON` keyword, if -desired. If data already exists for the column, it will be indexed -asynchronously. After the index is created, new data for the column is -indexed automatically at insertion time. +=== Index Types -Attempting to create an already existing index will return an error -unless the `IF NOT EXISTS` option is used. If it is used, the statement -will be a no-op if the index already exists. +The `USING` keyword optionally specifies an index type. There are two built-in types: + +- legacy_local_table - (default) legacy secondary index, implemented as a hidden local table +- sai - "storage-attched" index, implemented via optimized SSTable/Memtable-attached indexes + +To create a custom index, a fully qualified class name must be specified. === Indexes on Map Keys diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index 47b197cf9b..5b3bc81887 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.audit.AuditLogOptions; import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.fql.FullQueryLoggerOptions; +import org.apache.cassandra.index.internal.CassandraIndex; import org.apache.cassandra.io.sstable.format.big.BigFormat; import org.apache.cassandra.service.StartupChecks.StartupCheckType; import org.apache.cassandra.utils.StorageCompatibilityMode; @@ -49,7 +50,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.SKIP_PAXOS /** * A class that contains configuration properties for the cassandra node it runs within. - * + *
* Properties declared as volatile can be mutated via JMX.
*/
public class Config
@@ -864,6 +865,10 @@ public class Config
public volatile boolean drop_truncate_table_enabled = true;
public volatile boolean drop_keyspace_enabled = true;
public volatile boolean secondary_indexes_enabled = true;
+
+ public volatile String default_secondary_index = CassandraIndex.NAME;
+ public volatile boolean default_secondary_index_enabled = true;
+
public volatile boolean uncompressed_tables_enabled = true;
public volatile boolean compact_tables_enabled = true;
public volatile boolean read_before_write_list_operations_enabled = true;
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 043cb9b5bc..f288baefbf 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -3765,6 +3765,26 @@ public class DatabaseDescriptor
conf.sasi_indexes_enabled = enableSASIIndexes;
}
+ public static String getDefaultSecondaryIndex()
+ {
+ return conf.default_secondary_index;
+ }
+
+ public static void setDefaultSecondaryIndex(String name)
+ {
+ conf.default_secondary_index = name;
+ }
+
+ public static boolean getDefaultSecondaryIndexEnabled()
+ {
+ return conf.default_secondary_index_enabled;
+ }
+
+ public static void setDefaultSecondaryIndexEnabled(boolean enabled)
+ {
+ conf.default_secondary_index_enabled = enabled;
+ }
+
public static boolean isTransientReplicationEnabled()
{
return conf.transient_replication_enabled;
diff --git a/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java
index 73b66b738d..b53e066f90 100644
--- a/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java
@@ -35,6 +35,7 @@ import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.guardrails.Guardrails;
import org.apache.cassandra.db.marshal.MapType;
import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.index.internal.CassandraIndex;
import org.apache.cassandra.index.sasi.SASIIndex;
import org.apache.cassandra.schema.*;
import org.apache.cassandra.schema.Keyspaces.KeyspacesDiff;
@@ -77,6 +78,7 @@ public final class CreateIndexStatement extends AlterSchemaStatement
public static final String INDEX_DUPLICATE_OF_EXISTING = "Index %s is a duplicate of existing index %s";
public static final String KEYSPACE_DOES_NOT_MATCH_TABLE = "Keyspace name '%s' doesn't match table name '%s'";
public static final String KEYSPACE_DOES_NOT_MATCH_INDEX = "Keyspace name '%s' doesn't match index name '%s'";
+ public static final String MUST_SPECIFY_INDEX_IMPLEMENTATION = "Must specify index implementation via USING";
private final String indexName;
private final String tableName;
@@ -316,6 +318,27 @@ public final class CreateIndexStatement extends AlterSchemaStatement
if (indexName.hasKeyspace() && !keyspaceName.equals(indexName.getKeyspace()))
throw ire(KEYSPACE_DOES_NOT_MATCH_INDEX, keyspaceName, tableName);
+
+ // Set the configured default 2i implementation if one isn't specified with USING:
+ if (attrs.customClass == null)
+ {
+ if (DatabaseDescriptor.getDefaultSecondaryIndexEnabled())
+ attrs.customClass = DatabaseDescriptor.getDefaultSecondaryIndex();
+ else
+ // However, operators may require an implementation be specified
+ throw ire(MUST_SPECIFY_INDEX_IMPLEMENTATION);
+ }
+
+ // If we explicitly specify the index type "legacy_local_table", we can just clear the custom class, and the
+ // non-custom 2i creation process will begin. Otherwise, if an index type has been specified with
+ // USING, make sure the appropriate custom index is created.
+ if (attrs.customClass != null)
+ {
+ if (!attrs.isCustom && attrs.customClass.equalsIgnoreCase(CassandraIndex.NAME))
+ attrs.customClass = null;
+ else
+ attrs.isCustom = true;
+ }
return new CreateIndexStatement(keyspaceName, tableName.getName(), indexName.getName(), rawIndexTargets, attrs, ifNotExists);
}
diff --git a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
index 5d3e45089a..2979e41581 100644
--- a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
+++ b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
@@ -69,6 +69,8 @@ import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse
*/
public abstract class CassandraIndex implements Index
{
+ public static final String NAME = "legacy_local_table";
+
private static final Logger logger = LoggerFactory.getLogger(CassandraIndex.class);
public final ColumnFamilyStore baseCfs;
diff --git a/src/java/org/apache/cassandra/index/sai/README.md b/src/java/org/apache/cassandra/index/sai/README.md
index 6be0fa981a..1b434dba3c 100644
--- a/src/java/org/apache/cassandra/index/sai/README.md
+++ b/src/java/org/apache/cassandra/index/sai/README.md
@@ -61,9 +61,9 @@ Follow the instructions to build and start Cassandra in README.asc in root folde
`CREATE TABLE person (id int, name text, age int, PRIMARY KEY (id));`
-`CREATE CUSTOM INDEX ON person (name) USING 'StorageAttachedIndex' WITH OPTIONS = {'case_sensitive': false};`
+`CREATE INDEX ON person (name) USING 'sai' WITH OPTIONS = {'case_sensitive': false};`
-`CREATE CUSTOM INDEX ON person (age) USING 'StorageAttachedIndex';`
+`CREATE INDEX ON person (age) USING 'sai';`
2.) Add some data.
diff --git a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
index 264abdd71a..5a8f7b6a58 100644
--- a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
+++ b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
@@ -95,6 +95,8 @@ import org.apache.cassandra.utils.concurrent.OpOrder;
public class StorageAttachedIndex implements Index
{
+ public static final String NAME = "sai";
+
private static final Logger logger = LoggerFactory.getLogger(StorageAttachedIndex.class);
private static class StorageAttachedIndexBuildingSupport implements IndexBuildingSupport
diff --git a/src/java/org/apache/cassandra/schema/IndexMetadata.java b/src/java/org/apache/cassandra/schema/IndexMetadata.java
index 577c12b4ba..795abad984 100644
--- a/src/java/org/apache/cassandra/schema/IndexMetadata.java
+++ b/src/java/org/apache/cassandra/schema/IndexMetadata.java
@@ -67,7 +67,8 @@ public final class IndexMetadata
static
{
- indexNameAliases.put(StorageAttachedIndex.class.getSimpleName(), StorageAttachedIndex.class.getCanonicalName());
+ indexNameAliases.put(StorageAttachedIndex.NAME, StorageAttachedIndex.class.getCanonicalName());
+ indexNameAliases.put(StorageAttachedIndex.class.getSimpleName().toLowerCase(), StorageAttachedIndex.class.getCanonicalName());
indexNameAliases.put(SASIIndex.class.getSimpleName(), SASIIndex.class.getCanonicalName());
}
@@ -154,7 +155,7 @@ public final class IndexMetadata
if (isCustom())
{
String className = options.get(IndexTarget.CUSTOM_INDEX_OPTION_NAME);
- return indexNameAliases.getOrDefault(className, className);
+ return indexNameAliases.getOrDefault(className.toLowerCase(), className);
}
return CassandraIndex.class.getName();
}
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
index d87855a8bd..38f724968e 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
@@ -25,9 +25,12 @@ import java.util.concurrent.CountDownLatch;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.index.internal.CassandraIndex;
+import org.apache.cassandra.index.sai.StorageAttachedIndex;
import org.apache.cassandra.schema.ColumnMetadata;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.config.DatabaseDescriptor;
@@ -70,6 +73,12 @@ import static org.junit.Assert.fail;
public class SecondaryIndexTest extends CQLTester
{
public static final int TOO_BIG = 1024 * 65;
+
+ @BeforeClass
+ public static void setDefaultSecondaryIndex()
+ {
+ DatabaseDescriptor.setDefaultSecondaryIndex(CassandraIndex.NAME);
+ }
@Test
public void testCreateAndDropIndex() throws Throwable
@@ -161,6 +170,43 @@ public class SecondaryIndexTest extends CQLTester
return StringUtils.remove(indexName, '\"');
}
+ @Test
+ public void shouldCreateCassandraIndexExplicitly() throws Throwable
+ {
+ createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int)");
+ createIndex("CREATE INDEX byAge ON %s(age) USING 'legacy_local_table'");
+
+ SecondaryIndexManager indexManager = getCurrentColumnFamilyStore().indexManager;
+ assertTrue(indexManager.getIndexByName("byage") instanceof CassandraIndex);
+
+ UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
+ execute("INSERT INTO %s (userid, firstname, lastname, age) VALUES (?, 'Frodo', 'Baggins', 32)", id1);
+ assertEmpty(execute("SELECT firstname FROM %s WHERE userid = ? AND age = 33", id1));
+ }
+
+ @Test
+ public void shouldCreateCassandraIndexWhenNotDefault() throws Throwable
+ {
+ DatabaseDescriptor.setDefaultSecondaryIndex(StorageAttachedIndex.NAME);
+
+ try
+ {
+ createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int)");
+ createIndex("CREATE INDEX byAge ON %s(age) USING 'legacy_local_table'");
+
+ SecondaryIndexManager indexManager = getCurrentColumnFamilyStore().indexManager;
+ assertTrue(indexManager.getIndexByName("byage") instanceof CassandraIndex);
+
+ UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
+ execute("INSERT INTO %s (userid, firstname, lastname, age) VALUES (?, 'Frodo', 'Baggins', 32)", id1);
+ assertEmpty(execute("SELECT firstname FROM %s WHERE userid = ? AND age = 33", id1));
+ }
+ finally
+ {
+ DatabaseDescriptor.setDefaultSecondaryIndex(CassandraIndex.NAME);
+ }
+ }
+
/**
* Check that you can query for an indexed column even with a key EQ clause,
* migrated from cql_tests.py:TestCQL.static_cf_test()
diff --git a/test/unit/org/apache/cassandra/index/sai/SAITester.java b/test/unit/org/apache/cassandra/index/sai/SAITester.java
index d1616f49f9..4f147dc4b8 100644
--- a/test/unit/org/apache/cassandra/index/sai/SAITester.java
+++ b/test/unit/org/apache/cassandra/index/sai/SAITester.java
@@ -115,7 +115,7 @@ public abstract class SAITester extends CQLTester
protected static final String CREATE_TABLE_TEMPLATE = "CREATE TABLE %s (id1 TEXT PRIMARY KEY, v1 INT, v2 TEXT) WITH compaction = " +
"{'class' : 'SizeTieredCompactionStrategy', 'enabled' : false }";
- protected static final String CREATE_INDEX_TEMPLATE = "CREATE CUSTOM INDEX IF NOT EXISTS ON %%s(%s) USING 'StorageAttachedIndex'";
+ protected static final String CREATE_INDEX_TEMPLATE = "CREATE INDEX IF NOT EXISTS ON %%s(%s) USING 'sai'";
protected static final ColumnIdentifier V1_COLUMN_IDENTIFIER = ColumnIdentifier.getInterned("v1", true);
protected static final ColumnIdentifier V2_COLUMN_IDENTIFIER = ColumnIdentifier.getInterned("v2", true);
diff --git a/test/unit/org/apache/cassandra/index/sai/cql/CollectionIndexingTest.java b/test/unit/org/apache/cassandra/index/sai/cql/CollectionIndexingTest.java
index 8bc9efb1ca..a82f539842 100644
--- a/test/unit/org/apache/cassandra/index/sai/cql/CollectionIndexingTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/cql/CollectionIndexingTest.java
@@ -28,9 +28,11 @@ import org.apache.cassandra.index.sai.SAITester;
import static org.junit.Assert.assertEquals;
-// This test is primarily handling edge conditions, error conditions
-// and basic functionality. Comprehensive type testing of collections
-// is in the cql/types/collections package
+/**
+ * This test is primarily handling edge conditions, error conditions
+ * and basic functionality. Comprehensive type testing of collections
+ * is in the cql/types/collections package
+ */
public class CollectionIndexingTest extends SAITester
{
@Before
@@ -42,28 +44,28 @@ public class CollectionIndexingTest extends SAITester
@Test
public void indexMap() throws Throwable
{
- createPopulatedMap("CREATE CUSTOM INDEX ON %s(value) USING 'StorageAttachedIndex'");
+ createPopulatedMap(createIndexDDL("value"));
assertEquals(2, execute("SELECT * FROM %s WHERE value CONTAINS 'v1'").size());
}
@Test
public void indexMapKeys() throws Throwable
{
- createPopulatedMap("CREATE CUSTOM INDEX ON %s(KEYS(value)) USING 'StorageAttachedIndex'");
+ createPopulatedMap(createIndexDDL("KEYS(value)"));
assertEquals(2, execute("SELECT * FROM %s WHERE value CONTAINS KEY 1").size());
}
@Test
public void indexMapValues() throws Throwable
{
- createPopulatedMap("CREATE CUSTOM INDEX ON %s(VALUES(value)) USING 'StorageAttachedIndex'");
+ createPopulatedMap(createIndexDDL("VALUES(value)"));
assertEquals(2, execute("SELECT * FROM %s WHERE value CONTAINS 'v1'").size());
}
@Test
public void indexMapEntries() throws Throwable
{
- createPopulatedMap("CREATE CUSTOM INDEX ON %s(ENTRIES(value)) USING 'StorageAttachedIndex'");
+ createPopulatedMap(createIndexDDL("ENTRIES(value)"));
assertEquals(2, execute("SELECT * FROM %s WHERE value[1] = 'v1'").size());
assertEquals(1, execute("SELECT * FROM %s WHERE value[1] = 'v1' AND value[2] = 'v2'").size());
}
@@ -71,14 +73,14 @@ public class CollectionIndexingTest extends SAITester
@Test
public void indexFrozenList() throws Throwable
{
- createPopulatedFrozenList("CREATE CUSTOM INDEX ON %s(FULL(value)) USING 'StorageAttachedIndex'");
+ createPopulatedFrozenList(createIndexDDL("FULL(value)"));
assertEquals(2, execute("SELECT * FROM %s WHERE value = ?", Arrays.asList(1, 2, 3)).size());
}
@Test
public void indexFrozenMap() throws Throwable
{
- createPopulatedFrozenMap("CREATE CUSTOM INDEX ON %s(FULL(value)) USING 'StorageAttachedIndex'");
+ createPopulatedFrozenMap(createIndexDDL("FULL(value)"));
assertEquals(1, execute("SELECT * FROM %s WHERE value = ?", new HashMap>)");
createIndex(createIndex);
@@ -220,4 +222,9 @@ public class CollectionIndexingTest extends SAITester
assertInvalidMessage(StatementRestrictions.REQUIRES_ALLOW_FILTERING_MESSAGE, query, values);
assertEquals(expectedSize, execute(query + " ALLOW FILTERING").size());
}
+
+ private static String createIndexDDL(String target)
+ {
+ return "CREATE INDEX ON %s(" + target + ") USING 'sai'";
+ }
}
diff --git a/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java b/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
index bfaabf5b9a..0e488b2507 100644
--- a/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
@@ -30,20 +30,20 @@ public class CompositePartitionKeyIndexTest extends SAITester
public void createTableAndIndex()
{
createTable("CREATE TABLE %s (pk1 int, pk2 text, val int, PRIMARY KEY((pk1, pk2)))");
- createIndex("CREATE CUSTOM INDEX ON %s(pk1) USING 'StorageAttachedIndex'");
- createIndex("CREATE CUSTOM INDEX ON %s(pk2) USING 'StorageAttachedIndex'");
+ createIndex("CREATE INDEX ON %s(pk1) USING 'sai'");
+ createIndex("CREATE INDEX ON %s(pk2) USING 'sai'");
disableCompaction();
}
- private void insertData1() throws Throwable
+ private void insertData1()
{
execute("INSERT INTO %s (pk1, pk2, val) VALUES (1, '1', 1)");
execute("INSERT INTO %s (pk1, pk2, val) VALUES (2, '2', 2)");
execute("INSERT INTO %s (pk1, pk2, val) VALUES (3, '3', 3)");
}
- private void insertData2() throws Throwable
+ private void insertData2()
{
execute("INSERT INTO %s (pk1, pk2, val) VALUES (4, '4', 4)");
execute("INSERT INTO %s (pk1, pk2, val) VALUES (5, '5', 5)");
@@ -51,7 +51,7 @@ public class CompositePartitionKeyIndexTest extends SAITester
}
@Test
- public void queryFromMemtable() throws Throwable
+ public void queryFromMemtable()
{
insertData1();
insertData2();
@@ -62,7 +62,7 @@ public class CompositePartitionKeyIndexTest extends SAITester
return row(index, Integer.toString(index), index);
}
- private void runQueries() throws Throwable
+ private void runQueries()
{
assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE pk1 = 2"),
expectedRow(2));
diff --git a/test/unit/org/apache/cassandra/index/sai/cql/MultipleColumnIndexTest.java b/test/unit/org/apache/cassandra/index/sai/cql/MultipleColumnIndexTest.java
index 97f93e29aa..459d608dc5 100644
--- a/test/unit/org/apache/cassandra/index/sai/cql/MultipleColumnIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/cql/MultipleColumnIndexTest.java
@@ -25,26 +25,26 @@ import static org.junit.Assert.assertEquals;
public class MultipleColumnIndexTest extends SAITester
{
- // Note: Full testing of multiple map index types is done in the
- // types/collections/maps/MultiMap*Test tests
- // This is just testing that the indexes can be created
@Test
public void canCreateMultipleMapIndexesOnSameColumn()
{
+ // Note: Full testing of multiple map index types is done in the
+ // types/collections/maps/MultiMap*Test tests
+ // This is just testing that the indexes can be created
createTable("CREATE TABLE %s (pk int, ck int, value map