rpuch commented on code in PR #2485: URL: https://github.com/apache/ignite-3/pull/2485#discussion_r1302843333
########## modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogManagerImpl.java: ########## @@ -965,7 +936,25 @@ public void listen(CatalogEvent evt, EventListener<? extends CatalogEventParamet listen(evt, (EventListener<CatalogEventParameters>) closure); } - private static @Nullable CatalogDataStorageDescriptor dataStorage(@Nullable DataStorageParams params) { - return params == null ? null : fromParams(params); + private static void checkNotExistsIndexOrTable(CatalogSchemaDescriptor schema, String indexName) { Review Comment: The method name violates English grammar. How about `checkNeitherTableNorIndexExists`? ########## modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractCreateIndexCommandParams.java: ########## @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.commands; + +import java.util.List; + +/** Abstract create index ddl command. */ +public abstract class AbstractCreateIndexCommandParams extends AbstractIndexCommandParams { + /** Table name. */ + protected String tableName; + + /** Unique index flag. */ + protected boolean unique; + + /** Indexed columns. */ + protected List<String> columns; + + /** Returns table name. */ + public String tableName() { + return tableName; + } + + /** Returns {@code true} if index is unique, {@code false} otherwise. */ + public boolean unique() { + return unique; + } + + /** Returns index columns. */ + public List<String> columns() { + return columns; + } + + /** Parameters builder. */ + protected abstract static class AbstractCreateIndexBuilder<ParamT extends AbstractCreateIndexCommandParams, BuilderT> extends Review Comment: If I'm not mistaken, type variables should be one letter, not many, when possible. How about `<P, B>`? ########## modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractCreateIndexCommandParams.java: ########## @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.commands; + +import java.util.List; + +/** Abstract create index ddl command. */ +public abstract class AbstractCreateIndexCommandParams extends AbstractIndexCommandParams { + /** Table name. */ + protected String tableName; + + /** Unique index flag. */ + protected boolean unique; + + /** Indexed columns. */ + protected List<String> columns; + + /** Returns table name. */ + public String tableName() { + return tableName; + } + + /** Returns {@code true} if index is unique, {@code false} otherwise. */ + public boolean unique() { + return unique; + } + + /** Returns index columns. */ + public List<String> columns() { + return columns; + } + + /** Parameters builder. */ + protected abstract static class AbstractCreateIndexBuilder<ParamT extends AbstractCreateIndexCommandParams, BuilderT> extends + AbstractIndexBuilder<ParamT, BuilderT> { + AbstractCreateIndexBuilder(ParamT params) { + super(params); + } + + /** + * Set table name. + * + * @param tableName Table name. + * @return {@code this}. + */ + public BuilderT tableName(String tableName) { + params.tableName = tableName; + + return (BuilderT) this; + } + + /** + * Sets unique flag. + * + * @return {@code this}. + */ + public BuilderT unique() { + params.unique = true; + + return (BuilderT) this; + } + + /** + * Set columns names. + * + * @param columns Columns names. + * @return {@code this}. + */ + public BuilderT columns(List<String> columns) { + params.columns = columns; Review Comment: How about making a defensive copy? Creating an index is not something that happens a million times per second, so an extra copy of the collection is not a problem, but this might make it easier to reason about this code when we debug it. ########## modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractCreateIndexCommandParams.java: ########## @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.commands; + +import java.util.List; + +/** Abstract create index ddl command. */ +public abstract class AbstractCreateIndexCommandParams extends AbstractIndexCommandParams { + /** Table name. */ + protected String tableName; + + /** Unique index flag. */ + protected boolean unique; + + /** Indexed columns. */ + protected List<String> columns; + + /** Returns table name. */ + public String tableName() { + return tableName; + } + + /** Returns {@code true} if index is unique, {@code false} otherwise. */ + public boolean unique() { + return unique; + } + + /** Returns index columns. */ + public List<String> columns() { + return columns; + } + + /** Parameters builder. */ + protected abstract static class AbstractCreateIndexBuilder<ParamT extends AbstractCreateIndexCommandParams, BuilderT> extends + AbstractIndexBuilder<ParamT, BuilderT> { + AbstractCreateIndexBuilder(ParamT params) { + super(params); + } + + /** + * Set table name. + * + * @param tableName Table name. + * @return {@code this}. + */ + public BuilderT tableName(String tableName) { + params.tableName = tableName; + + return (BuilderT) this; Review Comment: This expression can be extracted to a method like ``` private BuilderT self() { return (BuilderT) this; } ``` so that it looks like `return self()` in all the setters, hiding the technical detail of casting ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerSelfTest.java: ########## @@ -1918,6 +1890,85 @@ void testCreateZoneWithDefaults() { assertEquals(DEFAULT_DATA_REGION, zone.dataStorage().dataRegion()); } + @Test + void testCreateAlreadyExistsIndex() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + assertThat(manager.createIndex(simpleIndex(INDEX_NAME, TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of("VAL"))), + willThrowFast(IndexAlreadyExistsException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(IndexAlreadyExistsException.class) + ); + } + + @Test + void testCreateIndexWithSameTableName() { Review Comment: ```suggestion void testCreateIndexWithSameNameAsExistingTable() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerSelfTest.java: ########## @@ -1918,6 +1890,85 @@ void testCreateZoneWithDefaults() { assertEquals(DEFAULT_DATA_REGION, zone.dataStorage().dataRegion()); } + @Test + void testCreateAlreadyExistsIndex() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + assertThat(manager.createIndex(simpleIndex(INDEX_NAME, TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of("VAL"))), + willThrowFast(IndexAlreadyExistsException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(IndexAlreadyExistsException.class) + ); + } + + @Test + void testCreateIndexWithSameTableName() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(TABLE_NAME, List.of("VAL"))), + willThrowFast(TableAlreadyExistsException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(TABLE_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(TableAlreadyExistsException.class) + ); + } + + @Test + void testCreateIndexWithNotExistsTable() { + assertThat( + manager.createIndex(createHashIndexParams(TABLE_NAME, List.of("VAL"))), + willThrowFast(TableNotFoundException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(TABLE_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(TableNotFoundException.class) + ); + } + + @Test + void testCreateIndexWithMissingTableColumns() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of("fake"))), + willThrowFast(ColumnNotFoundException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("fake"), List.of(ASC_NULLS_LAST))), + willThrowFast(ColumnNotFoundException.class) + ); + } + + @Test + void testCreateUniqIndexWithMissingTableColocationColumns() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, true, List.of("VAL"))), + willThrowFast(IgniteException.class, "Unique index must include all colocation columns") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, true, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(IgniteException.class, "Unique index must include all colocation columns") + ); + } + + @Test + void testDropNotExistsIndex() { Review Comment: ```suggestion void testDropNotExistingIndex() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsNotSpecifiedOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, null, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of())), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of(), null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + } + + @Test + void testValidateIndexColumnsContainsNullOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsContainingNullOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexNameOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerSelfTest.java: ########## @@ -1918,6 +1890,85 @@ void testCreateZoneWithDefaults() { assertEquals(DEFAULT_DATA_REGION, zone.dataStorage().dataRegion()); } + @Test + void testCreateAlreadyExistsIndex() { Review Comment: ```suggestion void testCreateIndexWithAlreadyExistingName() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, null, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of())), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of(), null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + } + + @Test + void testValidateIndexColumnsContainsNullOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", null))), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", null), null)), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + } + + @Test + void testValidateIndexColumnsDuplicatesOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", "key"))), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", "key"), null)), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + } + + @Test + void testValidateIndexColumnsCollationsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("key"), null)), + willThrowFast(CatalogValidationException.class, "Columns collations not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("key"), List.of())), + willThrowFast(CatalogValidationException.class, "Columns collations not specified") + ); + } + + @Test + void testValidateIndexColumnsCollationsContainsNullOnIndexCreate() { + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("key", "val"), Arrays.asList(ASC_NULLS_FIRST, null))), + willThrowFast(CatalogValidationException.class, "One of the columns collations is null") + ); + } + + @Test + void testValidateIndexColumnsCollationsNotScameSizeWithColumnsOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsCollationsNotScameSizeWithColumnsOnIndexCreation() { ``` ########## modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractIndexCommandParams.java: ########## @@ -17,57 +17,32 @@ package org.apache.ignite.internal.catalog.commands; -/** - * Abstract index ddl command. - */ +import org.jetbrains.annotations.Nullable; + +/** Abstract create index ddl command. */ public abstract class AbstractIndexCommandParams implements DdlCommandParams { /** Index name. */ protected String indexName; - /** Schema name where this new index will be created. */ - protected String schema; - - /** Table name. */ - protected String tableName; - - /** Unique index flag. */ - protected boolean unique; + /** Schema name. */ + protected @Nullable String schemaName; - /** - * Returns index simple name. - */ + /** Returns index name. */ public String indexName() { return indexName; } - /** - * Returns schema name. - */ - public String schemaName() { - return schema; + /** Returns schema name. */ + public @Nullable String schemaName() { Review Comment: Can there be a table (and hence index) without a schema? ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, null, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of())), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of(), null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + } + + @Test + void testValidateIndexColumnsContainsNullOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", null))), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", null), null)), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + } + + @Test + void testValidateIndexColumnsDuplicatesOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", "key"))), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", "key"), null)), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + } + + @Test + void testValidateIndexColumnsCollationsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("key"), null)), + willThrowFast(CatalogValidationException.class, "Columns collations not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("key"), List.of())), + willThrowFast(CatalogValidationException.class, "Columns collations not specified") + ); + } + + @Test + void testValidateIndexColumnsCollationsContainsNullOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsCollationsContainNullOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { Review Comment: ```suggestion void testValidateTableNameOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerSelfTest.java: ########## @@ -1918,6 +1890,85 @@ void testCreateZoneWithDefaults() { assertEquals(DEFAULT_DATA_REGION, zone.dataStorage().dataRegion()); } + @Test + void testCreateAlreadyExistsIndex() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + assertThat(manager.createIndex(simpleIndex(INDEX_NAME, TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of("VAL"))), + willThrowFast(IndexAlreadyExistsException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(IndexAlreadyExistsException.class) + ); + } + + @Test + void testCreateIndexWithSameTableName() { + assertThat(manager.createTable(simpleTable(TABLE_NAME)), willCompleteSuccessfully()); + + assertThat( + manager.createIndex(createHashIndexParams(TABLE_NAME, List.of("VAL"))), + willThrowFast(TableAlreadyExistsException.class) + ); + + assertThat( + manager.createIndex(createSortedIndexParams(TABLE_NAME, List.of("VAL"), List.of(ASC_NULLS_LAST))), + willThrowFast(TableAlreadyExistsException.class) + ); + } + + @Test + void testCreateIndexWithNotExistsTable() { Review Comment: ```suggestion void testCreateIndexWithNotExistingTable() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, null, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of())), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of(), null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + } + + @Test + void testValidateIndexColumnsContainsNullOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", null))), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", null), null)), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + } + + @Test + void testValidateIndexColumnsDuplicatesOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsDuplicatesOnIndexCreation() { ``` ########## modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogManagerValidationTest.java: ########## @@ -550,6 +557,118 @@ void testValidateZoneNamesOnRenameZone() { ); } + @Test + void testValidateTableNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).indexName(INDEX_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing table name") + ); + } + + @Test + void testValidateIndexNameOnIndexCreate() { + assertThat( + manager.createIndex(CreateHashIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + + assertThat( + manager.createIndex(CreateSortedIndexParams.builder().schemaName(DEFAULT_SCHEMA_NAME).tableName(TABLE_NAME).build()), + willThrowFast(CatalogValidationException.class, "Missing index name") + ); + } + + @Test + void testValidateIndexColumnsNotSpecifiedOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, null, null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, List.of())), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, List.of(), null)), + willThrowFast(CatalogValidationException.class, "Columns not specified") + ); + } + + @Test + void testValidateIndexColumnsContainsNullOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", null))), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", null), null)), + willThrowFast(CatalogValidationException.class, "One of the columns is null") + ); + } + + @Test + void testValidateIndexColumnsDuplicatesOnIndexCreate() { + assertThat( + manager.createIndex(createHashIndexParams(INDEX_NAME, Arrays.asList("key", "key"))), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + + assertThat( + manager.createIndex(createSortedIndexParams(INDEX_NAME, Arrays.asList("key", "key"), null)), + willThrowFast(CatalogValidationException.class, "Duplicate columns are present") + ); + } + + @Test + void testValidateIndexColumnsCollationsNotSpecifiedOnIndexCreate() { Review Comment: ```suggestion void testValidateIndexColumnsCollationsNotSpecifiedOnIndexCreation() { ``` -- 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: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org