This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-19460
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit 59e66e2156a947c09fead9e6adf11f47fc802df7
Author: amashenkov <[email protected]>
AuthorDate: Wed May 17 22:39:25 2023 +0300

    Add create index command.
    Add drop index command.
---
 .../ignite/internal/catalog/CatalogManager.java    |  18 ++++
 .../internal/catalog/CatalogServiceImpl.java       |  53 +++++++++++
 ...Params.java => AbstractIndexCommandParams.java} |  51 ++++-------
 .../commands/AbstractTableCommandParams.java       |  31 ++-----
 .../internal/catalog/commands/CatalogUtils.java    |  33 +++++++
 .../catalog/commands/CreateIndexParams.java        |  94 +++++++++++++++++++
 .../internal/catalog/commands/DropIndexParams.java |  36 ++++++++
 .../internal/catalog/storage/DropIndexEntry.java   |  49 ++++++++++
 .../internal/catalog/storage/NewIndexEntry.java    | 101 +++++++++++++++++++++
 .../engine/exec/ddl/DdlCommandHandlerWrapper.java  |  14 +++
 .../exec/ddl/DdlToCatalogCommandConverter.java     |  45 +++++++++
 11 files changed, 469 insertions(+), 56 deletions(-)

diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogManager.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogManager.java
index 2724d5d965..72da2432d1 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogManager.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogManager.java
@@ -20,7 +20,9 @@ package org.apache.ignite.internal.catalog;
 import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.internal.catalog.commands.AlterTableAddColumnParams;
 import org.apache.ignite.internal.catalog.commands.AlterTableDropColumnParams;
+import org.apache.ignite.internal.catalog.commands.CreateIndexParams;
 import org.apache.ignite.internal.catalog.commands.CreateTableParams;
+import org.apache.ignite.internal.catalog.commands.DropIndexParams;
 import org.apache.ignite.internal.catalog.commands.DropTableParams;
 import org.apache.ignite.internal.manager.IgniteComponent;
 
@@ -59,4 +61,20 @@ public interface CatalogManager extends IgniteComponent, 
CatalogService {
      * @return Operation future.
      */
     CompletableFuture<Void> dropColumn(AlterTableDropColumnParams params);
+
+    /**
+     * Creates new index.
+     *
+     * @param params Parameters.
+     * @return Operation future.
+     */
+    CompletableFuture<Void> createIndex(CreateIndexParams params);
+
+    /**
+     * Drops index.
+     *
+     * @param params Parameters.
+     * @return Operation future.
+     */
+    CompletableFuture<Void> dropIndex(DropIndexParams params);
 }
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java
index 4920647d4a..781df21e99 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java
@@ -32,7 +32,9 @@ import java.util.concurrent.ConcurrentSkipListMap;
 import org.apache.ignite.internal.catalog.commands.AlterTableAddColumnParams;
 import org.apache.ignite.internal.catalog.commands.AlterTableDropColumnParams;
 import org.apache.ignite.internal.catalog.commands.CatalogUtils;
+import org.apache.ignite.internal.catalog.commands.CreateIndexParams;
 import org.apache.ignite.internal.catalog.commands.CreateTableParams;
+import org.apache.ignite.internal.catalog.commands.DropIndexParams;
 import org.apache.ignite.internal.catalog.commands.DropTableParams;
 import org.apache.ignite.internal.catalog.descriptors.IndexDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.SchemaDescriptor;
@@ -41,7 +43,9 @@ import org.apache.ignite.internal.catalog.events.CatalogEvent;
 import org.apache.ignite.internal.catalog.events.CatalogEventParameters;
 import org.apache.ignite.internal.catalog.events.CreateTableEventParameters;
 import org.apache.ignite.internal.catalog.events.DropTableEventParameters;
+import org.apache.ignite.internal.catalog.storage.DropIndexEntry;
 import org.apache.ignite.internal.catalog.storage.DropTableEntry;
+import org.apache.ignite.internal.catalog.storage.NewIndexEntry;
 import org.apache.ignite.internal.catalog.storage.NewTableEntry;
 import org.apache.ignite.internal.catalog.storage.ObjectIdGenUpdateEntry;
 import org.apache.ignite.internal.catalog.storage.UpdateEntry;
