rpuch commented on code in PR #2680:
URL: https://github.com/apache/ignite-3/pull/2680#discussion_r1356237135


##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/IndexNotFoundValidationException.java:
##########
@@ -18,9 +18,9 @@
 package org.apache.ignite.internal.catalog;
 
 /**
- * This exception is thrown when index that going to be deleted not found in 
the schema.
+ * This exception is thrown when index not found in the schema.

Review Comment:
   ```suggestion
    * This exception is thrown when an index is not found in the schema.
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/IndexAlreadyAvailableValidationException.java:
##########
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+
+/**
+ * This exception is thrown when an attempt is made to make the index 
available a second time

Review Comment:
   ```suggestion
    * This exception is thrown when an attempt is made to make an index 
available a second time
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java:
##########
@@ -363,4 +365,22 @@ static CatalogZoneDescriptor zoneOrThrow(Catalog catalog, 
String name) throws Ca
     public static String pkIndexName(String tableName) {
         return tableName + "_PK";
     }
+
+    /**
+     * Returns index with given name.
+     *
+     * @param schema Schema to look up index in.
+     * @param name Name of the index of interest.
+     * @return Table with given name.
+     * @throws IndexNotFoundValidationException If index with given name is 
not exists.
+     */
+    static CatalogIndexDescriptor indexOrThrow(CatalogSchemaDescriptor schema, 
String name) throws IndexNotFoundValidationException {

Review Comment:
   How about moving this method to `CatalogSchemaDescriptor`?



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java:
##########
@@ -363,4 +365,22 @@ static CatalogZoneDescriptor zoneOrThrow(Catalog catalog, 
String name) throws Ca
     public static String pkIndexName(String tableName) {
         return tableName + "_PK";
     }
+
+    /**
+     * Returns index with given name.
+     *
+     * @param schema Schema to look up index in.
+     * @param name Name of the index of interest.
+     * @return Table with given name.
+     * @throws IndexNotFoundValidationException If index with given name is 
not exists.
+     */
+    static CatalogIndexDescriptor indexOrThrow(CatalogSchemaDescriptor schema, 
String name) throws IndexNotFoundValidationException {
+        CatalogIndexDescriptor index = schema.index(name);
+
+        if (index == null) {
+            throw new IndexNotFoundValidationException(format("Index with name 
'{}.{}' not found", schema.name(), name));

Review Comment:
   It looks like this method can be used not only in the context where we 
validate something, but it throws a validation exception. Can the exception 
type be generalized? Or the method renamed (or at least documented) that it's 
just for validation phase?



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogIndexDescriptor.java:
##########
@@ -52,19 +51,11 @@ public boolean unique() {
         return unique;
     }
 
+    /** Returns the state of the index, {@code true} when index is building, 
{@code false} when the index is built. */

Review Comment:
   ```suggestion
       /** Returns the state of the index, {@code true} when the index is being 
built, {@code false} when it is built. */
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/MakeIndexAvailableEntry.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * 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.storage;
+
+import java.util.Arrays;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.commands.CatalogUtils;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
+import org.apache.ignite.internal.catalog.events.AvailableIndexEventParameters;
+import org.apache.ignite.internal.catalog.events.CatalogEvent;
+import org.apache.ignite.internal.catalog.events.CatalogEventParameters;
+
+/** Describes making an index read-write. */
+public class MakeIndexAvailableEntry implements UpdateEntry, Fireable {
+    private static final long serialVersionUID = -5686678143537999594L;
+
+    private final String schemaName;
+
+    private final CatalogIndexDescriptor descriptor;
+
+    /** Constructor. */
+    public MakeIndexAvailableEntry(String schemaName, CatalogIndexDescriptor 
descriptor) {
+        this.schemaName = schemaName;
+        this.descriptor = descriptor;
+    }
+
+    @Override
+    public Catalog applyUpdate(Catalog catalog, long causalityToken) {

Review Comment:
   This method implementation is not specific to making an index available: it 
just replaces the current descriptor with a new one. Would it make sense to 
extract it to a static method (or use subclassing) in the light of more 'index 
modification' commands that are going to be added next?



##########
modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/MakeIndexAvailableCommandValidationTest.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * 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 static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
+
+import java.util.List;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.CatalogCommand;
+import org.apache.ignite.internal.catalog.CatalogValidationException;
+import 
org.apache.ignite.internal.catalog.IndexAlreadyAvailableValidationException;
+import org.apache.ignite.internal.catalog.IndexNotFoundValidationException;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogSystemViewDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/** Tests to verify validation of {@link MakeIndexAvailableCommand}. */
+@SuppressWarnings("ThrowableNotThrown")
+public class MakeIndexAvailableCommandValidationTest extends 
AbstractCommandValidationTest {
+    @ParameterizedTest(name = "[{index}] ''{argumentsWithNames}''")
+    @MethodSource("nullAndBlankStrings")
+    void schemaNameMustNotBeNullOrBlank(String name) {
+        MakeIndexAvailableCommandBuilder builder = 
MakeIndexAvailableCommand.builder();
+
+        builder.indexName("TEST").schemaName(name);
+
+        assertThrowsWithCause(
+                builder::build,
+                CatalogValidationException.class,
+                "Name of the schema can't be null or blank"
+        );
+    }
+
+    @ParameterizedTest(name = "[{index}] ''{argumentsWithNames}''")
+    @MethodSource("nullAndBlankStrings")
+    void indexNameMustNotBeNullOrBlank(String name) {
+        MakeIndexAvailableCommandBuilder builder = 
MakeIndexAvailableCommand.builder();
+
+        builder.schemaName(SCHEMA_NAME).indexName(name);
+
+        assertThrowsWithCause(
+                builder::build,
+                CatalogValidationException.class,
+                "Name of the index can't be null or blank"
+        );
+    }
+
+    @Test
+    void exceptionIsThrownIfIndexWithGivenNameNotFound() {
+        Catalog catalog = emptyCatalog();
+
+        CatalogCommand command = MakeIndexAvailableCommand.builder()
+                .schemaName(SCHEMA_NAME)
+                .indexName("TEST")
+                .build();
+
+        assertThrowsWithCause(
+                () -> command.get(catalog),
+                IndexNotFoundValidationException.class,
+                "Index with name 'PUBLIC.TEST' not found"
+        );
+    }
+
+    @Test
+    void exceptionIsThrownIfIndexAlreadyAvailable() {

Review Comment:
   ```suggestion
       void exceptionIsThrownIfIndexIsAlreadyAvailable() {
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/MakeIndexAvailableCommandBuilder.java:
##########
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+/** Builder {@link MakeIndexAvailableCommand}. */

Review Comment:
   ```suggestion
   /** Builder for {@link MakeIndexAvailableCommand}. */
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/MakeIndexAvailableCommand.java:
##########
@@ -0,0 +1,130 @@
+/*
+ * 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 static 
org.apache.ignite.internal.catalog.commands.CatalogUtils.indexOrThrow;
+import static 
org.apache.ignite.internal.catalog.commands.CatalogUtils.schemaOrThrow;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
+import java.util.List;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.CatalogCommand;
+import org.apache.ignite.internal.catalog.CatalogValidationException;
+import 
org.apache.ignite.internal.catalog.IndexAlreadyAvailableValidationException;
+import org.apache.ignite.internal.catalog.IndexNotFoundValidationException;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogSortedIndexDescriptor;
+import org.apache.ignite.internal.catalog.storage.MakeIndexAvailableEntry;
+import org.apache.ignite.internal.catalog.storage.UpdateEntry;
+
+/**
+ * Makes the index available for read-write, switches from the write-only to 
the read-write state in catalog.

Review Comment:
   ```suggestion
    * Makes the index available for read-write, switches from the write-only to 
the read-write state in the catalog.
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/IndexNotFoundValidationException.java:
##########
@@ -18,9 +18,9 @@
 package org.apache.ignite.internal.catalog;
 
 /**
- * This exception is thrown when index that going to be deleted not found in 
the schema.
+ * This exception is thrown when index not found in the schema.
  *
- * <p>This exception is used to properly handle IF EXISTS flag in ddl command 
handler.
+ * <p>Example: This exception is used to properly handle IF EXISTS flag in ddl 
command handler.</p>

Review Comment:
   Do we really need that trailing `</p>` ?



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogIndexDescriptor.java:
##########
@@ -33,13 +31,14 @@ public abstract class CatalogIndexDescriptor extends 
CatalogObjectDescriptor {
     /** Unique constraint flag. */
     private final boolean unique;
 
-    /** Write only flag. {@code True} when index is building. */
-    private boolean writeOnly;
+    /** Write only flag. {@code True} when index is building, {@code false} 
when the index is built. */

Review Comment:
   ```suggestion
       /** Write only flag. {@code True} when the index is being built, {@code 
false} when it is built. */
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogHashIndexDescriptor.java:
##########
@@ -37,10 +35,11 @@ public class CatalogHashIndexDescriptor extends 
CatalogIndexDescriptor {
      * @param tableId Id of the table index belongs to.
      * @param unique Unique flag.
      * @param columns A list of indexed columns. Must not contains duplicates.
+     * @param writeOnly State of the index, {@code true} when index is 
building, {@code false} when the index is built.
      * @throws IllegalArgumentException If columns list contains duplicates.
      */
-    public CatalogHashIndexDescriptor(int id, String name, int tableId, 
boolean unique, List<String> columns) {
-        super(id, name, tableId, unique);
+    public CatalogHashIndexDescriptor(int id, String name, int tableId, 
boolean unique, List<String> columns, boolean writeOnly) {
+        super(id, name, tableId, unique, writeOnly);

Review Comment:
   How about adding a constructor with the old set of parameters (without 
`writeOnly` flag) that would delegate to the new constructor with always 
passing `true` for `writeOnly`? This would create an index in its initial state 
(which is write only), it seems pretty natural, and we would have less 
syntactic noise.



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/MakeIndexAvailableEntry.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * 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.storage;
+
+import java.util.Arrays;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.commands.CatalogUtils;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
+import org.apache.ignite.internal.catalog.events.AvailableIndexEventParameters;
+import org.apache.ignite.internal.catalog.events.CatalogEvent;
+import org.apache.ignite.internal.catalog.events.CatalogEventParameters;
+
+/** Describes making an index read-write. */

Review Comment:
   The class calls this 'available', but the javadoc says about 'read-write'. 
This is a little confusing. Is it possible to use the same terminology in the 
code, and not 2 terminologies at the same time?



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/AvailableIndexEventParameters.java:
##########
@@ -0,0 +1,41 @@
+/*
+ * 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.events;
+
+/** {@link CatalogEvent#INDEX_AVAILABLE} event parameters. */
+public class AvailableIndexEventParameters extends CatalogEventParameters {

Review Comment:
   Wouldn't `MakeIndexAvailableEventParameters` align better with the current 
practice of using the verb first, like `CreateIndexEventParameters`?



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogSortedIndexDescriptor.java:
##########
@@ -38,25 +36,27 @@ public class CatalogSortedIndexDescriptor extends 
CatalogIndexDescriptor {
      * @param tableId Id of the table index belongs to.
      * @param unique Unique flag.
      * @param columns A list of columns descriptors.
+     * @param writeOnly State of the index, {@code true} when index is 
building, {@code false} when the index is built.
      * @throws IllegalArgumentException If columns list contains duplicates or 
columns size doesn't match the collations size.
      */
-    public CatalogSortedIndexDescriptor(int id, String name, int tableId, 
boolean unique, List<CatalogIndexColumnDescriptor> columns) {
-        super(id, name, tableId, unique);
+    public CatalogSortedIndexDescriptor(

Review Comment:
   Same suggestion about a constructor overload



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/AvailableIndexEventParameters.java:
##########
@@ -0,0 +1,41 @@
+/*
+ * 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.events;
+
+/** {@link CatalogEvent#INDEX_AVAILABLE} event parameters. */

Review Comment:
   Should we explicitly state in the javadoc of this class that this event is 
fired when the index becomes available for the SQL engine?



##########
modules/catalog/src/test/java/org/apache/ignite/internal/catalog/commands/MakeIndexAvailableCommandValidationTest.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * 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 static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
+
+import java.util.List;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.CatalogCommand;
+import org.apache.ignite.internal.catalog.CatalogValidationException;
+import 
org.apache.ignite.internal.catalog.IndexAlreadyAvailableValidationException;
+import org.apache.ignite.internal.catalog.IndexNotFoundValidationException;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogSystemViewDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/** Tests to verify validation of {@link MakeIndexAvailableCommand}. */
+@SuppressWarnings("ThrowableNotThrown")
+public class MakeIndexAvailableCommandValidationTest extends 
AbstractCommandValidationTest {
+    @ParameterizedTest(name = "[{index}] ''{argumentsWithNames}''")
+    @MethodSource("nullAndBlankStrings")
+    void schemaNameMustNotBeNullOrBlank(String name) {
+        MakeIndexAvailableCommandBuilder builder = 
MakeIndexAvailableCommand.builder();
+
+        builder.indexName("TEST").schemaName(name);
+
+        assertThrowsWithCause(
+                builder::build,
+                CatalogValidationException.class,
+                "Name of the schema can't be null or blank"
+        );
+    }
+
+    @ParameterizedTest(name = "[{index}] ''{argumentsWithNames}''")
+    @MethodSource("nullAndBlankStrings")
+    void indexNameMustNotBeNullOrBlank(String name) {
+        MakeIndexAvailableCommandBuilder builder = 
MakeIndexAvailableCommand.builder();
+
+        builder.schemaName(SCHEMA_NAME).indexName(name);
+
+        assertThrowsWithCause(
+                builder::build,
+                CatalogValidationException.class,
+                "Name of the index can't be null or blank"
+        );
+    }
+
+    @Test
+    void exceptionIsThrownIfIndexWithGivenNameNotFound() {
+        Catalog catalog = emptyCatalog();
+
+        CatalogCommand command = MakeIndexAvailableCommand.builder()
+                .schemaName(SCHEMA_NAME)
+                .indexName("TEST")
+                .build();
+
+        assertThrowsWithCause(
+                () -> command.get(catalog),
+                IndexNotFoundValidationException.class,
+                "Index with name 'PUBLIC.TEST' not found"
+        );
+    }
+
+    @Test
+    void exceptionIsThrownIfIndexAlreadyAvailable() {
+        String indexName = "TEST";
+
+        Catalog catalog = catalog(
+                new CatalogTableDescriptor[]{},
+                new CatalogIndexDescriptor[]{
+                        new CatalogHashIndexDescriptor(10, indexName, 1, 
false, List.of("c"), false)
+                },
+                new CatalogSystemViewDescriptor[]{}
+        );
+
+        CatalogCommand command = MakeIndexAvailableCommand.builder()
+                .schemaName(SCHEMA_NAME)
+                .indexName(indexName)
+                .build();
+
+        assertThrowsWithCause(
+                () -> command.get(catalog),
+                IndexAlreadyAvailableValidationException.class,
+                "Index already available 'PUBLIC.TEST'"

Review Comment:
   ```suggestion
                   "Index is already available 'PUBLIC.TEST'"
   ```



##########
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/MakeIndexAvailableCommand.java:
##########
@@ -0,0 +1,130 @@
+/*
+ * 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 static 
org.apache.ignite.internal.catalog.commands.CatalogUtils.indexOrThrow;
+import static 
org.apache.ignite.internal.catalog.commands.CatalogUtils.schemaOrThrow;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
+import java.util.List;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.catalog.CatalogCommand;
+import org.apache.ignite.internal.catalog.CatalogValidationException;
+import 
org.apache.ignite.internal.catalog.IndexAlreadyAvailableValidationException;
+import org.apache.ignite.internal.catalog.IndexNotFoundValidationException;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.CatalogSchemaDescriptor;
+import 
org.apache.ignite.internal.catalog.descriptors.CatalogSortedIndexDescriptor;
+import org.apache.ignite.internal.catalog.storage.MakeIndexAvailableEntry;
+import org.apache.ignite.internal.catalog.storage.UpdateEntry;
+
+/**
+ * Makes the index available for read-write, switches from the write-only to 
the read-write state in catalog.
+ *
+ * @see CatalogIndexDescriptor#writeOnly()
+ * @see IndexNotFoundValidationException
+ * @see IndexAlreadyAvailableValidationException
+ */
+public class MakeIndexAvailableCommand extends AbstractIndexCommand {
+    /** Returns builder to make an index available for read-write. */
+    public static MakeIndexAvailableCommandBuilder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param schemaName Schema name.
+     * @param indexName Index name.
+     * @throws CatalogValidationException If any of the parameters fails 
validation.
+     */
+    private MakeIndexAvailableCommand(String schemaName, String indexName) 
throws CatalogValidationException {
+        super(schemaName, indexName);
+    }
+
+    @Override
+    public List<UpdateEntry> get(Catalog catalog) {
+        CatalogSchemaDescriptor schema = schemaOrThrow(catalog, schemaName);
+
+        CatalogIndexDescriptor index = indexOrThrow(schema, indexName);
+
+        if (!index.writeOnly()) {
+            throw new IndexAlreadyAvailableValidationException(format("Index 
already available '{}.{}'", schemaName, indexName));

Review Comment:
   ```suggestion
               throw new IndexAlreadyAvailableValidationException(format("Index 
is already available '{}.{}'", schemaName, indexName));
   ```



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to