You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pr@cassandra.apache.org by "Maxwell-Guo (via GitHub)" <gi...@apache.org> on 2025/01/26 15:57:37 UTC
[PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Maxwell-Guo opened a new pull request, #3831:
URL: https://github.com/apache/cassandra/pull/3831
```
CREATE TABLE LIKE with INDEX/ TRIGGER /ALL option
patch by <Authors>; reviewed by <Reviewers> for CASSANDRA-19965
Co-authored-by: Name1 <email1>
Co-authored-by: Name2 <email2>
```
The [Cassandra Jira](https://issues.apache.org/jira/projects/CASSANDRA/issues/)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "bbotella (via GitHub)" <gi...@apache.org>.
bbotella commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1930789770
##########
pylib/cqlshlib/cql3handling.py:
##########
@@ -380,6 +380,11 @@ def dequote_value(cqlword):
( ender="," [propmapkey]=<term> ":" [propmapval]=<term> )*
ender="}"
;
+<propertyOrOption> ::= <property>
Review Comment:
Maybe having a standalone `copyOption` for `ALL | INDEXES | TRIGGERS` and turn this into
```
<propertyOrOption> ::= <property>
| <copyOption>
;
```
is cleaner. What do you think?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1948979057
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +238,56 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void maybeCopyIndexes(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption != CreateLikeOption.INDEXES || sourceTableMeta.indexes.isEmpty())
+ return;
+
+ Set<String> customIndexes = Sets.newTreeSet();
+ Set<String> alreadyExistingIndexes = Sets.newTreeSet();
+ List<IndexMetadata> indexesToCopy = new ArrayList<>();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ // only sai and legacy secondary index is supported
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM &&
+ indexMetadata.getIndexClassName() != StorageAttachedIndex.class.getCanonicalName())
Review Comment:
I do not think this is necessary. All we need to check is if that index is `CUSTOM`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939218749
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -248,7 +278,24 @@ public CQLStatement prepare(ClientState state)
{
String oldKeyspace = oldName.hasKeyspace() ? oldName.getKeyspace() : state.getKeyspace();
String newKeyspace = newName.hasKeyspace() ? newName.getKeyspace() : state.getKeyspace();
- return new CopyTableStatement(oldKeyspace, newKeyspace, oldName.getName(), newName.getName(), ifNotExists, attrs);
+ return new CopyTableStatement(oldKeyspace, newKeyspace, oldName.getName(), newName.getName(), ifNotExists, createLikeOption, attrs);
+ }
+
+ public void setLikeOptions(CreateLikeOption likeOption)
+ {
+ this.createLikeOption = likeOption;
+ }
+ }
+
+ public enum CreateLikeOption
+ {
+ EMPTY("EMPTY"),
Review Comment:
This is not used anywhere except in
`private CreateLikeOption createLikeOption = CreateLikeOption.EMPTY;`
You can just set `createLikeOption` to `null`, you do not need `EMPTY`. You can remove `EMPTY`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1937499107
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -227,13 +237,50 @@ public void validate(ClientState state)
Guardrails.tables.guard(totalUserTables + 1, targetTableName, false, state);
}
validateDefaultTimeToLive(attrs.asNewTableParams());
+
+ if (createLikeOptions.contains(ALL) && createLikeOptions.size() > 1)
+ {
+ throw ire("It is not allowed to use ALL option together with " + createLikeOptions.stream().filter(option -> option != ALL).sorted().collect(Collectors.toList()));
+ }
+ }
+
+ private void cloneIndexesAndTriggersIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta, String targetTableName)
+ {
+ if (createLikeOptions.contains(INDEX) ||
+ createLikeOptions.contains(ALL))
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ // todo use source index name if target keyspace don't have same index name but use random name now as cep-43 described
+ String baseName = targetKeyspaceMeta.name + "_" + targetTableName + "_" + indexMetadata.name;
+ String idxName = targetKeyspaceMeta.findAvailableIndexName(baseName);
+ idxBuilder.add(IndexMetadata.fromSchemaMetadata(idxName, indexMetadata.kind, indexMetadata.options));
Review Comment:
Agree with your suggestion.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939208017
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
Review Comment:
What if `sourceTableMeta.indexes` is empty? What if source table does not have any index? Then you are creating `idxBuilder` unnecessarily.
I would expand on the previous suggestion and did:
````
if (createLikeOption != CreateLikeOption.INDEX || sourceTableMeta.indexes.isEmpty())
return;
...
````
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "blerer (via GitHub)" <gi...@apache.org>.
blerer commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1936831243
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -227,13 +237,50 @@ public void validate(ClientState state)
Guardrails.tables.guard(totalUserTables + 1, targetTableName, false, state);
}
validateDefaultTimeToLive(attrs.asNewTableParams());
+
+ if (createLikeOptions.contains(ALL) && createLikeOptions.size() > 1)
+ {
+ throw ire("It is not allowed to use ALL option together with " + createLikeOptions.stream().filter(option -> option != ALL).sorted().collect(Collectors.toList()));
+ }
+ }
+
+ private void cloneIndexesAndTriggersIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta, String targetTableName)
+ {
+ if (createLikeOptions.contains(INDEX) ||
+ createLikeOptions.contains(ALL))
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ // todo use source index name if target keyspace don't have same index name but use random name now as cep-43 described
+ String baseName = targetKeyspaceMeta.name + "_" + targetTableName + "_" + indexMetadata.name;
+ String idxName = targetKeyspaceMeta.findAvailableIndexName(baseName);
+ idxBuilder.add(IndexMetadata.fromSchemaMetadata(idxName, indexMetadata.kind, indexMetadata.options));
Review Comment:
I am a bit confused by the logic surrounding the index and trigger name. I fear that it will bring more confusion than anything else. If an index with the same name already exists we should probably raise an error and let the user deal with it, no?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939205681
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
Review Comment:
I would do
````
if (createLikeOption != CreateLikeOption.INDEX)
return;
...
````
By doing that, we make the number of indentations smaller etc.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939199864
##########
doc/cql3/CQL.textile:
##########
@@ -414,16 +414,19 @@ bc(syntax)..
<copy-table-stmt> ::= CREATE ( TABLE | COLUMNFAMILY ) ( IF NOT EXISTS )? <newtablename> LIKE <oldtablename>
( WITH <option> ( AND <option>)* )?
-<option> ::= <property>
+<option> ::= <property> | INDEX
Review Comment:
@Maxwell-Guo should not it be "WITH INDEXES"? Bernardo suggested that as well below.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939201295
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
great! Maybe specifying keyspace, table and name of custom index in this message will be helpful for users.
EDIT: The shortcoming of this is that, imagine we have three indexes, two indexes are e.g. legacy 2i (not sai) and the third index is custom.
What you do here is that as soon as you encounter custom index, you will fail.
Imagine that sourceTableMeta.indexes contains these indexes:
1) first index 2i
2) second index custom
3) third index 2i
Then you create first index and you fail on the second so you will not add the third.
We have in general two options
1) iterate over `sourceTableMeta.indexes` and check if there is some custom index and if it is, we fail
2) iterate over `sourceTableMeta.indexes` and if there is a custom index, we will just skip it. That means that all non-custom indexes will be still created.
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
@Maxwell-Guo The shortcoming of this is that, imagine we have three indexes, two indexes are e.g. legacy 2i (not sai) and the third index is custom.
What you do here is that as soon as you encounter custom index, you will fail.
Imagine that sourceTableMeta.indexes contains these indexes:
1) first index 2i
2) second index custom
3) third index 2i
Then you create first index and you fail on the second so you will not add the third.
We have in general two options
1) iterate over `sourceTableMeta.indexes` and check if there is some custom index and if it is, we fail
2) iterate over `sourceTableMeta.indexes` and if there is a custom index, we will just skip it. That means that all non-custom indexes will be still created.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939201295
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
great!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEXES option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1952786647
##########
pylib/cqlshlib/cql3handling.py:
##########
@@ -380,6 +380,11 @@ def dequote_value(cqlword):
( ender="," [propmapkey]=<term> ":" [propmapval]=<term> )*
ender="}"
;
+<propertyOrOption> ::= <property>
Review Comment:
Update the code to support ALL INDEXES
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939208017
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
Review Comment:
What if `sourceTableMeta.indexes` is empty? What source does not have any index? Then you are creating `idxBuilder` unnecessarily.
I would expand on the previous suggestion and did:
````
if (createLikeOption != CreateLikeOption.INDEX || sourceTableMeta.indexes.isEmpty())
return;
...
````
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] Support CREATE TABLE LIKE with INDEXES [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo closed pull request #3831: Support CREATE TABLE LIKE with INDEXES
URL: https://github.com/apache/cassandra/pull/3831
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1950176507
##########
test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java:
##########
@@ -244,60 +248,59 @@ public void testCopyAfterAlterTable()
row(1, "1", duration1, uuid1));
assertRows(execute("SELECT * FROM " + targetKs + "." + targetTb),
row(2, "2", duration2, uuid2));
-
}
@Test
public void testTableOptionsCopy() throws Throwable
{
// compression
String tbCompressionDefault1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))");
- String tbCompressionDefault2 =createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'enabled' : 'false'};");
+ String tbCompressionDefault2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'enabled' : 'false'};");
String tbCompressionSnappy1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
- String tbCompressionSnappy2 =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
- String tbCompressionSnappy3 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
- String tbCompressionSnappy4 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
- String tbCompressionSnappy5 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
+ String tbCompressionSnappy2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
+ String tbCompressionSnappy3 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
+ String tbCompressionSnappy4 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
+ String tbCompressionSnappy5 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
// memtable
- String tableMemtableSkipList = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'skiplist';");
- String tableMemtableTrie = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'trie';");
- String tableMemtableDefault = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'default';");
+ String tableMemtableSkipList = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'skiplist';");
+ String tableMemtableTrie = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'trie';");
+ String tableMemtableDefault = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'default';");
// compaction
- String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
- String tableCompactionLcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
+ String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
+ String tableCompactionLcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
String tableCompactionTwcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'TimeWindowCompactionStrategy', 'min_threshold':2};");
- String tableCompactionUcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
+ String tableCompactionUcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
// other options are all different from default
String tableOtherOptions = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH" +
- " additional_write_policy = '95p' " +
- " AND bloom_filter_fp_chance = 0.1 " +
- " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
- " AND cdc = true " +
- " AND comment = 'test for create like'" +
- " AND crc_check_chance = 0.1" +
- " AND default_time_to_live = 10" +
- " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
- " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
- " AND gc_grace_seconds = 100" +
- " AND incremental_backups = false" +
- " AND max_index_interval = 1024" +
- " AND min_index_interval = 64" +
- " AND speculative_retry = '95p'" +
- " AND read_repair = 'NONE'" +
- " AND memtable_flush_period_in_ms = 360000" +
- " AND memtable = 'default';" );
+ " additional_write_policy = '95p' " +
+ " AND bloom_filter_fp_chance = 0.1 " +
+ " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
+ " AND cdc = true " +
+ " AND comment = 'test for create like'" +
+ " AND crc_check_chance = 0.1" +
+ " AND default_time_to_live = 10" +
+ " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
+ " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
Review Comment:
thanks
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1950175525
##########
pylib/cqlshlib/test/test_cqlsh_completion.py:
##########
@@ -808,23 +808,18 @@ def test_complete_in_create_table_like(self):
'memtable',
'memtable_flush_period_in_ms',
'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
- self.trycompletions('CREATE TABLE ' + 'new_table LIKE old_table WITH ',
- choices=['allow_auto_snapshot',
- 'bloom_filter_fp_chance', 'compaction',
- 'compression',
- 'default_time_to_live', 'gc_grace_seconds',
- 'incremental_backups',
- 'max_index_interval',
- 'memtable',
- 'memtable_flush_period_in_ms',
- 'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
+ 'min_index_interval',
+ 'speculative_retry', 'additional_write_policy',
+ 'cdc', 'read_repair',
+ 'ALL'])
+ self.trycompletions('CREATE TABLE new_table LIKE old_table WITH ALL ',
+ choices=['<identifier>', '='])
Review Comment:
There will be keyword "ALL" or property after keyword "WITH" and for property ,
see
```
<propertyOrOption> ::= <property>
| "ALL" <identifier>
```
as for <property> , it is also a key value map with "=" in the middle.
So the ALL was treated as the key of <property>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939201295
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
great! Maybe specifying keyspace, table and name of custom index in this message will be helpful for users.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939201295
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
@Maxwell-Guo The shortcoming of this is that, imagine we have three indexes, two indexes are e.g. legacy 2i (not sai) and the third index is custom.
What you do here is that as soon as you encounter custom index, you will fail.
Imagine that `sourceTableMeta.indexes` contains these indexes:
1) first index 2i
2) second index custom
3) third index 2i
Then you create first index and you fail on the second so you will not add the third.
We have in general two options
1) iterate over `sourceTableMeta.indexes` and check if there is some custom index and if it is, we fail
2) iterate over `sourceTableMeta.indexes` and if there is a custom index, we will just skip it. That means that all non-custom indexes will be still created.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "bbotella (via GitHub)" <gi...@apache.org>.
bbotella commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1930760576
##########
pylib/cqlshlib/cql3handling.py:
##########
@@ -380,6 +380,11 @@ def dequote_value(cqlword):
( ender="," [propmapkey]=<term> ":" [propmapval]=<term> )*
ender="}"
;
+<propertyOrOption> ::= <property>
+ | "ALL"
+ | "INDEX"
Review Comment:
Reading the CEP, I think these names should be plural right? `INDEXES` and `TRIGGERS`?
##########
test/unit/org/apache/cassandra/cql3/CQLTester.java:
##########
@@ -1969,24 +1981,82 @@ private static boolean isEmptyContainerNull(DataType type,
}
/**
- * Determine whether the source and target TableMetadata is equal without compare the table name and dropped columns.
+ * Determine whether the source and target TableMetadata is equal without compare the table name and dropped columns, and
+ * compare the indexes and triggers of the source and target tables, but do not compare their names.
* @param source the source TableMetadata
* @param target the target TableMetadata
- * @param compareParams wether compare table params
+ * @param compareParams wether compare table's params
* @param compareIndexes wether compare table's indexes
- * @param compareTrigger wether compare table's triggers
+ * @param compareTriggers wether compare table's triggers
* */
- protected boolean equalsWithoutTableNameAndDropCns(TableMetadata source, TableMetadata target, boolean compareParams, boolean compareIndexes, boolean compareTrigger)
+ protected boolean equalsWithoutTableNameAndDropCns(TableMetadata source, TableMetadata target, boolean compareParams, boolean compareIndexes, boolean compareTriggers)
{
return source.partitioner.equals(target.partitioner)
&& source.kind == target.kind
&& source.flags.equals(target.flags)
&& (!compareParams || source.params.equals(target.params))
- && (!compareIndexes || source.indexes.equals(target.indexes))
- && (!compareTrigger || source.triggers.equals(target.triggers))
+ && compareIndexesOrTriggerWithoutName(compareIndexes,
+ compareTriggers,
+ source.indexes,
+ target.indexes,
+ source.triggers,
+ target.triggers,
+ target.keyspace,
+ target.name)
&& columnsEqualWitoutKsTb(source, target);
}
+ /**
+ * Compare the source table and target table's indexes and triggers without compare their name,
+ * because the names of the target indexes and triggers are randomly genrated base on the source
+ * table name and source keyspace name with a rule thant can see
+ * {@link KeyspaceMetadata#findAvailableTriggerName(String)} and {@link KeyspaceMetadata#findAvailableIndexName(String)}
+ * for more detail.
+ * @param compareIndexes wether compare indexes or not
+ * @param compareTriggers wether compare triggers or not
+ * @param sourceIdxes source indexes
+ * @param targetIdxes target indexes
+ * @param sourceTriggers source triggers
+ * @param targetTriggers target triggers
+ * @return true if source table's indexes or triggers are same with target table's indexes or triggers without compare keyspace and table name
+ * */
+ private boolean compareIndexesOrTriggerWithoutName(boolean compareIndexes, boolean compareTriggers, Indexes sourceIdxes, Indexes targetIdxes, Triggers sourceTriggers, Triggers targetTriggers, String targetKs, String targetTb)
Review Comment:
Similar nit. I think splitting this method into indexes and triggers may help with the method signature.
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -227,13 +237,50 @@ public void validate(ClientState state)
Guardrails.tables.guard(totalUserTables + 1, targetTableName, false, state);
}
validateDefaultTimeToLive(attrs.asNewTableParams());
+
+ if (createLikeOptions.contains(ALL) && createLikeOptions.size() > 1)
+ {
+ throw ire("It is not allowed to use ALL option together with " + createLikeOptions.stream().filter(option -> option != ALL).sorted().collect(Collectors.toList()));
+ }
+ }
+
+ private void cloneIndexesAndTriggersIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta, String targetTableName)
+ {
+ if (createLikeOptions.contains(INDEX) ||
+ createLikeOptions.contains(ALL))
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ // todo use source index name if target keyspace don't have same index name but use random name now as cep-43 described
+ String baseName = targetKeyspaceMeta.name + "_" + targetTableName + "_" + indexMetadata.name;
+ String idxName = targetKeyspaceMeta.findAvailableIndexName(baseName);
+ idxBuilder.add(IndexMetadata.fromSchemaMetadata(idxName, indexMetadata.kind, indexMetadata.options));
+ }
+ builder.indexes(idxBuilder.build());
Review Comment:
Nit: I think extracting this and the triggers section to their own private methods may help with readibility.
##########
test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java:
##########
@@ -576,28 +581,135 @@ public void testTriggerOperationOnCopiedTable()
public void testUnSupportedSchema() throws Throwable
{
createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text)", "tb");
- String index = createIndex( "CREATE INDEX ON " + sourceKs + ".tb (c)");
+ String index = createIndex("CREATE INDEX ON " + sourceKs + ".tb (c)");
assertInvalidThrowMessage("Souce Table '" + targetKs + "." + index + "' doesn't exist", InvalidRequestException.class,
- "CREATE TABLE " + sourceKs + ".newtb LIKE " + targetKs + "." + index + ";");
+ "CREATE TABLE " + sourceKs + ".newtb LIKE " + targetKs + "." + index + ";");
assertInvalidThrowMessage("System keyspace 'system' is not user-modifiable", InvalidRequestException.class,
"CREATE TABLE system.local_clone LIKE system.local ;");
assertInvalidThrowMessage("System keyspace 'system_views' is not user-modifiable", InvalidRequestException.class,
"CREATE TABLE system_views.newtb LIKE system_views.snapshots ;");
}
+ @Test
+ public void testTableCopyWithIndex()
+ {
+ String sourceTb = createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createIndex(sourceKs, "CREATE INDEX ON %s (b)");
+ createIndex(sourceKs, "CREATE INDEX ON %s (c)");
+ String targetTb = createTableLike("CREATE TABLE %s LIKE %s WITH INDEX ", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTb);
+ }
+
+ @Test
+ public void testTableCopyWithTrigger()
+ {
+ String sourceTb = createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createTrigger(sourceKs, "sourcetb", "trigger_1", "CREATE TRIGGER %s ON %s USING '" + triggerClass1 + "'");
+ createTrigger(sourceKs, "sourcetb", "trigger_2", "CREATE TRIGGER %s ON %s USING '" + triggerClass2 + "'");
+ String targetTb = createTableLike("CREATE TABLE %s LIKE %s WITH TRIGGER", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTb);
+ }
+
+ @Test
+ public void testTableCopyWithIndexAndTrigger()
+ {
+ String sourceTb = createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createIndex(sourceKs, "CREATE INDEX ON %s (b)");
+ createIndex(sourceKs, "CREATE INDEX ON %s (d)");
+ createTrigger(sourceKs, "sourcetb", "trigger_1", "CREATE TRIGGER %s ON %s USING '" + triggerClass1 + "'");
+ createTrigger(sourceKs, "sourcetb", "trigger_2", "CREATE TRIGGER %s ON %s USING '" + triggerClass2 + "'");
+ createTrigger(sourceKs, "sourcetb", "trigger_3", "CREATE TRIGGER %s ON %s USING '" + triggerClass2 + "'");
+ String targetTb = createTableLike("CREATE TABLE %s LIKE %s WITH TRIGGER AND INDEX", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTb);
+ }
+
+ @Test
+ public void testTableCopyWithAllOption()
+ {
+ String sourceTb = createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createIndex(sourceKs, "CREATE INDEX ON %s (b)");
+ createTrigger(sourceKs, "sourcetb", "trigger_1", "CREATE TRIGGER %s ON %s USING '" + triggerClass1 + "'");
+ createTrigger(sourceKs, "sourcetb", "trigger_2", "CREATE TRIGGER %s ON %s USING '" + triggerClass2 + "'");
+ String targetTb = createTableLike("CREATE TABLE %s LIKE %s WITH ALL ", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTb);
+ }
+
+ @Test
+ public void testTableCopyOptionAndTableProperty()
+ {
+ String sourceTb = createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createIndex(sourceKs, "CREATE INDEX ON %s (b)");
+ createTrigger(sourceKs, "sourcetb", "trigger_1", "CREATE TRIGGER %s ON %s USING '" + triggerClass1 + "'");
+ String targetTbWithAll = createTableLike("CREATE TABLE %s LIKE %s WITH ALL AND crc_check_chance = 0.8 AND cdc = true", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTbWithAll, false, false, false);
+
+ TableMetadata source = getTableMetadata(sourceKs, sourceTb);
+ TableMetadata target = getTableMetadata(targetKs, targetTbWithAll);
+ assertNotEquals(source.params, target.params);
+ assertTrue(target.params.cdc);
+ assertFalse(source.params.cdc);
+ assertEquals(0.8, target.params.crcCheckChance, 0.0);
+
+ String targetTbWithTrigger = createTableLike("CREATE TABLE %s LIKE %s WITH TRIGGER AND crc_check_chance = 0.8 AND cdc = true", sourceTb, sourceKs, targetKs);
+ assertTableMetaEqualsWithoutKs(sourceKs, targetKs, sourceTb, targetTbWithTrigger, false, false, false);
+
+ source = getTableMetadata(sourceKs, sourceTb);
+ target = getTableMetadata(targetKs, targetTbWithTrigger);
+ assertNotEquals(source.params, target.params);
+ assertTrue(target.params.cdc);
+ assertFalse(source.params.cdc);
+ assertEquals(0.8, target.params.crcCheckChance, 0.0);
+ }
+
+ @Test
+ public void testUnSupportedCopyofIndexAndTrigger() throws Throwable
+ {
+ createTable(sourceKs, "CREATE TABLE %s (a int PRIMARY KEY, b int, c text, d int)", "sourcetb");
+ createIndex(sourceKs, "CREATE INDEX ON %s (b)");
+ createTrigger(sourceKs, "sourcetb", "trigger_1", "CREATE TRIGGER %s ON %s USING '" + triggerClass1 + "'");
+ // ALL and TRIGGERS is not allowed
+ assertInvalidThrowMessage("It is not allowed to use ALL option together with [TRIGGER]",
+ InvalidRequestException.class,
+ "CREATE TABLE " + targetKs + ".targettb LIKE " + sourceKs + ".sourcetb WITH TRIGGER AND ALL");
+ // ALL and INDEXES is not allowed
+ assertInvalidThrowMessage("It is not allowed to use ALL option together with [INDEX]",
+ InvalidRequestException.class,
+ "CREATE TABLE " + targetKs + ".targettb LIKE " + sourceKs + ".sourcetb WITH INDEX AND ALL");
+ // ALL and INDEXES and TRIGGERS is not allowed
+ assertInvalidThrowMessage("It is not allowed to use ALL option together with [INDEX, TRIGGER]",
+ InvalidRequestException.class,
+ "CREATE TABLE " + targetKs + ".targettb LIKE " + sourceKs + ".sourcetb WITH INDEX AND TRIGGER AND ALL");
+ }
+
Review Comment:
What about, for completion, adding tests for tables without indexes and triggers that are being copied with `LIKE foo WITH INDEX/TRIGGER/ALL`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1950175525
##########
pylib/cqlshlib/test/test_cqlsh_completion.py:
##########
@@ -808,23 +808,18 @@ def test_complete_in_create_table_like(self):
'memtable',
'memtable_flush_period_in_ms',
'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
- self.trycompletions('CREATE TABLE ' + 'new_table LIKE old_table WITH ',
- choices=['allow_auto_snapshot',
- 'bloom_filter_fp_chance', 'compaction',
- 'compression',
- 'default_time_to_live', 'gc_grace_seconds',
- 'incremental_backups',
- 'max_index_interval',
- 'memtable',
- 'memtable_flush_period_in_ms',
- 'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
+ 'min_index_interval',
+ 'speculative_retry', 'additional_write_policy',
+ 'cdc', 'read_repair',
+ 'ALL'])
+ self.trycompletions('CREATE TABLE new_table LIKE old_table WITH ALL ',
+ choices=['<identifier>', '='])
Review Comment:
There will be keyword "ALL" or property after keyword "WITH" and for property ,
see
```
<propertyOrOption> ::= <property>
| "ALL" <identifier>
```
as for <property> , it is also a key value map with "=" in the middle.
So the ALL was treated as the key of " <property>"
##########
pylib/cqlshlib/test/test_cqlsh_completion.py:
##########
@@ -808,23 +808,18 @@ def test_complete_in_create_table_like(self):
'memtable',
'memtable_flush_period_in_ms',
'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
- self.trycompletions('CREATE TABLE ' + 'new_table LIKE old_table WITH ',
- choices=['allow_auto_snapshot',
- 'bloom_filter_fp_chance', 'compaction',
- 'compression',
- 'default_time_to_live', 'gc_grace_seconds',
- 'incremental_backups',
- 'max_index_interval',
- 'memtable',
- 'memtable_flush_period_in_ms',
- 'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
+ 'min_index_interval',
+ 'speculative_retry', 'additional_write_policy',
+ 'cdc', 'read_repair',
+ 'ALL'])
+ self.trycompletions('CREATE TABLE new_table LIKE old_table WITH ALL ',
+ choices=['<identifier>', '='])
Review Comment:
There will be keyword "ALL" or property after keyword "WITH" and for property ,
see
```
<propertyOrOption> ::= <property>
| "ALL" <identifier>
```
as for <property> , it is also a key value map with "=" in the middle.
So the ALL was treated as the key of "property"
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939218985
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -248,7 +278,24 @@ public CQLStatement prepare(ClientState state)
{
String oldKeyspace = oldName.hasKeyspace() ? oldName.getKeyspace() : state.getKeyspace();
String newKeyspace = newName.hasKeyspace() ? newName.getKeyspace() : state.getKeyspace();
- return new CopyTableStatement(oldKeyspace, newKeyspace, oldName.getName(), newName.getName(), ifNotExists, attrs);
+ return new CopyTableStatement(oldKeyspace, newKeyspace, oldName.getName(), newName.getName(), ifNotExists, createLikeOption, attrs);
+ }
+
+ public void setLikeOptions(CreateLikeOption likeOption)
+ {
+ this.createLikeOption = likeOption;
+ }
+ }
+
+ public enum CreateLikeOption
+ {
+ EMPTY("EMPTY"),
+ INDEX("INDEX");
Review Comment:
should be probably `INDEXES`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939248985
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
https://github.com/Maxwell-Guo/cassandra/pull/2/files
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939203114
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
+
+ if (targetKeyspaceMeta.hasIndex(indexMetadata.name))
+ {
+ throw ire("Target keyspace already has an index with the name : " + indexMetadata.name);
Review Comment:
`Target keyspace ks.tb has already an index with the name ...`
Please add there also keyspace and table
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939205681
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
Review Comment:
I would do
````
if (createLikeOption != CreateLikeOption.INDEX)
return;
...
````
By doing that, we make the number of indentation smaller etc.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "bbotella (via GitHub)" <gi...@apache.org>.
bbotella commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1949177228
##########
doc/cql3/CQL.textile:
##########
@@ -438,7 +441,7 @@ The old table name defines the already existed table.
h4(#copyTableOptions). @<copyoptions>@
-The @COPY TABLE@ statement supports a number of options that controls the configuration of a new table. These options can be specified after the @WITH@ keyword, and all options are the same as those options when creating a table except for id .
+The @COPY TABLE@ statement supports a number of options that controls the configuration of a new table. These options can be specified after the @WITH@ keyword, and all options are the same as those options when creating a table except for id .Besides the options can also be specified with keyword INDEXES which means copy source table's indexes.
Review Comment:
```suggestion
The @COPY TABLE@ statement supports a number of options that controls the configuration of a new table. These options can be specified after the @WITH@ keyword, and all options are the same as those options when creating a table except for id. Besides the options can also be specified with keyword INDEXES which means copy source table's indexes.
```
##########
pylib/cqlshlib/test/test_cqlsh_completion.py:
##########
@@ -808,23 +808,18 @@ def test_complete_in_create_table_like(self):
'memtable',
'memtable_flush_period_in_ms',
'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
- self.trycompletions('CREATE TABLE ' + 'new_table LIKE old_table WITH ',
- choices=['allow_auto_snapshot',
- 'bloom_filter_fp_chance', 'compaction',
- 'compression',
- 'default_time_to_live', 'gc_grace_seconds',
- 'incremental_backups',
- 'max_index_interval',
- 'memtable',
- 'memtable_flush_period_in_ms',
- 'caching', 'comment',
- 'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
+ 'min_index_interval',
+ 'speculative_retry', 'additional_write_policy',
+ 'cdc', 'read_repair',
+ 'ALL'])
+ self.trycompletions('CREATE TABLE new_table LIKE old_table WITH ALL ',
+ choices=['<identifier>', '='])
Review Comment:
Curious. Why `=` is a choice here?
##########
test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java:
##########
@@ -244,60 +248,59 @@ public void testCopyAfterAlterTable()
row(1, "1", duration1, uuid1));
assertRows(execute("SELECT * FROM " + targetKs + "." + targetTb),
row(2, "2", duration2, uuid2));
-
}
@Test
public void testTableOptionsCopy() throws Throwable
{
// compression
String tbCompressionDefault1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))");
- String tbCompressionDefault2 =createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'enabled' : 'false'};");
+ String tbCompressionDefault2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'enabled' : 'false'};");
String tbCompressionSnappy1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
- String tbCompressionSnappy2 =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
- String tbCompressionSnappy3 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
- String tbCompressionSnappy4 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
- String tbCompressionSnappy5 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
+ String tbCompressionSnappy2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
+ String tbCompressionSnappy3 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
+ String tbCompressionSnappy4 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
+ String tbCompressionSnappy5 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
// memtable
- String tableMemtableSkipList = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'skiplist';");
- String tableMemtableTrie = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'trie';");
- String tableMemtableDefault = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'default';");
+ String tableMemtableSkipList = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'skiplist';");
+ String tableMemtableTrie = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'trie';");
+ String tableMemtableDefault = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'default';");
// compaction
- String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
- String tableCompactionLcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
+ String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
+ String tableCompactionLcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
String tableCompactionTwcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'TimeWindowCompactionStrategy', 'min_threshold':2};");
- String tableCompactionUcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
+ String tableCompactionUcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
// other options are all different from default
String tableOtherOptions = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH" +
- " additional_write_policy = '95p' " +
- " AND bloom_filter_fp_chance = 0.1 " +
- " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
- " AND cdc = true " +
- " AND comment = 'test for create like'" +
- " AND crc_check_chance = 0.1" +
- " AND default_time_to_live = 10" +
- " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
- " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
- " AND gc_grace_seconds = 100" +
- " AND incremental_backups = false" +
- " AND max_index_interval = 1024" +
- " AND min_index_interval = 64" +
- " AND speculative_retry = '95p'" +
- " AND read_repair = 'NONE'" +
- " AND memtable_flush_period_in_ms = 360000" +
- " AND memtable = 'default';" );
+ " additional_write_policy = '95p' " +
+ " AND bloom_filter_fp_chance = 0.1 " +
+ " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
+ " AND cdc = true " +
+ " AND comment = 'test for create like'" +
+ " AND crc_check_chance = 0.1" +
+ " AND default_time_to_live = 10" +
+ " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
Review Comment:
```suggestion
" AND compaction = {'class': 'UnifiedCompactionStrategy'} " +
```
##########
test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java:
##########
@@ -244,60 +248,59 @@ public void testCopyAfterAlterTable()
row(1, "1", duration1, uuid1));
assertRows(execute("SELECT * FROM " + targetKs + "." + targetTb),
row(2, "2", duration2, uuid2));
-
}
@Test
public void testTableOptionsCopy() throws Throwable
{
// compression
String tbCompressionDefault1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))");
- String tbCompressionDefault2 =createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'enabled' : 'false'};");
+ String tbCompressionDefault2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'enabled' : 'false'};");
String tbCompressionSnappy1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
- String tbCompressionSnappy2 =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
- String tbCompressionSnappy3 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
- String tbCompressionSnappy4 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
- String tbCompressionSnappy5 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
+ String tbCompressionSnappy2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
+ String tbCompressionSnappy3 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
+ String tbCompressionSnappy4 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
+ String tbCompressionSnappy5 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
// memtable
- String tableMemtableSkipList = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'skiplist';");
- String tableMemtableTrie = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'trie';");
- String tableMemtableDefault = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'default';");
+ String tableMemtableSkipList = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'skiplist';");
+ String tableMemtableTrie = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'trie';");
+ String tableMemtableDefault = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'default';");
// compaction
- String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
- String tableCompactionLcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
+ String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
+ String tableCompactionLcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
String tableCompactionTwcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'TimeWindowCompactionStrategy', 'min_threshold':2};");
- String tableCompactionUcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
+ String tableCompactionUcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
// other options are all different from default
String tableOtherOptions = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH" +
- " additional_write_policy = '95p' " +
- " AND bloom_filter_fp_chance = 0.1 " +
- " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
- " AND cdc = true " +
- " AND comment = 'test for create like'" +
- " AND crc_check_chance = 0.1" +
- " AND default_time_to_live = 10" +
- " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
- " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
- " AND gc_grace_seconds = 100" +
- " AND incremental_backups = false" +
- " AND max_index_interval = 1024" +
- " AND min_index_interval = 64" +
- " AND speculative_retry = '95p'" +
- " AND read_repair = 'NONE'" +
- " AND memtable_flush_period_in_ms = 360000" +
- " AND memtable = 'default';" );
+ " additional_write_policy = '95p' " +
+ " AND bloom_filter_fp_chance = 0.1 " +
+ " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
+ " AND cdc = true " +
+ " AND comment = 'test for create like'" +
+ " AND crc_check_chance = 0.1" +
+ " AND default_time_to_live = 10" +
+ " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
+ " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
Review Comment:
Please review other similar extra/missing spaces
##########
test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java:
##########
@@ -244,60 +248,59 @@ public void testCopyAfterAlterTable()
row(1, "1", duration1, uuid1));
assertRows(execute("SELECT * FROM " + targetKs + "." + targetTb),
row(2, "2", duration2, uuid2));
-
}
@Test
public void testTableOptionsCopy() throws Throwable
{
// compression
String tbCompressionDefault1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))");
- String tbCompressionDefault2 =createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'enabled' : 'false'};");
+ String tbCompressionDefault2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'enabled' : 'false'};");
String tbCompressionSnappy1 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
- String tbCompressionSnappy2 =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
- String tbCompressionSnappy3 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
- String tbCompressionSnappy4 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
- String tbCompressionSnappy5 = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 };");
+ String tbCompressionSnappy2 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32, 'enabled' : true };");
+ String tbCompressionSnappy3 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 2 };");
+ String tbCompressionSnappy4 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 1 };");
+ String tbCompressionSnappy5 = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH compression = { 'class' : 'SnappyCompressor', 'min_compress_ratio' : 0 };");
// memtable
- String tableMemtableSkipList = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'skiplist';");
- String tableMemtableTrie = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'trie';");
- String tableMemtableDefault = createTable(sourceKs,"CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
- " WITH memtable = 'default';");
+ String tableMemtableSkipList = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'skiplist';");
+ String tableMemtableTrie = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'trie';");
+ String tableMemtableDefault = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" +
+ " WITH memtable = 'default';");
// compaction
- String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
- String tableCompactionLcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
+ String tableCompactionStcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':2, 'enabled':false};");
+ String tableCompactionLcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'LeveledCompactionStrategy', 'sstable_size_in_mb':1, 'fanout_size':5};");
String tableCompactionTwcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'TimeWindowCompactionStrategy', 'min_threshold':2};");
- String tableCompactionUcs =createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
+ String tableCompactionUcs = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH compaction = {'class':'UnifiedCompactionStrategy'};");
// other options are all different from default
String tableOtherOptions = createTable(sourceKs, "CREATE TABLE %s (a text, b int, c int, primary key (a, b)) WITH" +
- " additional_write_policy = '95p' " +
- " AND bloom_filter_fp_chance = 0.1 " +
- " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
- " AND cdc = true " +
- " AND comment = 'test for create like'" +
- " AND crc_check_chance = 0.1" +
- " AND default_time_to_live = 10" +
- " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
- " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
- " AND gc_grace_seconds = 100" +
- " AND incremental_backups = false" +
- " AND max_index_interval = 1024" +
- " AND min_index_interval = 64" +
- " AND speculative_retry = '95p'" +
- " AND read_repair = 'NONE'" +
- " AND memtable_flush_period_in_ms = 360000" +
- " AND memtable = 'default';" );
+ " additional_write_policy = '95p' " +
+ " AND bloom_filter_fp_chance = 0.1 " +
+ " AND caching = {'keys': 'ALL', 'rows_per_partition': '100'}" +
+ " AND cdc = true " +
+ " AND comment = 'test for create like'" +
+ " AND crc_check_chance = 0.1" +
+ " AND default_time_to_live = 10" +
+ " AND compaction = {'class':'UnifiedCompactionStrategy'} " +
+ " AND compression = { 'class' : 'SnappyCompressor', 'chunk_length_in_kb' : 32 }" +
Review Comment:
```suggestion
" AND compression = { 'class': 'SnappyCompressor', 'chunk_length_in_kb': 32 }" +
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "Maxwell-Guo (via GitHub)" <gi...@apache.org>.
Maxwell-Guo commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1937529013
##########
pylib/cqlshlib/cql3handling.py:
##########
@@ -380,6 +380,11 @@ def dequote_value(cqlword):
( ender="," [propmapkey]=<term> ":" [propmapval]=<term> )*
ender="}"
;
+<propertyOrOption> ::= <property>
Review Comment:
we may only implement INDEX OPTION now, so ~~~ there will only be one copyOption now.
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +238,56 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void maybeCopyIndexes(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption != CreateLikeOption.INDEXES || sourceTableMeta.indexes.isEmpty())
+ return;
+
+ Set<String> customIndexes = Sets.newTreeSet();
+ Set<String> alreadyExistingIndexes = Sets.newTreeSet();
+ List<IndexMetadata> indexesToCopy = new ArrayList<>();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ // only sai and legacy secondary index is supported
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM &&
+ indexMetadata.getIndexClassName() != StorageAttachedIndex.class.getCanonicalName())
Review Comment:
For this test : [sai](https://github.com/Maxwell-Guo/cassandra/blob/CASSANDRA-19965/test/unit/org/apache/cassandra/schema/createlike/CreateLikeTest.java#L598)
The index KIND seems to be CUSTOM with option of class_name : sai , So i just add the filter `indexMetadata.getIndexClassName() != StorageAttachedIndex.class.getCanonicalName()` to skip sai index.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org
Re: [PR] CREATE TABLE LIKE with INDEX/TRIGGER/ALL option [cassandra]
Posted by "smiklosovic (via GitHub)" <gi...@apache.org>.
smiklosovic commented on code in PR #3831:
URL: https://github.com/apache/cassandra/pull/3831#discussion_r1939201295
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
@Maxwell-Guo The shortcoming of this is that, imagine we have three indexes, two indexes are e.g. legacy 2i (not sai) and the third index is custom.
What you do here is that as soon as you encounter custom index, you will fail.
Imagine that `sourceTableMeta.indexes` contains these indexes:
1) first index 2i
2) second index custom
3) third index 2i
Then you add first index into the builder and you fail on the second so you will not add the third.
We have in general two options
1) iterate over `sourceTableMeta.indexes` and check if there is some custom index and if it is, we fail
2) iterate over `sourceTableMeta.indexes` and if there is a custom index, we will just skip it. That means that all non-custom indexes will be still created.
##########
src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:
##########
@@ -229,12 +234,37 @@ public void validate(ClientState state)
validateDefaultTimeToLive(attrs.asNewTableParams());
}
+ private void cloneIndexesIfNeeded(TableMetadata.Builder builder, TableMetadata sourceTableMeta, KeyspaceMetadata targetKeyspaceMeta)
+ {
+ if (createLikeOption == CreateLikeOption.INDEX)
+ {
+ Indexes.Builder idxBuilder = Indexes.builder();
+ for (IndexMetadata indexMetadata : sourceTableMeta.indexes)
+ {
+ if (indexMetadata.kind == IndexMetadata.Kind.CUSTOM)
+ throw ire("CUSTOM INDEX is not supported.");
Review Comment:
@Maxwell-Guo The shortcoming of this is that, imagine we have three indexes, two indexes are e.g. legacy 2i (not sai) and the third index is custom.
What you do here is that as soon as you encounter custom index, you will fail.
Imagine that `sourceTableMeta.indexes` contains these indexes:
1) first index 2i
2) second index custom
3) third index 2i
Then you add the first index into the builder and you fail on the second so you will not add the third.
We have in general two options
1) iterate over `sourceTableMeta.indexes` and check if there is some custom index and if it is, we fail
2) iterate over `sourceTableMeta.indexes` and if there is a custom index, we will just skip it. That means that all non-custom indexes will be still created.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscribe@cassandra.apache.org
For additional commands, e-mail: pr-help@cassandra.apache.org