@@ -55,6 +59,8 @@ import org.apache.ignite.internal.util.ArrayUtils;
 import org.apache.ignite.internal.util.PendingComparableValuesTracker;
 import org.apache.ignite.lang.ErrorGroups.Common;
 import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IndexAlreadyExistsException;
+import org.apache.ignite.lang.IndexNotFoundException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
 import org.apache.ignite.lang.TableNotFoundException;
 import org.jetbrains.annotations.Nullable;
@@ -214,6 +220,53 @@ public class CatalogServiceImpl extends 
Producer<CatalogEvent, CatalogEventParam
         return failedFuture(new UnsupportedOperationException("Not implemented 
yet."));
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public CompletableFuture<Void> createIndex(CreateIndexParams params) {
+        return saveUpdate(catalog -> {
+            String schemaName = 
Objects.requireNonNullElse(params.schemaName(), CatalogService.PUBLIC);
+
+            SchemaDescriptor schema = 
Objects.requireNonNull(catalog.schema(schemaName), "No schema found: " + 
schemaName);
+
+            if (schema.index(params.indexName()) != null) {
+                throw new IndexAlreadyExistsException(schemaName, 
params.indexName());
+            }
+
+            TableDescriptor table = schema.table(params.tableName());
+
+            if (table == null) {
+                throw new TableNotFoundException(schemaName, 
params.tableName());
+            }
+
+            IndexDescriptor index = 
CatalogUtils.fromParams(catalog.objectIdGenState(), table.id(), params);
+
+            return List.of(
+                    new NewIndexEntry(index),
+                    new ObjectIdGenUpdateEntry(1)
+            );
+        });
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public CompletableFuture<Void> dropIndex(DropIndexParams params) {
+        return saveUpdate(catalog -> {
+            String schemaName = 
Objects.requireNonNullElse(params.schemaName(), CatalogService.PUBLIC);
+
+            SchemaDescriptor schema = 
Objects.requireNonNull(catalog.schema(schemaName), "No schema found: " + 
schemaName);
+
+            IndexDescriptor index = schema.index(params.indexName());
+
+            if (index == null) {
+                throw new IndexNotFoundException(schemaName, 
params.indexName());
+            }
+
+            return List.of(
+                    new DropIndexEntry(index.id())
+            );
+        });
+    }
+
     private void registerCatalog(Catalog newCatalog) {
         catalogByVer.put(newCatalog.version(), newCatalog);
         catalogByTs.put(newCatalog.time(), newCatalog);
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractIndexCommandParams.java
similarity index 65%
copy from 
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
copy to 
modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractIndexCommandParams.java
index 0aa2b8ecfc..ed3d56b6cc 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractIndexCommandParams.java
@@ -18,37 +18,33 @@
 package org.apache.ignite.internal.catalog.commands;
 
 /**
- * Abstract table ddl command.
+ * Abstract index ddl command.
  */
-public class AbstractTableCommandParams implements DdlCommandParams {
-    /** Table name. */
-    protected String tableName;
+public class AbstractIndexCommandParams implements DdlCommandParams {
+    /** Index name. */
+    protected String indexName;
 
-    /** Quietly ignore this command if table is not exists. */
-    protected boolean ifTableExists;
-
-    /** Schema name where this new table will be created. */
+    /** Schema name where this new index will be created. */
     protected String schema;
 
-    public String tableName() {
-        return tableName;
-    }
-
-    public String schemaName() {
-        return schema;
+    /**
+     * Returns index simple name.
+     */
+    public String indexName() {
+        return indexName;
     }
 
     /**
-     * Quietly ignore if table is not exist.
+     * Returns schema name.
      */
-    public boolean ifTableExists() {
-        return ifTableExists;
+    public String schemaName() {
+        return schema;
     }
 
     /**
      * Parameters builder.
      */
-    protected abstract static class AbstractBuilder<ParamT extends 
AbstractTableCommandParams, BuilderT> {
+    protected abstract static class AbstractBuilder<ParamT extends 
AbstractIndexCommandParams, BuilderT> {
         protected ParamT params;
 
         AbstractBuilder(ParamT params) {
@@ -67,24 +63,13 @@ public class AbstractTableCommandParams implements 
DdlCommandParams {
         }
 
         /**
-         * Sets table schema.
+         * Sets index simple name.
          *
-         * @param tableName Table name.
+         * @param indexName Index simple name.
          * @return {@code this}.
          */
-        public BuilderT tableName(String tableName) {
-            params.tableName = tableName;
-            return (BuilderT) this;
-        }
-
-        /**
-         * Set quietly ignore flag.
-         *
-         * @param ifTableNotExists Flag.
-         */
-        public BuilderT ifTableExists(boolean ifTableNotExists) {
-            params.ifTableExists = ifTableNotExists;
-
+        public BuilderT indexName(String indexName) {
+            params.indexName = indexName;
             return (BuilderT) this;
         }
 
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
index 0aa2b8ecfc..67c7a588e8 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/AbstractTableCommandParams.java
@@ -24,25 +24,21 @@ public class AbstractTableCommandParams implements 
DdlCommandParams {
     /** Table name. */
     protected String tableName;
 
-    /** Quietly ignore this command if table is not exists. */
-    protected boolean ifTableExists;
-
     /** Schema name where this new table will be created. */
     protected String schema;
 
+    /**
+     * Returns table simple name.
+     */
     public String tableName() {
         return tableName;
     }
 
-    public String schemaName() {
-        return schema;
-    }
-
     /**
-     * Quietly ignore if table is not exist.
+     * Returns schema name.
      */
-    public boolean ifTableExists() {
-        return ifTableExists;
+    public String schemaName() {
+        return schema;
     }
 
     /**
@@ -67,9 +63,9 @@ public class AbstractTableCommandParams implements 
DdlCommandParams {
         }
 
         /**
-         * Sets table schema.
+         * Sets table simple name.
          *
-         * @param tableName Table name.
+         * @param tableName Table simple name.
          * @return {@code this}.
          */
         public BuilderT tableName(String tableName) {
@@ -77,17 +73,6 @@ public class AbstractTableCommandParams implements 
DdlCommandParams {
             return (BuilderT) this;
         }
 
-        /**
-         * Set quietly ignore flag.
-         *
-         * @param ifTableNotExists Flag.
-         */
-        public BuilderT ifTableExists(boolean ifTableNotExists) {
-            params.ifTableExists = ifTableNotExists;
-
-            return (BuilderT) this;
-        }
-
         /**
          * Builds parameters.
          *
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java
index 1ead944291..a09a2d5393 100644
--- 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CatalogUtils.java
@@ -17,7 +17,13 @@
 
 package org.apache.ignite.internal.catalog.commands;
 
+import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import org.apache.ignite.internal.catalog.descriptors.HashIndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.IndexColumnDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.IndexDescriptor;
+import org.apache.ignite.internal.catalog.descriptors.SortedIndexDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.TableColumnDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.TableDescriptor;
 
@@ -41,6 +47,33 @@ public class CatalogUtils {
         );
     }
 
+    /**
+     * Converts CreateIndex command params to descriptor.
+     *
+     * @param id Index id.
+     * @param tableId Table id.
+     * @param params Parameters.
+     * @return Index descriptor.
+     */
+    public static IndexDescriptor fromParams(int id, int tableId, 
CreateIndexParams params) {
+        switch (params.type()) {
+            case HASH:
+                return new HashIndexDescriptor(id,
+                        params.indexName(),
+                        tableId,
+                        params.columns()
+                );
+            case SORTED:
+                List<IndexColumnDescriptor> columnDescriptors = 
IntStream.range(0, params.collations().size())
+                        .mapToObj(i -> new 
IndexColumnDescriptor(params.columns().get(i), params.collations().get(i)))
+                        .collect(Collectors.toList());
+                return new SortedIndexDescriptor(id, params.indexName(), 
tableId, columnDescriptors);
+            default:
+                throw new IllegalArgumentException("Unsupported index type: " 
+ params.type());
+        }
+
+    }
+
     private static TableColumnDescriptor fromParams(ColumnParams params) {
         return new TableColumnDescriptor(params.name(), params.type(), 
params.nullable(), params.defaultValueDefinition());
     }
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateIndexParams.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateIndexParams.java
new file mode 100644
index 0000000000..d0a6012c42
--- /dev/null
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/CreateIndexParams.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+import org.apache.ignite.internal.catalog.descriptors.ColumnCollation;
+
+/**
+ * CREATE INDEX statement.
+ */
+public class CreateIndexParams extends AbstractIndexCommandParams {
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /** Type of the index to create. */
+    public enum Type {
+        SORTED, HASH
+    }
+
+    /** Table name. */
+    private String tableName;
+
+    private Type type;
+
+    private List<String> columns;
+
+    private List<ColumnCollation> collations;
+
+    public List<String> columns() {
+        return columns;
+    }
+
+    public List<ColumnCollation> collations() {
+        return collations;
+    }
+
+    public Type type() {
+        return type;
+    }
+
+    public String tableName() {
+        return tableName;
+    }
+
+    /**
+     * Parameters builder.
+     */
+    public static class Builder extends 
AbstractIndexCommandParams.AbstractBuilder<CreateIndexParams, 
CreateIndexParams.Builder> {
+        private Builder() {
+            super(new CreateIndexParams());
+        }
+
+        public Builder type(Type type) {
+            params.type = type;
+
+            return this;
+        }
+
+        public Builder tableName(String tblName) {
+            params.tableName = tblName;
+
+            return this;
+        }
+
+        public Builder columns(List<String> columns) {
+            params.columns = columns;
+
+            return this;
+        }
+
+        public Builder collations(List<ColumnCollation> collations) {
+            params.collations = collations;
+
+            return this;
+        }
+
+    }
+}
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/DropIndexParams.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/DropIndexParams.java
new file mode 100644
index 0000000000..aeefaabb1c
--- /dev/null
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/DropIndexParams.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * DROP INDEX statement.
+ */
+public class DropIndexParams extends AbstractIndexCommandParams {
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Parameters builder.
+     */
+    public static class Builder extends AbstractBuilder<DropIndexParams, 
Builder> {
+        Builder() {
+            super(new DropIndexParams());
+        }
+    }
+}
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/DropIndexEntry.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/DropIndexEntry.java
new file mode 100644
index 0000000000..6ec3b63f9e
--- /dev/null
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/DropIndexEntry.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.ignite.internal.tostring.S;
+
+/**
+ * Describes deletion of a index.
+ */
+public class DropIndexEntry implements UpdateEntry {
+    private static final long serialVersionUID = -604729846502020728L;
+
+    private final int indexId;
+
+    /**
+     * Constructs the object.
+     *
+     * @param IndexId An id of a index to drop.
+     */
+    public DropIndexEntry(int IndexId) {
+        this.indexId = IndexId;
+    }
+
+    /** Returns an id of a index to drop. */
+    public int indexId() {
+        return indexId;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return S.toString(this);
+    }
+}
diff --git 
a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/NewIndexEntry.java
 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/NewIndexEntry.java
new file mode 100644
index 0000000000..40d622aa8f
--- /dev/null
+++ 
b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/storage/NewIndexEntry.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 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 org.apache.ignite.internal.catalog.descriptors.IndexDescriptor;
+import org.apache.ignite.internal.tostring.S;
+
+/**
+ * Describes addition of a new index.
+ */
+public class NewIndexEntry implements UpdateEntry {
+    private static final long serialVersionUID = 6717363577013237711L;
+
+    private final IndexDescriptor descriptor;
+
+    /**
+     * Constructs the object.
+     *
+     * @param descriptor A descriptor of a index to add.
+     */
+    public NewIndexEntry(IndexDescriptor descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    /** Returns descriptor of a index to add. */
+    public IndexDescriptor descriptor() {
+        return descriptor;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return S.toString(this);
+    }
+}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerWrapper.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerWrapper.java
index 21f39ea169..2a427d4619 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerWrapper.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlCommandHandlerWrapper.java
@@ -22,11 +22,15 @@ import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.internal.catalog.CatalogManager;
 import org.apache.ignite.internal.distributionzones.DistributionZoneManager;
 import org.apache.ignite.internal.index.IndexManager;
+import org.apache.ignite.internal.sql.engine.prepare.ddl.CreateIndexCommand;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.CreateTableCommand;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.DdlCommand;
+import org.apache.ignite.internal.sql.engine.prepare.ddl.DropIndexCommand;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.DropTableCommand;
 import org.apache.ignite.internal.storage.DataStorageManager;
 import org.apache.ignite.internal.table.distributed.TableManager;
+import org.apache.ignite.lang.IndexAlreadyExistsException;
+import org.apache.ignite.lang.IndexNotFoundException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
 import org.apache.ignite.lang.TableNotFoundException;
 
@@ -70,6 +74,16 @@ public class DdlCommandHandlerWrapper extends 
DdlCommandHandler {
                     .thenCompose(res -> 
catalogManager.dropTable(DdlToCatalogCommandConverter.convert((DropTableCommand)
 cmd))
                             
.handle(handleModificationResult(((DropTableCommand) cmd).ifTableExists(), 
TableNotFoundException.class))
                     );
+        } else if (cmd instanceof CreateIndexCommand) {
+            return ddlCommandFuture
+                    .thenCompose(res -> 
catalogManager.createIndex(DdlToCatalogCommandConverter.convert((CreateIndexCommand)
 cmd))
+                            
.handle(handleModificationResult(((CreateIndexCommand) cmd).ifNotExists(), 
IndexAlreadyExistsException.class))
+                    );
+        } else if (cmd instanceof DropIndexCommand) {
+            return ddlCommandFuture
+                    .thenCompose(res -> 
catalogManager.dropIndex(DdlToCatalogCommandConverter.convert((DropIndexCommand)
 cmd))
+                            
.handle(handleModificationResult(((DropIndexCommand) cmd).ifNotExists(), 
IndexNotFoundException.class))
+                    );
         }
 
         return ddlCommandFuture;
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlToCatalogCommandConverter.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlToCatalogCommandConverter.java
index e0e9f4f520..4a4cc96d82 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlToCatalogCommandConverter.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/ddl/DdlToCatalogCommandConverter.java
@@ -20,13 +20,20 @@ package org.apache.ignite.internal.sql.engine.exec.ddl;
 import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.ignite.internal.catalog.commands.ColumnParams;
+import org.apache.ignite.internal.catalog.commands.CreateIndexParams;
 import org.apache.ignite.internal.catalog.commands.CreateTableParams;
 import org.apache.ignite.internal.catalog.commands.DefaultValue;
+import org.apache.ignite.internal.catalog.commands.DropIndexParams;
 import org.apache.ignite.internal.catalog.commands.DropTableParams;
+import org.apache.ignite.internal.catalog.descriptors.ColumnCollation;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.ColumnDefinition;
+import org.apache.ignite.internal.sql.engine.prepare.ddl.CreateIndexCommand;
+import 
org.apache.ignite.internal.sql.engine.prepare.ddl.CreateIndexCommand.Type;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.CreateTableCommand;
 import 
org.apache.ignite.internal.sql.engine.prepare.ddl.DefaultValueDefinition;
+import org.apache.ignite.internal.sql.engine.prepare.ddl.DropIndexCommand;
 import org.apache.ignite.internal.sql.engine.prepare.ddl.DropTableCommand;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex;
 import org.apache.ignite.internal.sql.engine.util.TypeUtils;
 
 /**
@@ -56,6 +63,29 @@ class DdlToCatalogCommandConverter {
                 .build();
     }
 
+    static CreateIndexParams convert(CreateIndexCommand cmd) {
+        List<ColumnCollation> collations = cmd.collations() == null ? null
+                : 
cmd.collations().stream().map(DdlToCatalogCommandConverter::convert).collect(Collectors.toList());
+
+        return CreateIndexParams.builder()
+                .schemaName(cmd.schemaName())
+                .indexName(cmd.indexName())
+
+                .tableName(cmd.tableName())
+                .type(convert(cmd.type()))
+                .columns(cmd.columns())
+                .collations(collations)
+
+                .build();
+    }
+
+    static DropIndexParams convert(DropIndexCommand cmd) {
+        return DropIndexParams.builder()
+                .schemaName(cmd.schemaName())
+                .indexName(cmd.indexName())
+                .build();
+    }
+
     private static ColumnParams convert(ColumnDefinition def) {
         return new ColumnParams(def.name(), TypeUtils.columnType(def.type()), 
convert(def.defaultValueDefinition()), def.nullable());
     }
@@ -72,4 +102,19 @@ class DdlToCatalogCommandConverter {
                 throw new IllegalArgumentException("Default value definition: 
" + def.type());
         }
     }
+
+    private static CreateIndexParams.Type convert(Type type) {
+        switch (type) {
+            case SORTED:
+                return CreateIndexParams.Type.SORTED;
+            case HASH:
+                return CreateIndexParams.Type.HASH;
+            default:
+                throw new IllegalArgumentException("Unsupported index type: " 
+ type);
+        }
+    }
+
+    private static ColumnCollation convert(IgniteIndex.Collation collation) {
+        return ColumnCollation.get(collation.asc, collation.nullsFirst);
+    }
 }

Reply via email to