4848
4949public final class CreateIndexStatement extends AlterSchemaStatement
5050{
51+ public static final String SASI_INDEX_DISABLED = "SASI indexes are disabled. Enable in cassandra.yaml to use." ;
52+ public static final String KEYSPACE_DOES_NOT_EXIST = "Keyspace '%s' doesn't exist" ;
53+ public static final String TABLE_DOES_NOT_EXIST = "Table '%s' doesn't exist" ;
54+ public static final String COUNTER_TABLES_NOT_SUPPORTED = "Secondary indexes on counter tables aren't supported" ;
55+ public static final String MATERIALIZED_VIEWS_NOT_SUPPORTED = "Secondary indexes on materialized views aren't supported" ;
56+ public static final String TRANSIENTLY_REPLICATED_KEYSPACE_NOT_SUPPORTED = "Secondary indexes are not supported on transiently replicated keyspaces" ;
57+ public static final String CUSTOM_CREATE_WITHOUT_COLUMN = "Only CUSTOM indexes can be created without specifying a target column" ;
58+ public static final String CUSTOM_MULTIPLE_COLUMNS = "Only CUSTOM indexes support multiple columns" ;
59+ public static final String DUPLICATE_TARGET_COLUMN = "Duplicate column '%s' in index target list" ;
60+ public static final String COLUMN_DOES_NOT_EXIST = "Column '%s' doesn't exist" ;
5161 public static final String INVALID_CUSTOM_INDEX_TARGET = "Column '%s' is longer than the permissible name length of %d characters or" +
5262 " contains non-alphanumeric-underscore characters" ;
63+ public static final String COLLECTIONS_WITH_DURATIONS_NOT_SUPPORTED = "Secondary indexes are not supported on collections containing durations" ;
64+ public static final String TUPLES_WITH_DURATIONS_NOT_SUPPORTED = "Secondary indexes are not supported on tuples containing durations" ;
65+ public static final String DURATIONS_NOT_SUPPORTED = "Secondary indexes are not supported on duration columns" ;
66+ public static final String UDTS_WITH_DURATIONS_NOT_SUPPORTED = "Secondary indexes are not supported on UDTs containing durations" ;
67+ public static final String PRIMARY_KEY_IN_COMPACT_STORAGE = "Secondary indexes are not supported on PRIMARY KEY columns in COMPACT STORAGE tables" ;
68+ public static final String COMPACT_COLUMN_IN_COMPACT_STORAGE = "Secondary indexes are not supported on compact value column of COMPACT STORAGE tables" ;
69+ public static final String ONLY_PARTITION_KEY = "Cannot create secondary index on the only partition key column %s" ;
70+ public static final String CREATE_ON_FROZEN_COLUMN = "Cannot create %s() index on frozen column %s. Frozen collections are immutable and must be fully " +
71+ "indexed by using the 'full(%s)' modifier" ;
72+ public static final String FULL_ON_FROZEN_COLLECTIONS = "full() indexes can only be created on frozen collections" ;
73+ public static final String NON_COLLECTION_SIMPLE_INDEX = "Cannot create %s() index on %s. Non-collection columns only support simple indexes" ;
74+ public static final String CREATE_WITH_NON_MAP_TYPE = "Cannot create index on %s of column %s with non-map type" ;
75+ public static final String CREATE_ON_NON_FROZEN_UDT = "Cannot create index on non-frozen UDT column %s" ;
76+ public static final String INDEX_ALREADY_EXISTS = "Index '%s' already exists" ;
77+ public static final String INDEX_DUPLICATE_OF_EXISTING = "Index %s is a duplicate of existing index %s" ;
78+ public static final String KEYSPACE_DOES_NOT_MATCH_TABLE = "Keyspace name '%s' doesn't match table name '%s'" ;
79+ public static final String KEYSPACE_DOES_NOT_MATCH_INDEX = "Keyspace name '%s' doesn't match index name '%s'" ;
5380
5481 private final String indexName ;
5582 private final String tableName ;
@@ -90,32 +117,32 @@ public Keyspaces apply(Keyspaces schema)
90117 Guardrails .createSecondaryIndexesEnabled .ensureEnabled ("Creating secondary indexes" , state );
91118
92119 if (attrs .isCustom && attrs .customClass .equals (SASIIndex .class .getName ()) && !DatabaseDescriptor .getSASIIndexesEnabled ())
93- throw new InvalidRequestException ("SASI indexes are disabled. Enable in cassandra.yaml to use." );
120+ throw new InvalidRequestException (SASI_INDEX_DISABLED );
94121
95122 KeyspaceMetadata keyspace = schema .getNullable (keyspaceName );
96123 if (null == keyspace )
97- throw ire ("Keyspace '%s' doesn't exist" , keyspaceName );
124+ throw ire (KEYSPACE_DOES_NOT_EXIST , keyspaceName );
98125
99126 TableMetadata table = keyspace .getTableOrViewNullable (tableName );
100127 if (null == table )
101- throw ire ("Table '%s' doesn't exist" , tableName );
128+ throw ire (TABLE_DOES_NOT_EXIST , tableName );
102129
103130 if (null != indexName && keyspace .hasIndex (indexName ))
104131 {
105132 if (ifNotExists )
106133 return schema ;
107134
108- throw ire ("Index '%s' already exists" , indexName );
135+ throw ire (INDEX_ALREADY_EXISTS , indexName );
109136 }
110137
111138 if (table .isCounter ())
112- throw ire ("Secondary indexes on counter tables aren't supported" );
139+ throw ire (COUNTER_TABLES_NOT_SUPPORTED );
113140
114141 if (table .isView ())
115- throw ire ("Secondary indexes on materialized views aren't supported" );
142+ throw ire (MATERIALIZED_VIEWS_NOT_SUPPORTED );
116143
117144 if (Keyspace .open (table .keyspace ).getReplicationStrategy ().hasTransientReplicas ())
118- throw new InvalidRequestException ("Secondary indexes are not supported on transiently replicated keyspaces" );
145+ throw new InvalidRequestException (TRANSIENTLY_REPLICATED_KEYSPACE_NOT_SUPPORTED );
119146
120147 // guardrails to limit number of secondary indexes per table.
121148 Guardrails .secondaryIndexesPerTable .guard (table .indexes .size () + 1 ,
@@ -128,17 +155,17 @@ public Keyspaces apply(Keyspaces schema)
128155 List <IndexTarget > indexTargets = Lists .newArrayList (transform (rawIndexTargets , t -> t .prepare (table )));
129156
130157 if (indexTargets .isEmpty () && !attrs .isCustom )
131- throw ire ("Only CUSTOM indexes can be created without specifying a target column" );
158+ throw ire (CUSTOM_CREATE_WITHOUT_COLUMN );
132159
133160 if (indexTargets .size () > 1 )
134161 {
135162 if (!attrs .isCustom )
136- throw ire ("Only CUSTOM indexes support multiple columns" );
163+ throw ire (CUSTOM_MULTIPLE_COLUMNS );
137164
138165 Set <ColumnIdentifier > columns = new HashSet <>();
139166 for (IndexTarget target : indexTargets )
140167 if (!columns .add (target .column ))
141- throw ire ("Duplicate column '%s' in index target list" , target .column );
168+ throw ire (DUPLICATE_TARGET_COLUMN , target .column );
142169 }
143170
144171 IndexMetadata .Kind kind = attrs .isCustom ? IndexMetadata .Kind .CUSTOM : IndexMetadata .Kind .COMPOSITES ;
@@ -158,7 +185,7 @@ public Keyspaces apply(Keyspaces schema)
158185 if (ifNotExists )
159186 return schema ;
160187
161- throw ire ("Index %s is a duplicate of existing index %s" , index .name , equalIndex .name );
188+ throw ire (INDEX_DUPLICATE_OF_EXISTING , index .name , equalIndex .name );
162189 }
163190
164191 TableMetadata newTable = table .withSwapped (table .indexes .with (index ));
@@ -181,52 +208,51 @@ private void validateIndexTarget(TableMetadata table, IndexMetadata.Kind kind, I
181208 ColumnMetadata column = table .getColumn (target .column );
182209
183210 if (null == column )
184- throw ire ("Column '%s' doesn't exist" , target .column );
211+ throw ire (COLUMN_DOES_NOT_EXIST , target .column );
185212
186213 if ((kind == IndexMetadata .Kind .CUSTOM ) && !SchemaConstants .isValidName (target .column .toString ()))
187214 throw ire (INVALID_CUSTOM_INDEX_TARGET , target .column , SchemaConstants .NAME_LENGTH );
188215
189216 if (column .type .referencesDuration ())
190217 {
191218 if (column .type .isCollection ())
192- throw ire ("Secondary indexes are not supported on collections containing durations" );
219+ throw ire (COLLECTIONS_WITH_DURATIONS_NOT_SUPPORTED );
193220
194221 if (column .type .isTuple ())
195- throw ire ("Secondary indexes are not supported on tuples containing durations" );
222+ throw ire (TUPLES_WITH_DURATIONS_NOT_SUPPORTED );
196223
197224 if (column .type .isUDT ())
198- throw ire ("Secondary indexes are not supported on UDTs containing durations" );
225+ throw ire (UDTS_WITH_DURATIONS_NOT_SUPPORTED );
199226
200- throw ire ("Secondary indexes are not supported on duration columns" );
227+ throw ire (DURATIONS_NOT_SUPPORTED );
201228 }
202229
203230 if (table .isCompactTable ())
204231 {
205232 TableMetadata .CompactTableMetadata compactTable = (TableMetadata .CompactTableMetadata ) table ;
206233 if (column .isPrimaryKeyColumn ())
207- throw new InvalidRequestException ("Secondary indexes are not supported on PRIMARY KEY columns in COMPACT STORAGE tables" );
234+ throw new InvalidRequestException (PRIMARY_KEY_IN_COMPACT_STORAGE );
208235 if (compactTable .compactValueColumn .equals (column ))
209- throw new InvalidRequestException ("Secondary indexes are not supported on compact value column of COMPACT STORAGE tables" );
236+ throw new InvalidRequestException (COMPACT_COLUMN_IN_COMPACT_STORAGE );
210237 }
211238
212239 if (column .isPartitionKey () && table .partitionKeyColumns ().size () == 1 )
213- throw ire ("Cannot create secondary index on the only partition key column %s" , column );
240+ throw ire (ONLY_PARTITION_KEY , column );
214241
215242 if (column .type .isFrozenCollection () && target .type != Type .FULL )
216- throw ire ("Cannot create %s() index on frozen column %s. Frozen collections are immutable and must be fully " +
217- "indexed by using the 'full(%s)' modifier" , target .type , column , column );
243+ throw ire (CREATE_ON_FROZEN_COLUMN , target .type , column , column );
218244
219245 if (!column .type .isFrozenCollection () && target .type == Type .FULL )
220- throw ire ("full() indexes can only be created on frozen collections" );
246+ throw ire (FULL_ON_FROZEN_COLLECTIONS );
221247
222248 if (!column .type .isCollection () && target .type != Type .SIMPLE )
223- throw ire ("Cannot create %s() index on %s. Non-collection columns only support simple indexes" , target .type , column );
249+ throw ire (NON_COLLECTION_SIMPLE_INDEX , target .type , column );
224250
225251 if (!(column .type instanceof MapType && column .type .isMultiCell ()) && (target .type == Type .KEYS || target .type == Type .KEYS_AND_VALUES ))
226- throw ire ("Cannot create index on %s of column %s with non-map type" , target .type , column );
252+ throw ire (CREATE_WITH_NON_MAP_TYPE , target .type , column );
227253
228254 if (column .type .isUDT () && column .type .isMultiCell ())
229- throw ire ("Cannot create index on non-frozen UDT column %s" , column );
255+ throw ire (CREATE_ON_NON_FROZEN_UDT , column );
230256 }
231257
232258 private String generateIndexName (KeyspaceMetadata keyspace , List <IndexTarget > targets )
@@ -286,10 +312,10 @@ public CreateIndexStatement prepare(ClientState state)
286312 : indexName .hasKeyspace () ? indexName .getKeyspace () : state .getKeyspace ();
287313
288314 if (tableName .hasKeyspace () && !keyspaceName .equals (tableName .getKeyspace ()))
289- throw ire ("Keyspace name '%s' doesn't match table name '%s'" , keyspaceName , tableName );
315+ throw ire (KEYSPACE_DOES_NOT_MATCH_TABLE , keyspaceName , tableName );
290316
291317 if (indexName .hasKeyspace () && !keyspaceName .equals (indexName .getKeyspace ()))
292- throw ire ("Keyspace name '%s' doesn't match index name '%s'" , keyspaceName , tableName );
318+ throw ire (KEYSPACE_DOES_NOT_MATCH_INDEX , keyspaceName , tableName );
293319
294320 return new CreateIndexStatement (keyspaceName , tableName .getName (), indexName .getName (), rawIndexTargets , attrs , ifNotExists );
295321 }
0 commit comments