You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2023/07/10 13:25:17 UTC

[ignite-3] 02/02: Fix invalid default type scale/precision. Fix tests.

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

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

commit 52495c0490e56bfe7c55119628cc53b014f38174
Author: amashenkov <an...@gmail.com>
AuthorDate: Fri Jul 7 17:11:40 2023 +0300

    Fix invalid default type scale/precision.
    Fix tests.
---
 .../apache/ignite/internal/catalog/Catalog.java    |  31 +++
 .../internal/catalog/commands/CatalogUtils.java    |  47 ++++-
 .../internal/catalog/commands/ColumnParams.java    |   6 +-
 .../internal/catalog/CatalogServiceSelfTest.java   |  89 +++++----
 .../storage/ItRebalanceDistributedTest.java        |  31 +--
 .../inmemory/ItRaftStorageVolatilityTest.java      |  12 +-
 .../runner/app/ItSchemaChangeKvViewTest.java       |   2 +
 .../runner/app/ItSchemaChangeTableViewTest.java    |   1 +
 .../runner/app/ItTableApiContractTest.java         | 124 ++++++------
 .../internal/runner/app/ItTablesApiTest.java       |  56 +++---
 .../runner/app/PlatformTestNodeRunner.java         |  22 +--
 .../ignite/internal/sql/api/ItCommonApiTest.java   |  10 +-
 .../ignite/internal/table/ItRoReadsTest.java       |  22 ++-
 .../internal/table/ItThinClientColocationTest.java |   4 +-
 modules/schema/build.gradle                        |   1 +
 .../ignite/internal/schema/DecimalNativeType.java  |   6 -
 .../apache/ignite/internal/schema/NativeTypes.java |   7 +-
 .../ignite/internal/schema/TemporalNativeType.java |  24 +--
 .../configuration/AbstractSchemaConverterTest.java |   7 +-
 .../schema/serializer/AbstractSerializerTest.java  |   9 +-
 .../testutils/SchemaToCatalogParamsConverter.java  | 208 +++++++++++++++++++++
 .../schema/testutils/definition/ColumnType.java    |  44 +----
 .../engine/exec/ddl/DdlCommandHandlerWrapper.java  |  10 +-
 .../exec/ddl/DdlToCatalogCommandConverter.java     |   7 +
 .../internal/sql/engine/type/IgniteTypeSystem.java |   6 +-
 .../internal/table/distributed/TableManager.java   |   7 +-
 .../internal/table/MutableRowTupleAdapterTest.java |   6 +-
 .../table/distributed/TableManagerTest.java        |  56 +++---
 28 files changed, 541 insertions(+), 314 deletions(-)

diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/Catalog.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/Catalog.java
index 2a6c06b5e3..c4e88285cf 100644
--- a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/Catalog.java
+++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/Catalog.java
@@ -39,6 +39,37 @@ import org.apache.ignite.internal.util.CollectionUtils;
  * Catalog descriptor represents database schema snapshot.
  */
 public class Catalog {
+    /**
+     * Default TIMESTAMP type precision: microseconds.
+     *
+     * <p>SQL`16 part 2 section 6.1 syntax rule 36
+     */
+    public static final int DEFAULT_TIMESTAMP_PRECISION = 6;
+    /**
+     * Default TIME type precision: seconds.
+     *
+     * <p>SQL`16 part 2 section 6.1 syntax rule 36
+     */
+    public static final int DEFAULT_TIME_PRECISION = 0;
+    /**
+     * Max TIME precision.
+     *
+     * <p>SQL99 part 2 section 6.1 syntax rule 32
+     */
+    public static final int MAX_TIME_PRECISION = 9;
+    /**
+     * Default DECIMAL precision is implementation-defined.
+     *
+     * <p>SQL`16 part 2 section 6.1 syntax rule 25
+     */
+    public static final int DEFAULT_DECIMAL_PRECISION = 19;
+    /**
+     * Default DECIMAL scale is implementation-defined.
+     *
+     * <p>SQL`16 part 2 section 6.1 syntax rule 25
+     */
+    public static final int DEFAULT_DECIMAL_SCALE = 3;
+
     private static <T extends CatalogObjectDescriptor> Collector<T, ?, Map<String, T>> toMapByName() {
         return Collectors.toUnmodifiableMap(CatalogObjectDescriptor::name, Function.identity());
     }
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 7823b09d47..a380849fa0 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
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.IntStream;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.catalog.descriptors.CatalogColumnCollation;
 import org.apache.ignite.internal.catalog.descriptors.CatalogHashIndexDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.CatalogIndexColumnDescriptor;
@@ -125,11 +126,13 @@ public class CatalogUtils {
      * @return Column descriptor.
      */
     public static CatalogTableColumnDescriptor fromParams(ColumnParams params) {
-        int precision = params.precision() != null ? params.precision() : 0;
-        int scale = params.scale() != null ? params.scale() : 0;
-        int length = params.length() != null ? params.length() : 0;
+        int precision = params.precision() != null ? params.precision() : defaultPrecision(params.type());
+        int scale = params.scale() != null ? params.scale() : defaultScale(params.type());
+        int length = params.length() != null ? params.length() : defaultLength(params.type());
         DefaultValue defaultValue = params.defaultValueDefinition();
 
+        // assert scale <= precision : "Column type 'scale' can't be greater than 'precision'.";
+
         return new CatalogTableColumnDescriptor(params.name(), params.type(), params.nullable(),
                 precision, scale, length, defaultValue);
     }
@@ -146,4 +149,42 @@ public class CatalogUtils {
 
         return supportedTransitions != null && supportedTransitions.contains(target);
     }
+
+    private static int defaultPrecision(ColumnType columnType) {
+        //TODO IGNITE-18556: Add REAL,FLOAT and DOUBLE precision. See SQL`16 part 2 section 6.1 syntax rule 29-31
+        switch (columnType) {
+            case NUMBER:
+            case DECIMAL:
+                return Catalog.DEFAULT_DECIMAL_PRECISION;
+            case TIME:
+                return Catalog.DEFAULT_TIME_PRECISION;
+            case TIMESTAMP:
+            case DATETIME:
+                return Catalog.DEFAULT_TIMESTAMP_PRECISION;
+            default:
+                return 0;
+        }
+    }
+
+    private static int defaultScale(ColumnType columnType) {
+        //TODO IGNITE-18556: Add REAL,FLOAT and DOUBLE precision. See SQL`16 part 2 section 6.1 syntax rule 29-31
+        switch (columnType) {
+            case DECIMAL:
+                return Catalog.DEFAULT_DECIMAL_SCALE;
+            default:
+                return 0;
+        }
+    }
+
+    private static int defaultLength(ColumnType columnType) {
+        //TODO IGNITE-18556: Return length for other types. See SQL`16 part 2 section 6.1 syntax rule 39
+        switch (columnType) {
+            case STRING:
+            case BYTE_ARRAY:
+                return Integer.MAX_VALUE;
+            default:
+                return 0;
+        }
+    }
+
 }
diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/ColumnParams.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/ColumnParams.java
index f95e0544d7..9a57887652 100644
--- a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/ColumnParams.java
+++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/commands/ColumnParams.java
@@ -158,7 +158,7 @@ public class ColumnParams {
          *
          * @return {@code this}.
          */
-        public Builder precision(int precision) {
+        public Builder precision(Integer precision) {
             params.precision = precision;
 
             return this;
@@ -169,7 +169,7 @@ public class ColumnParams {
          *
          * @return {@code this}.
          */
-        public Builder scale(int scale) {
+        public Builder scale(Integer scale) {
             params.scale = scale;
 
             return this;
@@ -180,7 +180,7 @@ public class ColumnParams {
          *
          * @return {@code this}.
          */
-        public Builder length(int length) {
+        public Builder length(Integer length) {
             params.length = length;
 
             return this;
diff --git a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogServiceSelfTest.java b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogServiceSelfTest.java
index 7dd9c5f4ce..370365604d 100644
--- a/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogServiceSelfTest.java
+++ b/modules/catalog/src/test/java/org/apache/ignite/internal/catalog/CatalogServiceSelfTest.java
@@ -424,7 +424,7 @@ public class CatalogServiceSelfTest {
         assertEquals(DefaultValue.Type.CONSTANT, column.defaultValue().type());
         assertEquals("Ignite!", ((DefaultValue.ConstantValue) column.defaultValue()).value());
 
-        assertEquals(0, column.length());
+        assertEquals(Integer.MAX_VALUE, column.length());
         assertEquals(0, column.precision());
         assertEquals(0, column.scale());
     }
@@ -674,7 +674,7 @@ public class CatalogServiceSelfTest {
     @EnumSource(value = ColumnType.class, names = {"DECIMAL"}, mode = Mode.INCLUDE)
     public void testAlterColumnTypePrecision(ColumnType type) {
         ColumnParams pkCol = ColumnParams.builder().name("ID").type(ColumnType.INT32).build();
-        ColumnParams col = ColumnParams.builder().name("COL_" + type).type(type).build();
+        ColumnParams col = ColumnParams.builder().name("COL_" + type).type(type).precision(5).build();
 
         assertThat(service.createTable(simpleTable(TABLE_NAME, List.of(pkCol, col))), willBe(nullValue()));
 
@@ -682,46 +682,37 @@ public class CatalogServiceSelfTest {
         assertNotNull(service.schema(schemaVer));
         assertNull(service.schema(schemaVer + 1));
 
-        // ANY-> UNDEFINED PRECISION : No-op.
-        assertThat(changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type()), null, null),
-                willBe(nullValue()));
-        assertNull(service.schema(schemaVer + 1));
-
-        // UNDEFINED PRECISION -> 10 : Ok.
+        // 5 -> 6 : Ok.
         assertThat(
-                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 10, null, null), null, null),
+                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 6, null, null), null, null),
                 willBe(nullValue())
         );
         assertNotNull(service.schema(++schemaVer));
 
-        // 10 -> 11 : Ok.
+        // No change.
         assertThat(
-                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 11, null, null), null, null),
+                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 6, null, null), null, null),
                 willBe(nullValue())
         );
+        assertNull(service.schema(schemaVer + 1));
 
-        CatalogSchemaDescriptor schema = service.schema(++schemaVer);
-        assertNotNull(schema);
-
-        CatalogTableColumnDescriptor desc = schema.table(TABLE_NAME).column(col.name());
-
-        assertNotSame(desc.length(), desc.precision());
-        assertEquals(11, col.type() == ColumnType.DECIMAL ? desc.precision() : desc.length());
-
-        // 11 -> 10 : Error.
+        // 6 -> 5 : Error.
         assertThat(
-                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 10, null, null), null, null),
-                willThrowFast(SqlException.class, "Cannot decrease precision to 10 for column '" + col.name() + "'.")
+                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), 5, null, null), null, null),
+                willThrowFast(SqlException.class, "Cannot decrease precision to 5 for column '" + col.name() + "'.")
         );
         assertNull(service.schema(schemaVer + 1));
     }
 
+    /**
+     * Changing precision is not supported for all types other than DECIMAL.
+     */
     @ParameterizedTest
     @EnumSource(value = ColumnType.class, names = {"NULL", "DECIMAL"}, mode = Mode.EXCLUDE)
     public void testAlterColumnTypeAnyPrecisionChangeIsRejected(ColumnType type) {
         ColumnParams pkCol = ColumnParams.builder().name("ID").type(ColumnType.INT32).build();
         ColumnParams col = ColumnParams.builder().name("COL").type(type).build();
-        ColumnParams colWithPrecision = ColumnParams.builder().name("COL_PRECISION").type(type).precision(10).build();
+        ColumnParams colWithPrecision = ColumnParams.builder().name("COL_PRECISION").type(type).precision(3).build();
 
         assertThat(service.createTable(simpleTable(TABLE_NAME, List.of(pkCol, col, colWithPrecision))), willBe(nullValue()));
 
@@ -729,16 +720,16 @@ public class CatalogServiceSelfTest {
         assertNotNull(service.schema(schemaVer));
         assertNull(service.schema(schemaVer + 1));
 
-        assertThat(changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(type, 10, null, null), null, null),
+        assertThat(changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(type, 3, null, null), null, null),
                 willThrowFast(SqlException.class, "Cannot change precision for column '" + col.name() + "'"));
 
-        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 10, null, null), null, null),
+        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 3, null, null), null, null),
                 willBe(nullValue()));
 
-        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 9, null, null), null, null),
+        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 2, null, null), null, null),
                 willThrowFast(SqlException.class, "Cannot change precision for column '" + colWithPrecision.name() + "'"));
 
-        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 11, null, null), null, null),
+        assertThat(changeColumn(TABLE_NAME, colWithPrecision.name(), new TestColumnTypeParams(type, 4, null, null), null, null),
                 willThrowFast(SqlException.class, "Cannot change precision for column '" + colWithPrecision.name() + "'"));
 
         assertNull(service.schema(schemaVer + 1));
@@ -756,7 +747,7 @@ public class CatalogServiceSelfTest {
     @EnumSource(value = ColumnType.class, names = {"STRING", "BYTE_ARRAY"}, mode = Mode.INCLUDE)
     public void testAlterColumnTypeLength(ColumnType type) {
         ColumnParams pkCol = ColumnParams.builder().name("ID").type(ColumnType.INT32).build();
-        ColumnParams col = ColumnParams.builder().name("COL_" + type).type(type).build();
+        ColumnParams col = ColumnParams.builder().name("COL_" + type).length(10).type(type).build();
 
         assertThat(service.createTable(simpleTable(TABLE_NAME, List.of(pkCol, col))), willBe(nullValue()));
 
@@ -764,18 +755,6 @@ public class CatalogServiceSelfTest {
         assertNotNull(service.schema(schemaVer));
         assertNull(service.schema(schemaVer + 1));
 
-        // ANY-> UNDEFINED LENGTH : No-op.
-        assertThat(changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type()), null, null),
-                willBe(nullValue()));
-        assertNull(service.schema(schemaVer + 1));
-
-        // UNDEFINED LENGTH -> 10 : Ok.
-        assertThat(
-                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), null, 10, null), null, null),
-                willBe(nullValue())
-        );
-        assertNotNull(service.schema(++schemaVer));
-
         // 10 -> 11 : Ok.
         assertThat(
                 changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), null, 11, null), null, null),
@@ -785,19 +764,36 @@ public class CatalogServiceSelfTest {
         CatalogSchemaDescriptor schema = service.schema(++schemaVer);
         assertNotNull(schema);
 
-        CatalogTableColumnDescriptor desc = schema.table(TABLE_NAME).column(col.name());
-
-        assertNotSame(desc.length(), desc.precision());
-        assertEquals(11, col.type() == ColumnType.DECIMAL ? desc.precision() : desc.length());
-
         // 11 -> 10 : Error.
         assertThat(
                 changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), null, 10, null), null, null),
                 willThrowFast(SqlException.class, "Cannot decrease length to 10 for column '" + col.name() + "'.")
         );
         assertNull(service.schema(schemaVer + 1));
+
+        // 11 -> 11 : No-op.
+        assertThat(
+                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), null, 11, null), null, null),
+                willBe(nullValue())
+        );
+        assertNull(service.schema(schemaVer + 1));
+
+        // No change.
+        assertThat(changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type()), null, null),
+                willBe(nullValue()));
+        assertNull(service.schema(schemaVer + 1));
+
+        // 11 -> 10 : failed.
+        assertThat(
+                changeColumn(TABLE_NAME, col.name(), new TestColumnTypeParams(col.type(), null, 10, null), null, null),
+                willThrowFast(SqlException.class)
+        );
+        assertNull(service.schema(schemaVer + 1));
     }
 
+    /**
+     * Changing length is forbidden for all types other than STRING and BYTE_ARRAY.
+     */
     @ParameterizedTest
     @EnumSource(value = ColumnType.class, names = {"NULL", "STRING", "BYTE_ARRAY"}, mode = Mode.EXCLUDE)
     public void testAlterColumnTypeAnyLengthChangeIsRejected(ColumnType type) {
@@ -826,6 +822,9 @@ public class CatalogServiceSelfTest {
         assertNull(service.schema(schemaVer + 1));
     }
 
+    /**
+     * Changing scale is incompatible change, thus it's forbidden for all types.
+     */
     @ParameterizedTest
     @EnumSource(value = ColumnType.class, names = "NULL", mode = Mode.EXCLUDE)
     public void testAlterColumnTypeScaleIsRejected(ColumnType type) {
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItRebalanceDistributedTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItRebalanceDistributedTest.java
index 0d71a098c2..f1c53c6571 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItRebalanceDistributedTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItRebalanceDistributedTest.java
@@ -123,7 +123,7 @@ import org.apache.ignite.internal.schema.configuration.defaultvalue.ConstantValu
 import org.apache.ignite.internal.schema.configuration.defaultvalue.FunctionCallDefaultConfigurationSchema;
 import org.apache.ignite.internal.schema.configuration.defaultvalue.NullValueDefaultConfigurationSchema;
 import org.apache.ignite.internal.schema.configuration.index.HashIndexConfigurationSchema;
-import org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
 import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
@@ -266,9 +266,7 @@ public class ItRebalanceDistributedTest {
         ).withPrimaryKey("key").build();
 
         await(nodes.get(0).tableManager.createTableAsync(
-                "TBL1",
-                ZONE_1_NAME,
-                tblChanger -> SchemaConfigurationConverter.convert(schTbl1, tblChanger)
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_1_NAME, schTbl1)
         ));
 
         assertEquals(1, getPartitionClusterNodes(0, 0).size());
@@ -292,9 +290,7 @@ public class ItRebalanceDistributedTest {
         ).withPrimaryKey("key").build();
 
         await(nodes.get(0).tableManager.createTableAsync(
-                "TBL1",
-                ZONE_1_NAME,
-                tblChanger -> SchemaConfigurationConverter.convert(schTbl1, tblChanger)
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_1_NAME, schTbl1)
         ));
 
         assertEquals(1, getPartitionClusterNodes(0, 0).size());
@@ -319,9 +315,8 @@ public class ItRebalanceDistributedTest {
         ).withPrimaryKey("key").build();
 
         await(nodes.get(0).tableManager.createTableAsync(
-                "TBL1",
-                ZONE_1_NAME,
-                tblChanger -> SchemaConfigurationConverter.convert(schTbl1, tblChanger)));
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_1_NAME, schTbl1)
+        ));
 
         assertEquals(1, getPartitionClusterNodes(0, 0).size());
 
@@ -349,9 +344,8 @@ public class ItRebalanceDistributedTest {
 
         // Tests that the distribution zone created on node0 is available on node1.
         TableImpl table = (TableImpl) await(nodes.get(1).tableManager.createTableAsync(
-                "TBL1",
-                zoneName,
-                tblChanger -> SchemaConfigurationConverter.convert(schTbl1, tblChanger)));
+                SchemaToCatalogParamsConverter.toCreateTable(zoneName, schTbl1)
+        ));
 
         Set<String> partitionNodesConsistentIds = getPartitionClusterNodes(0, 0).stream()
                 .map(Assignment::consistentId)
@@ -412,9 +406,8 @@ public class ItRebalanceDistributedTest {
         ).withPrimaryKey("key").build();
 
         await(nodes.get(0).tableManager.createTableAsync(
-                "TBL1",
-                ZONE_1_NAME,
-                tblChanger -> SchemaConfigurationConverter.convert(schTbl1, tblChanger)));
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_1_NAME, schTbl1)
+        ));
 
         assertEquals(1, getPartitionClusterNodes(0, 0).size());
 
@@ -992,11 +985,7 @@ public class ItRebalanceDistributedTest {
 
         assertThat(
                 nodes.get(0).tableManager.createTableAsync(
-                        tableName,
-                        zoneName,
-                        tableChange -> {
-                            SchemaConfigurationConverter.convert(createTableDefinition(tableName), tableChange);
-                        }
+                        SchemaToCatalogParamsConverter.toCreateTable(zoneName, createTableDefinition(tableName))
                 ),
                 willCompleteSuccessfully()
         );
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/inmemory/ItRaftStorageVolatilityTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/inmemory/ItRaftStorageVolatilityTest.java
index 9c7f7d4115..e19cb341e0 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/inmemory/ItRaftStorageVolatilityTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/inmemory/ItRaftStorageVolatilityTest.java
@@ -21,7 +21,6 @@ import static ca.seinesoftware.hamcrest.path.PathMatcher.exists;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.stream.Collectors.toList;
 import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_PARTITION_COUNT;
-import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_ZONE_NAME;
 import static org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.createZone;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -42,7 +41,7 @@ import org.apache.ignite.internal.ClusterPerTestIntegrationTest;
 import org.apache.ignite.internal.app.IgniteImpl;
 import org.apache.ignite.internal.raft.configuration.EntryCountBudgetChange;
 import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
-import org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
 import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
@@ -240,7 +239,7 @@ class ItRaftStorageVolatilityTest extends ClusterPerTestIntegrationTest {
     }
 
     private void createTableWithMaxOneInMemoryEntryAllowed(String tableName) {
-        int zoneId = await(createZone(
+        await(createZone(
                 node(0).distributionZoneManager(), "zone1", 1, DEFAULT_PARTITION_COUNT,
                 dataStorageChange -> dataStorageChange.convert(VolatilePageMemoryDataStorageChange.class)));
 
@@ -249,9 +248,8 @@ class ItRaftStorageVolatilityTest extends ClusterPerTestIntegrationTest {
                 SchemaBuilders.column("NAME", ColumnType.string()).asNullable(true).build()
         ).withPrimaryKey("ID").build();
 
-        await(((TableManager) node(0).tables()).createTableAsync(tableName, DEFAULT_ZONE_NAME, tableChange -> {
-            SchemaConfigurationConverter.convert(tableDef, tableChange)
-                    .changeZoneId(zoneId);
-        }));
+        await(((TableManager) node(0).tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable("zone1", tableDef)
+        ));
     }
 }
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeKvViewTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeKvViewTest.java
index deb86eaadf..197d44d38c 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeKvViewTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeKvViewTest.java
@@ -28,11 +28,13 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.schema.SchemaMismatchException;
 import org.apache.ignite.table.KeyValueView;
 import org.apache.ignite.table.Tuple;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 /**
  * Ignition interface tests.
  */
+@Disabled("IGNITE-19499")
 class ItSchemaChangeKvViewTest extends AbstractSchemaChangeTest {
     /**
      * Check add a new column to table schema.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeTableViewTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeTableViewTest.java
index 9906221940..b759356c78 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeTableViewTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItSchemaChangeTableViewTest.java
@@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
 /**
  * Ignition interface tests.
  */
+@Disabled("IGNITE-19499")
 class ItSchemaChangeTableViewTest extends AbstractSchemaChangeTest {
     /**
      * Check add a new column to table schema.
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
index 91da7e94e7..a60da2e800 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.runner.app;
 
 import static java.util.stream.Collectors.toList;
 import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_ZONE_NAME;
-import static org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter.convert;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
@@ -34,8 +33,14 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.stream.IntStream;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.catalog.commands.AlterTableAddColumnParams;
+import org.apache.ignite.internal.catalog.commands.ColumnParams;
+import org.apache.ignite.internal.catalog.commands.DefaultValue;
+import org.apache.ignite.internal.catalog.commands.DropTableParams;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
+import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
 import org.apache.ignite.internal.sql.engine.ClusterPerClassIntegrationTest;
 import org.apache.ignite.internal.table.distributed.TableManager;
 import org.apache.ignite.lang.TableAlreadyExistsException;
@@ -142,13 +147,19 @@ public class ItTableApiContractTest extends ClusterPerClassIntegrationTest {
      */
     @Test
     public void testDropTable() throws Exception {
-        CompletableFuture<Void> dropTblFut1 =  tableManager().dropTableAsync(TABLE_NAME);
+        CompletableFuture<Void> dropTblFut1 = tableManager().dropTableAsync(DropTableParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .build());
 
         dropTblFut1.get();
 
         assertNull(ignite.tables().table(TABLE_NAME));
 
-        CompletableFuture<Void> dropTblFut2 = tableManager().dropTableAsync(TABLE_NAME);
+        CompletableFuture<Void> dropTblFut2 = tableManager().dropTableAsync(DropTableParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .build());
 
         assertThrows(TableNotFoundException.class, () -> futureResult(dropTblFut2));
     }
@@ -160,23 +171,29 @@ public class ItTableApiContractTest extends ClusterPerClassIntegrationTest {
      */
     @Test
     public void testAlterTable() throws Exception {
-        await(tableManager().alterTableAsync(TABLE_NAME, chng -> {
-            chng.changeColumns(cols ->
-                    cols.create("NAME_1", colChg -> convert(SchemaBuilders.column("NAME_1", ColumnType.string()).asNullable(true)
-                            .withDefaultValue("default").build(), colChg)));
-            return true;
-        }));
+        await(tableManager().alterTableAddColumnAsync(AlterTableAddColumnParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .columns(List.of(
+                        ColumnParams.builder().name("NAME_1").type(org.apache.ignite.sql.ColumnType.STRING).nullable(true)
+                                .defaultValue(DefaultValue.constant("default")).build()
+                ))
+                .build()
+        ));
 
         assertNotNull(ignite.tables().table(TABLE_NAME));
 
-        assertNull(ignite.tables().table(TABLE_NAME + "_not_exist"));
-
-        assertThrows(TableNotFoundException.class, () -> await(tableManager().alterTableAsync(TABLE_NAME + "_not_exist", chng -> {
-            chng.changeColumns(cols ->
-                    cols.create("NAME_1", colChg -> convert(SchemaBuilders.column("NAME_1", ColumnType.string()).asNullable(true)
-                            .withDefaultValue("default").build(), colChg)));
-            return true;
-        })));
+        assertNull(ignite.tables().table("UNKNOWN"));
+
+        assertThrows(TableNotFoundException.class, () -> await(tableManager().alterTableAddColumnAsync(AlterTableAddColumnParams.builder()
+                .schemaName(SCHEMA)
+                .tableName("UNKNOWN")
+                .columns(List.of(
+                        ColumnParams.builder().name("NAME_1").type(org.apache.ignite.sql.ColumnType.STRING).nullable(true)
+                                .defaultValue(DefaultValue.constant("default")).build()
+                ))
+                .build()
+        )));
     }
 
     /**
@@ -186,68 +203,49 @@ public class ItTableApiContractTest extends ClusterPerClassIntegrationTest {
      */
     @Test
     public void testAlterTableAsync() throws Exception {
-        CompletableFuture<Void> altTblFut1 = tableManager().alterTableAsync(TABLE_NAME,
-                chng -> {
-                    chng.changeColumns(cols ->
-                            cols.create("NAME_1", colChg -> convert(SchemaBuilders.column("NAME_1",
-                                            ColumnType.string()).asNullable(true).withDefaultValue("default").build(), colChg)));
-                return true;
-            });
-
-        CompletableFuture<Void> altTblFut2 = tableManager().alterTableAsync(TABLE_NAME + "_not_exist",
-                chng -> {
-                    chng.changeColumns(cols ->
-                            cols.create("NAME_1", colChg -> convert(SchemaBuilders.column("NAME_1",
-                                            ColumnType.string()).asNullable(true).withDefaultValue("default").build(), colChg)));
-                    return true;
-            });
+        CompletableFuture<Void> altTblFut1 = tableManager().alterTableAddColumnAsync(AlterTableAddColumnParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .columns(List.of(
+                        ColumnParams.builder().name("NAME_1").type(org.apache.ignite.sql.ColumnType.STRING).nullable(true)
+                                .defaultValue(DefaultValue.constant("default")).build()
+                ))
+                .build());
+
+        CompletableFuture<Void> altTblFut2 = tableManager().alterTableAddColumnAsync(AlterTableAddColumnParams.builder()
+                .schemaName(SCHEMA)
+                .tableName("UNKNOWN")
+                .columns(List.of(
+                        ColumnParams.builder().name("NAME_1").type(org.apache.ignite.sql.ColumnType.STRING).nullable(true)
+                                .defaultValue(DefaultValue.constant("default")).build()
+                ))
+                .build());
 
         assertNotNull(ignite.tables().table(TABLE_NAME));
 
-        assertNull(ignite.tables().table(TABLE_NAME + "_not_exist"));
+        assertNull(ignite.tables().table("UNKNOWN"));
 
         altTblFut1.get();
 
         assertThrows(TableNotFoundException.class, () -> futureResult(altTblFut2));
     }
 
-    /**
-     * Checks a contract for table creation.
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testCreateTable() throws Exception {
-        Table table = ignite.tables().table(TABLE_NAME);
-
-        assertNotNull(table);
-
-        assertThrows(TableAlreadyExistsException.class,
-                () -> await(tableManager().createTableAsync(TABLE_NAME, DEFAULT_ZONE_NAME,
-                        tableChange -> convert(SchemaBuilders.tableBuilder(SCHEMA, TABLE_NAME)
-                                .columns(
-                                        SchemaBuilders.column("new_key", ColumnType.INT64).build(),
-                                        SchemaBuilders.column("new_val", ColumnType.string()).build())
-                                .withPrimaryKey("new_key")
-                                .build(), tableChange))));
-    }
-
     /**
      * Checks a contract for asynchronous table creation.
-     *
-     * @throws Exception If failed.
      */
     @Test
-    public void testCreateTableAsync() throws Exception {
+    public void testCreateTableAsync() {
         assertNotNull(ignite.tables().table(TABLE_NAME));
 
+        TableDefinition tableDefinition = SchemaBuilders.tableBuilder(SCHEMA, TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("new_key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("new_val", ColumnType.string()).build())
+                .withPrimaryKey("new_key")
+                .build();
+
         CompletableFuture<Table> tableFut2 = tableManager()
-                .createTableAsync(TABLE_NAME, DEFAULT_ZONE_NAME, tableChange -> convert(SchemaBuilders.tableBuilder(SCHEMA, TABLE_NAME)
-                        .columns(
-                                SchemaBuilders.column("new_key", ColumnType.INT64).build(),
-                                SchemaBuilders.column("new_val", ColumnType.string()).build())
-                        .withPrimaryKey("new_key")
-                        .build(), tableChange));
+                .createTableAsync(SchemaToCatalogParamsConverter.toCreateTable(DEFAULT_ZONE_NAME, tableDefinition));
 
         assertThrows(TableAlreadyExistsException.class, () -> futureResult(tableFut2));
     }
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
index cb96e88300..c4fc440077 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.runner.app;
 import static java.util.concurrent.CompletableFuture.runAsync;
 import static java.util.concurrent.CompletableFuture.supplyAsync;
 import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_ZONE_NAME;
-import static org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter.convert;
 import static org.apache.ignite.internal.test.WatchListenerInhibitor.metastorageEventsInhibitor;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.testNodeName;
@@ -44,6 +43,9 @@ import java.util.stream.IntStream;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.InitParameters;
+import org.apache.ignite.internal.catalog.commands.AlterTableAddColumnParams;
+import org.apache.ignite.internal.catalog.commands.DropTableParams;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnDefinition;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
@@ -442,7 +444,10 @@ public class ItTablesApiTest extends IgniteAbstractTest {
 
         ignite1Inhibitor.startInhibit();
 
-        await(((TableManager) clusterNodes.get(0).tables()).dropTableAsync(TABLE_NAME));
+        await(((TableManager) clusterNodes.get(0).tables()).dropTableAsync(DropTableParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .build()));
 
         // Because the event inhibitor was started, last metastorage updates do not reach to one node.
         // Therefore the table still exists locally, but API prevents getting it.
@@ -466,11 +471,6 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      * @param tableName Table name.
      */
     protected Table createTable(Ignite node, String tableName) {
-        List<ColumnDefinition> cols = new ArrayList<>();
-        cols.add(SchemaBuilders.column("key", ColumnType.INT64).build());
-        cols.add(SchemaBuilders.column("valInt", ColumnType.INT32).asNullable(true).build());
-        cols.add(SchemaBuilders.column("valStr", ColumnType.string()).withDefaultValue("default").build());
-
         var tmpl = "CREATE TABLE %s (key BIGINT PRIMARY KEY, valInt INT, valStr VARCHAR)";
         var sql = String.format(tmpl, tableName);
 
@@ -489,17 +489,19 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      */
     protected Table createTableIfNotExists(Ignite node, String tableName) {
         try {
-            return await(((TableManager) node.tables()).createTableAsync(
-                    tableName,
-                    DEFAULT_ZONE_NAME,
-                    tblCh -> convert(SchemaBuilders.tableBuilder(SCHEMA, tableName).columns(Arrays.asList(
+            TableManager tableManager = (TableManager) node.tables();
+
+            await(tableManager.createTableAsync(
+                    SchemaToCatalogParamsConverter.toCreateTable(DEFAULT_ZONE_NAME,
+                            SchemaBuilders.tableBuilder(SCHEMA, tableName).columns(Arrays.asList(
                                     SchemaBuilders.column("key", ColumnType.INT64).build(),
                                     SchemaBuilders.column("valInt", ColumnType.INT32).asNullable(true).build(),
                                     SchemaBuilders.column("valStr", ColumnType.string())
                                             .withDefaultValue("default").build()
-                            )).withPrimaryKey("key").build(),
-                            tblCh)
+                            )).withPrimaryKey("key").build())
             ));
+
+            return tableManager.table(tableName);
         } catch (TableAlreadyExistsException ex) {
             return node.tables().table(tableName);
         }
@@ -512,7 +514,10 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      * @param tableName Table name.
      */
     protected void dropTable(Ignite node, String tableName) {
-        await(((TableManager) node.tables()).dropTableAsync(tableName));
+        await(((TableManager) node.tables()).dropTableAsync(DropTableParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(TABLE_NAME)
+                .build()));
     }
 
     /**
@@ -523,7 +528,10 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      */
     protected void dropTableIfExists(Ignite node, String tableName) {
         try {
-            await(((TableManager) node.tables()).dropTableAsync(tableName));
+            await(((TableManager) node.tables()).dropTableAsync(DropTableParams.builder()
+                    .schemaName(SCHEMA)
+                    .tableName(tableName)
+                    .build()));
         } catch (TableNotFoundException ex) {
             log.info("Dropping the table ignored.", ex);
         }
@@ -550,18 +558,12 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      * @param colDefinition Column defenition.
      */
     private void addColumnInternal(Ignite node, String tableName, ColumnDefinition colDefinition) {
-        await(((TableManager) node.tables()).alterTableAsync(
-                tableName,
-                chng -> {
-                    chng.changeColumns(cols -> {
-                        try {
-                            cols.create(colDefinition.name(), colChg -> convert(colDefinition, colChg));
-                        } catch (IllegalArgumentException e) {
-                            throw new ColumnAlreadyExistsException(colDefinition.name());
-                        }
-                    });
-                    return true;
-                }));
+        await(((TableManager) node.tables()).alterTableAddColumnAsync(
+                AlterTableAddColumnParams.builder()
+                        .schemaName(SCHEMA)
+                        .tableName(tableName)
+                        .columns(List.of(SchemaToCatalogParamsConverter.convert(colDefinition)))
+                        .build()));
     }
 
     /**
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
index 4307c87641..bb74f9a4b6 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
@@ -39,6 +39,7 @@ import org.apache.ignite.compute.ComputeJob;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.internal.app.IgniteImpl;
 import org.apache.ignite.internal.binarytuple.BinaryTupleReader;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.client.proto.ColumnTypeConverter;
 import org.apache.ignite.internal.configuration.BasicAuthenticationProviderChange;
 import org.apache.ignite.internal.configuration.SecurityConfiguration;
@@ -48,10 +49,9 @@ import org.apache.ignite.internal.schema.SchemaDescriptor;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerException;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerImpl;
 import org.apache.ignite.internal.schema.row.Row;
-import org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
-import org.apache.ignite.internal.schema.testutils.definition.ColumnType.TemporalColumnType;
 import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
 import org.apache.ignite.internal.table.RecordBinaryViewImpl;
 import org.apache.ignite.internal.table.distributed.TableManager;
@@ -267,11 +267,11 @@ public class PlatformTestNodeRunner {
                 SchemaBuilders.column("val", ColumnType.string()).asNullable(true).build()
         ).withPrimaryKey(keyCol).build();
 
-        await(((TableManager) node.tables()).createTableAsync(schTbl.name(), ZONE_NAME, tblCh ->
-                SchemaConfigurationConverter.convert(schTbl, tblCh)
+        await(((TableManager) node.tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, schTbl)
         ));
 
-        int maxTimePrecision = TemporalColumnType.MAX_TIME_PRECISION;
+        int maxTimePrecision = Catalog.MAX_TIME_PRECISION;
 
         TableDefinition schTblAll = SchemaBuilders.tableBuilder(SCHEMA_NAME, TABLE_NAME_ALL_COLUMNS).columns(
                 SchemaBuilders.column(keyCol, ColumnType.INT64).build(),
@@ -295,8 +295,8 @@ public class PlatformTestNodeRunner {
                 SchemaBuilders.column("decimal", ColumnType.decimal()).asNullable(true).build()
         ).withPrimaryKey(keyCol).build();
 
-        await(((TableManager) node.tables()).createTableAsync(schTblAll.name(), ZONE_NAME, tblCh ->
-                SchemaConfigurationConverter.convert(schTblAll, tblCh)
+        await(((TableManager) node.tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, schTblAll)
         ));
 
         // TODO IGNITE-18431 remove extra table, use TABLE_NAME_ALL_COLUMNS for SQL tests.
@@ -321,8 +321,8 @@ public class PlatformTestNodeRunner {
                 SchemaBuilders.column("decimal", ColumnType.decimal()).asNullable(true).build()
         ).withPrimaryKey(keyCol).build();
 
-        await(((TableManager) node.tables()).createTableAsync(schTblAllSql.name(), ZONE_NAME, tblCh ->
-                SchemaConfigurationConverter.convert(schTblAllSql, tblCh)
+        await(((TableManager) node.tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, schTblAllSql)
         ));
 
         createTwoColumnTable(node, ColumnType.INT8);
@@ -351,8 +351,8 @@ public class PlatformTestNodeRunner {
                 SchemaBuilders.column("val", type).asNullable(true).build()
         ).withPrimaryKey(keyCol).build();
 
-        await(((TableManager) node.tables()).createTableAsync(schTbl.name(), ZONE_NAME, tblCh ->
-                SchemaConfigurationConverter.convert(schTbl, tblCh)
+        await(((TableManager) node.tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, schTbl)
         ));
     }
 
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItCommonApiTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItCommonApiTest.java
index d19cfd1bf2..ef4a2871e3 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItCommonApiTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItCommonApiTest.java
@@ -32,10 +32,10 @@ import java.util.concurrent.TimeUnit;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.app.IgniteImpl;
-import org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter;
+import org.apache.ignite.internal.catalog.Catalog;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
-import org.apache.ignite.internal.schema.testutils.definition.ColumnType.TemporalColumnType;
 import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
 import org.apache.ignite.internal.sql.engine.ClusterPerClassIntegrationTest;
 import org.apache.ignite.internal.sql.engine.SqlQueryProcessor;
@@ -124,7 +124,7 @@ public class ItCommonApiTest extends ClusterPerClassIntegrationTest {
         String kvTblName = "tbl_all_columns_sql";
         String schemaName = "PUBLIC";
         String keyCol = "key";
-        int maxTimePrecision = TemporalColumnType.MAX_TIME_PRECISION;
+        int maxTimePrecision = Catalog.MAX_TIME_PRECISION;
 
         Ignite node = CLUSTER_NODES.get(0);
 
@@ -143,8 +143,8 @@ public class ItCommonApiTest extends ClusterPerClassIntegrationTest {
                 SchemaBuilders.column("datetime", ColumnType.datetime(maxTimePrecision)).asNullable(true).build()
         ).withPrimaryKey(keyCol).build();
 
-        await(((TableManager) node.tables()).createTableAsync(schTblAllSql.name(), DEFAULT_ZONE_NAME, tblCh ->
-                SchemaConfigurationConverter.convert(schTblAllSql, tblCh)
+        await(((TableManager) node.tables()).createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(DEFAULT_ZONE_NAME, schTblAllSql)
         ));
 
         Table tbl = node.tables().table(kvTblName);
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItRoReadsTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItRoReadsTest.java
index 0fcb2c7da7..ca16262897 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItRoReadsTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItRoReadsTest.java
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.table;
 import static org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_REPLICA_COUNT;
 import static org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.createZone;
 import static org.apache.ignite.internal.runner.app.ItTablesApiTest.SCHEMA;
-import static org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter.convert;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.testNodeName;
 import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
@@ -47,6 +46,7 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.InitParameters;
 import org.apache.ignite.internal.app.IgniteImpl;
+import org.apache.ignite.internal.catalog.commands.DropTableParams;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.schema.BinaryRow;
@@ -56,6 +56,7 @@ import org.apache.ignite.internal.schema.NativeTypes;
 import org.apache.ignite.internal.schema.SchemaDescriptor;
 import org.apache.ignite.internal.schema.row.Row;
 import org.apache.ignite.internal.schema.row.RowAssembler;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnDefinition;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
@@ -532,18 +533,23 @@ public class ItRoReadsTest extends BaseIgniteAbstractTest {
         cols.add(SchemaBuilders.column("valStr", ColumnType.string()).withDefaultValue("default").build());
 
         String zoneName = "zone_" + tableName;
-        int zoneId = await(createZone(((IgniteImpl) node).distributionZoneManager(), zoneName, 1, DEFAULT_REPLICA_COUNT));
+        await(createZone(((IgniteImpl) node).distributionZoneManager(), zoneName, 1, DEFAULT_REPLICA_COUNT));
 
-        return await(((TableManager) node.tables()).createTableAsync(
-                tableName,
-                zoneName,
-                tblCh -> convert(SchemaBuilders.tableBuilder(SCHEMA, tableName).columns(
-                        cols).withPrimaryKey("key").build(), tblCh)
+        TableManager tableManager = (TableManager) node.tables();
+
+        await(tableManager.createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(zoneName, SchemaBuilders.tableBuilder(SCHEMA, tableName).columns(
+                        cols).withPrimaryKey("key").build())
         ));
+
+        return tableManager.table(tableName);
     }
 
     private static void stopTable(Ignite node, String tableName) {
-        await(((TableManager) node.tables()).dropTableAsync(tableName));
+        await(((TableManager) node.tables()).dropTableAsync(DropTableParams.builder()
+                .schemaName(SCHEMA)
+                .tableName(tableName)
+                .build()));
         await(((IgniteImpl) node).distributionZoneManager().dropZone("zone_" + tableName));
     }
 
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItThinClientColocationTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItThinClientColocationTest.java
index b829700efc..3e5dbacc9e 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItThinClientColocationTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/table/ItThinClientColocationTest.java
@@ -27,6 +27,7 @@ import java.util.concurrent.CompletableFuture;
 import java.util.stream.Stream;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.client.handler.requests.table.ClientTableCommon;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.client.table.ClientColumn;
 import org.apache.ignite.internal.client.table.ClientSchema;
 import org.apache.ignite.internal.client.table.ClientTupleSerializer;
@@ -34,7 +35,6 @@ import org.apache.ignite.internal.schema.Column;
 import org.apache.ignite.internal.schema.NativeType;
 import org.apache.ignite.internal.schema.NativeTypes;
 import org.apache.ignite.internal.schema.SchemaDescriptor;
-import org.apache.ignite.internal.schema.TemporalNativeType;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshaller;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerException;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerImpl;
@@ -144,7 +144,7 @@ public class ItThinClientColocationTest extends ClusterPerClassIntegrationTest {
 
         var types2 = new ArrayList<NativeType>();
 
-        for (int i = 0; i <= TemporalNativeType.MAX_TIME_PRECISION; i++) {
+        for (int i = 0; i <= Catalog.MAX_TIME_PRECISION; i++) {
             types2.add(NativeTypes.time(i));
             types2.add(NativeTypes.datetime(i));
             types2.add(NativeTypes.timestamp(i));
diff --git a/modules/schema/build.gradle b/modules/schema/build.gradle
index 483350dc7d..c82758d1a2 100644
--- a/modules/schema/build.gradle
+++ b/modules/schema/build.gradle
@@ -51,6 +51,7 @@ dependencies {
     testFixturesImplementation project(':ignite-api')
     testFixturesImplementation project(':ignite-bytecode')
     testFixturesImplementation project(':ignite-configuration-api')
+    testFixturesImplementation project(':ignite-catalog')
     testFixturesImplementation(testFixtures(project(':ignite-core')))
     testFixturesImplementation libs.jetbrains.annotations
     testFixturesImplementation libs.junit5.api
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/DecimalNativeType.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/DecimalNativeType.java
index 45949c98e3..cb642ba90f 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/DecimalNativeType.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/DecimalNativeType.java
@@ -24,12 +24,6 @@ import org.apache.ignite.internal.tostring.S;
  * Decimal column type.
  */
 public class DecimalNativeType extends NativeType {
-    /** Default precision. */
-    public static final int DEFAULT_PRECISION = 19;
-
-    /** Default scale. */
-    public static final int DEFAULT_SCALE = 3;
-
     /** Precision. */
     private final int precision;
 
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/NativeTypes.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/NativeTypes.java
index fff7ad5e5b..3a042678f0 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/NativeTypes.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/NativeTypes.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.schema;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.BitSet;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.jetbrains.annotations.Contract;
 
 /**
@@ -146,7 +147,7 @@ public class NativeTypes {
      * @see #time(int)
      */
     public static NativeType time() {
-        return TemporalNativeType.time(TemporalNativeType.DEFAULT_TIME_PRECISION);
+        return TemporalNativeType.time(Catalog.DEFAULT_TIME_PRECISION);
     }
 
     /**
@@ -166,7 +167,7 @@ public class NativeTypes {
      * @see #datetime(int)
      */
     public static NativeType datetime() {
-        return TemporalNativeType.datetime(TemporalNativeType.DEFAULT_TIMESTAMP_PRECISION);
+        return TemporalNativeType.datetime(Catalog.DEFAULT_TIMESTAMP_PRECISION);
     }
 
     /**
@@ -186,7 +187,7 @@ public class NativeTypes {
      * @see #timestamp(int)
      */
     public static NativeType timestamp() {
-        return TemporalNativeType.timestamp(TemporalNativeType.DEFAULT_TIMESTAMP_PRECISION);
+        return TemporalNativeType.timestamp(Catalog.DEFAULT_TIMESTAMP_PRECISION);
     }
 
     /**
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/TemporalNativeType.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/TemporalNativeType.java
index 91164870c8..cd228dbe2b 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/TemporalNativeType.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/TemporalNativeType.java
@@ -17,33 +17,13 @@
 
 package org.apache.ignite.internal.schema;
 
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.tostring.S;
 
 /**
  * Temporal native type.
  */
 public class TemporalNativeType extends NativeType {
-    /**
-     * Default TIMESTAMP type precision: microseconds.
-     *
-     * <p>SQL99 part 2 section 6.1 syntax rule 30
-     */
-    public static final int DEFAULT_TIMESTAMP_PRECISION = 6;
-
-    /**
-     * Default TIME type precision: seconds.
-     *
-     * <p>SQL99 part 2 section 6.1 syntax rule 30
-     */
-    public static final int DEFAULT_TIME_PRECISION = 0;
-
-    /**
-     * Max TIME precision.
-     *
-     * <p>SQL99 part 2 section 6.1 syntax rule 32
-     */
-    public static final int MAX_TIME_PRECISION = 9;
-
     /**
      * Creates TIME type.
      *
@@ -92,7 +72,7 @@ public class TemporalNativeType extends NativeType {
     private TemporalNativeType(NativeTypeSpec typeSpec, int size, int precision) {
         super(typeSpec, size);
 
-        if (precision < 0 || precision > MAX_TIME_PRECISION) {
+        if (precision < 0 || precision > Catalog.MAX_TIME_PRECISION) {
             throw new IllegalArgumentException("Unsupported fractional seconds precision: " + precision);
         }
 
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/AbstractSchemaConverterTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/AbstractSchemaConverterTest.java
index adc0a00ae8..33f14a9293 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/AbstractSchemaConverterTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/configuration/AbstractSchemaConverterTest.java
@@ -35,11 +35,10 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import org.apache.ignite.internal.schema.DecimalNativeType;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.schema.NativeType;
 import org.apache.ignite.internal.schema.NativeTypeSpec;
 import org.apache.ignite.internal.schema.NativeTypes;
-import org.apache.ignite.internal.schema.testutils.definition.ColumnType.DecimalColumnType;
 import org.apache.ignite.internal.util.ArrayUtils;
 
 /**
@@ -113,7 +112,7 @@ public class AbstractSchemaConverterTest {
     @SuppressWarnings("unchecked")
     protected static <T> T adjust(T val) {
         if (val instanceof BigDecimal) {
-            return (T) ((BigDecimal) val).setScale(DecimalColumnType.DEFAULT_SCALE, HALF_UP);
+            return (T) ((BigDecimal) val).setScale(Catalog.DEFAULT_DECIMAL_SCALE, HALF_UP);
         }
 
         return val;
@@ -145,7 +144,7 @@ public class AbstractSchemaConverterTest {
             case TIMESTAMP:
                 return NativeTypes.timestamp();
             case NUMBER:
-                return NativeTypes.numberOf(DecimalNativeType.DEFAULT_PRECISION);
+                return NativeTypes.numberOf(Catalog.DEFAULT_DECIMAL_PRECISION);
             case STRING:
                 return NativeTypes.stringOf(8);
             case UUID:
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/serializer/AbstractSerializerTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/serializer/AbstractSerializerTest.java
index 455771d2a3..b96e3a67c9 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/serializer/AbstractSerializerTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/serializer/AbstractSerializerTest.java
@@ -45,8 +45,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.schema.Column;
-import org.apache.ignite.internal.schema.DecimalNativeType;
 import org.apache.ignite.internal.schema.DefaultValueProvider.Type;
 import org.apache.ignite.internal.schema.NativeType;
 import org.apache.ignite.internal.schema.NativeTypeSpec;
@@ -56,7 +56,6 @@ import org.apache.ignite.internal.schema.mapping.ColumnMapper;
 import org.apache.ignite.internal.schema.mapping.ColumnMapping;
 import org.apache.ignite.internal.schema.marshaller.schema.AbstractSchemaSerializer;
 import org.apache.ignite.internal.schema.marshaller.schema.SchemaSerializerImpl;
-import org.apache.ignite.internal.schema.testutils.definition.ColumnType.DecimalColumnType;
 import org.apache.ignite.internal.util.ArrayUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -313,7 +312,7 @@ public class AbstractSerializerTest {
     @SuppressWarnings("unchecked")
     protected static <T> T adjust(T val) {
         if (val instanceof BigDecimal) {
-            return (T) ((BigDecimal) val).setScale(DecimalColumnType.DEFAULT_SCALE, HALF_UP);
+            return (T) ((BigDecimal) val).setScale(Catalog.DEFAULT_DECIMAL_SCALE, HALF_UP);
         }
 
         return val;
@@ -335,7 +334,7 @@ public class AbstractSerializerTest {
             case DOUBLE:
                 return NativeTypes.DOUBLE;
             case DECIMAL:
-                return NativeTypes.decimalOf(DecimalNativeType.DEFAULT_PRECISION, DecimalNativeType.DEFAULT_SCALE);
+                return NativeTypes.decimalOf(Catalog.DEFAULT_DECIMAL_PRECISION, Catalog.DEFAULT_DECIMAL_SCALE);
             case DATE:
                 return NativeTypes.DATE;
             case TIME:
@@ -345,7 +344,7 @@ public class AbstractSerializerTest {
             case TIMESTAMP:
                 return NativeTypes.timestamp();
             case NUMBER:
-                return NativeTypes.numberOf(DecimalNativeType.DEFAULT_PRECISION);
+                return NativeTypes.numberOf(Catalog.DEFAULT_DECIMAL_PRECISION);
             case STRING:
                 return NativeTypes.stringOf(Byte.MAX_VALUE);
             case UUID:
diff --git a/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/SchemaToCatalogParamsConverter.java b/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/SchemaToCatalogParamsConverter.java
new file mode 100644
index 0000000000..a00eda8c7f
--- /dev/null
+++ b/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/SchemaToCatalogParamsConverter.java
@@ -0,0 +1,208 @@
+/*
+ * 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.schema.testutils;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.catalog.commands.ColumnParams;
+import org.apache.ignite.internal.catalog.commands.ColumnParams.Builder;
+import org.apache.ignite.internal.catalog.commands.CreateTableParams;
+import org.apache.ignite.internal.catalog.commands.DefaultValue;
+import org.apache.ignite.internal.schema.testutils.definition.ColumnDefinition;
+import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
+import org.apache.ignite.internal.schema.testutils.definition.DefaultValueDefinition.ConstantValue;
+import org.apache.ignite.internal.schema.testutils.definition.DefaultValueDefinition.FunctionCall;
+import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
+
+/**
+ * Schema to Catalog params converter.
+ */
+public class SchemaToCatalogParamsConverter {
+    /**
+     * Types map.
+     */
+    private static final EnumSet<ColumnType.ColumnTypeSpec> fixSizedTypes = EnumSet.of(
+            ColumnType.INT8.typeSpec(),
+            ColumnType.INT16.typeSpec(),
+            ColumnType.INT32.typeSpec(),
+            ColumnType.INT64.typeSpec(),
+            ColumnType.FLOAT.typeSpec(),
+            ColumnType.DOUBLE.typeSpec(),
+            ColumnType.UUID.typeSpec(),
+            ColumnType.DATE.typeSpec()
+    );
+
+    /**
+     * Converts table definition to CreateTableParams.
+     */
+    public static CreateTableParams toCreateTable(String zoneName, TableDefinition tableDef) {
+        Set<String> keyColumns = tableDef.keyColumns();
+
+        List<String> keyColumnsInOrder = tableDef.columns().stream()
+                .map(ColumnDefinition::name)
+                .filter(keyColumns::contains)
+                .collect(Collectors.toList());
+
+        List<ColumnParams> columnParams = tableDef.columns().stream()
+                .map(SchemaToCatalogParamsConverter::convert)
+                .collect(Collectors.toList());
+
+        return CreateTableParams.builder()
+                .schemaName(tableDef.schemaName())
+                .tableName(tableDef.name())
+                .zone(zoneName)
+                .columns(columnParams)
+                .primaryKeyColumns(keyColumnsInOrder)
+                .colocationColumns(tableDef.colocationColumns())
+                .build();
+    }
+
+    /**
+     * Convert column to column change.
+     *
+     * @param def Column to convert.
+     * @return Column params.
+     */
+    public static ColumnParams convert(ColumnDefinition def) {
+        Builder builder = ColumnParams.builder()
+                .name(def.name())
+                .nullable(def.nullable());
+
+        setType(builder, def.type());
+
+        assert def.defaultValueDefinition() != null;
+
+        switch (def.defaultValueDefinition().type()) {
+            case CONSTANT:
+                ConstantValue constantValue = def.defaultValueDefinition();
+
+                builder.defaultValue(DefaultValue.constant(constantValue.value()));
+
+                break;
+            case FUNCTION_CALL:
+                FunctionCall functionCall = def.defaultValueDefinition();
+
+                builder.defaultValue(DefaultValue.functionCall(functionCall.functionName()));
+
+                break;
+            case NULL:
+
+                builder.defaultValue(DefaultValue.constant(null));
+                break;
+            default:
+                throw new IllegalStateException("Unknown default value definition type [type="
+                        + def.defaultValueDefinition().type() + ']');
+        }
+
+        return builder.build();
+    }
+
+    private static org.apache.ignite.sql.ColumnType convert(ColumnType colType) {
+        switch (colType.typeSpec()) {
+            case INT8:
+                return org.apache.ignite.sql.ColumnType.INT8;
+            case INT16:
+                return org.apache.ignite.sql.ColumnType.INT16;
+            case INT32:
+                return org.apache.ignite.sql.ColumnType.INT32;
+            case INT64:
+                return org.apache.ignite.sql.ColumnType.INT64;
+            case FLOAT:
+                return org.apache.ignite.sql.ColumnType.FLOAT;
+            case DOUBLE:
+                return org.apache.ignite.sql.ColumnType.DOUBLE;
+            case DECIMAL:
+                return org.apache.ignite.sql.ColumnType.DECIMAL;
+            case DATE:
+                return org.apache.ignite.sql.ColumnType.DATE;
+            case TIME:
+                return org.apache.ignite.sql.ColumnType.TIME;
+            case DATETIME:
+                return org.apache.ignite.sql.ColumnType.DATETIME;
+            case TIMESTAMP:
+                return org.apache.ignite.sql.ColumnType.TIMESTAMP;
+            case UUID:
+                return org.apache.ignite.sql.ColumnType.UUID;
+            case BITMASK:
+                return org.apache.ignite.sql.ColumnType.BITMASK;
+            case STRING:
+                return org.apache.ignite.sql.ColumnType.STRING;
+            case BYTES:
+                return org.apache.ignite.sql.ColumnType.BYTE_ARRAY;
+            case NUMBER:
+                return org.apache.ignite.sql.ColumnType.NUMBER;
+
+            default:
+                throw new IllegalArgumentException("Type is not supported: " + colType.typeSpec());
+        }
+    }
+
+    /**
+     * Convert ColumnType to ColumnTypeChange.
+     *
+     * @param builder Column builder.
+     * @param colType ColumnType.
+     */
+    private static void setType(Builder builder, ColumnType colType) {
+        builder.type(convert(colType));
+
+        if (fixSizedTypes.contains(colType.typeSpec())) {
+            return;
+        }
+
+        switch (colType.typeSpec()) {
+            case BITMASK:
+            case BYTES:
+            case STRING:
+                int length = ((ColumnType.VarLenColumnType) colType).length();
+
+                if (length == 0) {
+                    length = Integer.MAX_VALUE;
+                }
+
+                builder.length(length);
+
+                return;
+            case DECIMAL:
+                ColumnType.DecimalColumnType numColType = (ColumnType.DecimalColumnType) colType;
+
+                builder.precision(numColType.precision());
+                builder.scale(numColType.scale());
+
+                return;
+            case NUMBER:
+                ColumnType.NumberColumnType numType = (ColumnType.NumberColumnType) colType;
+
+                builder.precision(numType.precision());
+
+                return;
+            case TIME:
+            case DATETIME:
+            case TIMESTAMP:
+                ColumnType.TemporalColumnType temporalColType = (ColumnType.TemporalColumnType) colType;
+
+                builder.precision(temporalColType.precision());
+
+                return;
+            default:
+                throw new IllegalArgumentException("Unknown type " + colType.typeSpec().name());
+        }
+    }
+}
diff --git a/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/definition/ColumnType.java b/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/definition/ColumnType.java
index 9b75d8e738..a9f4181da0 100644
--- a/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/definition/ColumnType.java
+++ b/modules/schema/src/testFixtures/java/org/apache/ignite/internal/schema/testutils/definition/ColumnType.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.schema.testutils.definition;
 
 import java.util.Objects;
+import org.apache.ignite.internal.catalog.Catalog;
 
 /**
  * Predefined column types.
@@ -156,8 +157,8 @@ public class ColumnType {
     public static DecimalColumnType decimal() {
         return new DecimalColumnType(
                 ColumnTypeSpec.DECIMAL,
-                DecimalColumnType.DEFAULT_PRECISION,
-                DecimalColumnType.DEFAULT_SCALE
+                Catalog.DEFAULT_DECIMAL_PRECISION,
+                Catalog.DEFAULT_DECIMAL_SCALE
         );
     }
 
@@ -166,11 +167,11 @@ public class ColumnType {
      * of 0 (seconds).
      *
      * @return Native type.
-     * @see TemporalColumnType#DEFAULT_TIME_PRECISION
+     * @see Catalog#DEFAULT_TIME_PRECISION
      * @see #time(int)
      */
     public static TemporalColumnType time() {
-        return new TemporalColumnType(ColumnTypeSpec.TIME, TemporalColumnType.DEFAULT_TIME_PRECISION);
+        return new TemporalColumnType(ColumnTypeSpec.TIME, Catalog.DEFAULT_TIME_PRECISION);
     }
 
     /**
@@ -194,11 +195,11 @@ public class ColumnType {
      * Returns timezone-free datetime encoded as (date, time) with the default time precision of 6 (microseconds).
      *
      * @return Native type.
-     * @see TemporalColumnType#DEFAULT_TIMESTAMP_PRECISION
+     * @see Catalog#DEFAULT_TIMESTAMP_PRECISION
      * @see #datetime(int)
      */
     public static TemporalColumnType datetime() {
-        return new TemporalColumnType(ColumnTypeSpec.DATETIME, TemporalColumnType.DEFAULT_TIMESTAMP_PRECISION);
+        return new TemporalColumnType(ColumnTypeSpec.DATETIME, Catalog.DEFAULT_TIMESTAMP_PRECISION);
     }
 
     /**
@@ -224,11 +225,11 @@ public class ColumnType {
      * (microseconds).
      *
      * @return Native type.
-     * @see TemporalColumnType#DEFAULT_TIMESTAMP_PRECISION
+     * @see Catalog#DEFAULT_TIMESTAMP_PRECISION
      * @see #timestamp(int)
      */
     public static TemporalColumnType timestamp() {
-        return new TemporalColumnType(ColumnTypeSpec.TIMESTAMP, TemporalColumnType.DEFAULT_TIMESTAMP_PRECISION);
+        return new TemporalColumnType(ColumnTypeSpec.TIMESTAMP, Catalog.DEFAULT_TIMESTAMP_PRECISION);
     }
 
     /**
@@ -315,12 +316,6 @@ public class ColumnType {
      * Decimal column type.
      */
     public static class DecimalColumnType extends ColumnType {
-        /** Default precision. */
-        public static final int DEFAULT_PRECISION = 19;
-
-        /** Default scale. */
-        public static final int DEFAULT_SCALE = 3;
-
         /** Precision. */
         private final int precision;
 
@@ -448,27 +443,6 @@ public class ColumnType {
      * Column type of variable length.
      */
     public static class TemporalColumnType extends ColumnType {
-        /**
-         * Default TIMESTAMP type precision: microseconds.
-         *
-         * <p>SQL99 part 2 section 6.1 syntax rule 30
-         */
-        public static final int DEFAULT_TIMESTAMP_PRECISION = 6;
-
-        /**
-         * Default TIME type precision: seconds.
-         *
-         * <p>SQL99 part 2 section 6.1 syntax rule 30
-         */
-        public static final int DEFAULT_TIME_PRECISION = 0;
-
-        /**
-         * Max TIME precision.
-         *
-         * <p>SQL99 part 2 section 6.1 syntax rule 32
-         */
-        public static final int MAX_TIME_PRECISION = 9;
-
         /** Fractional seconds precision. */
         private final int precision;
 
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 ca9e596478..bb702d4566 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
@@ -83,17 +83,15 @@ public class DdlCommandHandlerWrapper extends DdlCommandHandler {
 
             return tableManager.alterTableDropColumnAsync(DdlToCatalogCommandConverter.convert(dropCommand))
                     .handle(handleModificationResult(dropCommand.ifTableExists(), TableNotFoundException.class));
+        } else if (cmd instanceof AlterColumnCommand) {
+            return catalogManager.alterColumn(DdlToCatalogCommandConverter.convert((AlterColumnCommand) cmd))
+                    .handle(handleModificationResult(((AlterColumnCommand) cmd).ifTableExists(), TableNotFoundException.class));
         }
 
         // Handle command in usual way.
         CompletableFuture<Boolean> ddlCommandFuture = super.handle(cmd);
 
-        if (cmd instanceof AlterColumnCommand) {
-            return ddlCommandFuture
-                    .thenCompose(res -> catalogManager.alterColumn(DdlToCatalogCommandConverter.convert((AlterColumnCommand) cmd))
-                            .handle(handleModificationResult(((AlterColumnCommand) cmd).ifTableExists(), TableNotFoundException.class))
-                    );
-        } else if (cmd instanceof CreateIndexCommand) {
+        if (cmd instanceof CreateIndexCommand) {
             return ddlCommandFuture
                     .thenCompose(res -> {
                         AbstractIndexCommandParams params = DdlToCatalogCommandConverter.convert((CreateIndexCommand) cmd);
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 22eb89195b..4aecc984af 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
@@ -212,10 +212,17 @@ class DdlToCatalogCommandConverter {
     }
 
     private static ColumnParams convert(ColumnDefinition def) {
+        RelDataType type = def.type();
+
+        assert type != null;
+
         return ColumnParams.builder()
                 .name(def.name())
                 .type(TypeUtils.columnType(def.type()))
                 .nullable(def.nullable())
+                .precision(def.precision())
+                .scale(def.scale())
+                .length(def.precision())
                 .defaultValue(convert(def.defaultValueDefinition()))
                 .build();
     }
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
index 4371fe3651..a825e7a43d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java
@@ -24,7 +24,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
 import org.apache.calcite.sql.type.BasicSqlType;
 import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.ignite.internal.schema.TemporalNativeType;
+import org.apache.ignite.internal.catalog.Catalog;
 
 /**
  * Ignite type system.
@@ -54,7 +54,7 @@ public class IgniteTypeSystem extends RelDataTypeSystemImpl implements Serializa
             case TIME_WITH_LOCAL_TIME_ZONE:
             case TIMESTAMP:
             case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
-                return TemporalNativeType.MAX_TIME_PRECISION;
+                return Catalog.MAX_TIME_PRECISION;
             default:
                 return super.getMaxPrecision(typeName);
         }
@@ -66,7 +66,7 @@ public class IgniteTypeSystem extends RelDataTypeSystemImpl implements Serializa
         switch (typeName) {
             case TIMESTAMP: // DATETIME
             case TIMESTAMP_WITH_LOCAL_TIME_ZONE: // TIMESTAMP
-                return TemporalNativeType.DEFAULT_TIMESTAMP_PRECISION;
+                return Catalog.DEFAULT_TIMESTAMP_PRECISION;
             case FLOAT:
                 // TODO: https://issues.apache.org/jira/browse/IGNITE-18556
                 // Fixes leastRestrictive(FLOAT, DOUBLE) != leastRestrictive(DOUBLE, FLOAT).
diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index c8b933a7ad..834d63b0f1 100644
--- a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++ b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -101,9 +101,6 @@ import org.apache.ignite.internal.catalog.commands.DropTableParams;
 import org.apache.ignite.internal.catalog.descriptors.CatalogDataStorageDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor;
-import org.apache.ignite.internal.catalog.events.CatalogEvent;
-import org.apache.ignite.internal.catalog.events.CreateTableEventParameters;
-import org.apache.ignite.internal.catalog.events.DropTableEventParameters;
 import org.apache.ignite.internal.causality.CompletionListener;
 import org.apache.ignite.internal.causality.IncrementalVersionedValue;
 import org.apache.ignite.internal.cluster.management.ClusterManagementGroupManager;
@@ -1841,7 +1838,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
         }
     }
 
-    /** See {@link #dropTableAsync(String)} for details. */
+    /** See {@link #dropTableAsync(DropTableParams)} for details. */
     private CompletableFuture<Void> dropTableAsyncInternal(String name) {
         return tableAsyncInternal(name).thenCompose(tbl -> {
             // In case of drop it's an optimization that allows not to fire drop-change-closure if there's no such
@@ -2889,7 +2886,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
 
                         PrimaryKeyView priKey = chng.primaryKey();
 
-                        Set<String> colNamesToOrders = new HashSet<>(cols.namedListKeys());;
+                        Set<String> colNamesToOrders = new HashSet<>(cols.namedListKeys());
 
                         Set<String> colNames0 = new HashSet<>();
 
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
index 56bb7b6f85..a623e0d9cf 100644
--- a/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
+++ b/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
@@ -53,6 +53,7 @@ import java.time.temporal.Temporal;
 import java.util.BitSet;
 import java.util.Random;
 import java.util.UUID;
+import org.apache.ignite.internal.catalog.Catalog;
 import org.apache.ignite.internal.schema.ByteBufferRow;
 import org.apache.ignite.internal.schema.Column;
 import org.apache.ignite.internal.schema.InvalidTypeException;
@@ -64,7 +65,6 @@ import org.apache.ignite.internal.schema.marshaller.TupleMarshaller;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerException;
 import org.apache.ignite.internal.schema.marshaller.TupleMarshallerImpl;
 import org.apache.ignite.internal.schema.row.Row;
-import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
 import org.apache.ignite.internal.table.impl.DummySchemaManagerImpl;
 import org.apache.ignite.internal.testframework.IgniteTestUtils;
 import org.apache.ignite.table.Tuple;
@@ -643,8 +643,8 @@ public class MutableRowTupleAdapterTest {
     }
 
     private <T extends Temporal> T truncateToDefaultPrecision(T temporal) {
-        int precision = temporal instanceof Instant ? ColumnType.TemporalColumnType.DEFAULT_TIMESTAMP_PRECISION
-                : ColumnType.TemporalColumnType.DEFAULT_TIME_PRECISION;
+        int precision = temporal instanceof Instant ? Catalog.DEFAULT_TIMESTAMP_PRECISION
+                : Catalog.DEFAULT_TIME_PRECISION;
 
         return (T) temporal.with(NANO_OF_SECOND,
                 truncatePrecision(temporal.get(NANO_OF_SECOND), tailFactor(precision)));
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
index 43a381ac54..fef3c45331 100644
--- a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
+++ b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
@@ -60,12 +60,13 @@ import java.util.concurrent.Flow.Subscription;
 import java.util.concurrent.Phaser;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.LongFunction;
 import org.apache.ignite.configuration.NamedListView;
 import org.apache.ignite.internal.affinity.AffinityUtils;
 import org.apache.ignite.internal.baseline.BaselineManager;
 import org.apache.ignite.internal.catalog.CatalogManager;
+import org.apache.ignite.internal.catalog.commands.AlterTableAddColumnParams;
+import org.apache.ignite.internal.catalog.commands.DropTableParams;
 import org.apache.ignite.internal.catalog.descriptors.CatalogTableDescriptor;
 import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor;
 import org.apache.ignite.internal.cluster.management.ClusterManagementGroupManager;
@@ -94,10 +95,10 @@ import org.apache.ignite.internal.schema.SchemaManager;
 import org.apache.ignite.internal.schema.SchemaUtils;
 import org.apache.ignite.internal.schema.configuration.ExtendedTableChange;
 import org.apache.ignite.internal.schema.configuration.GcConfiguration;
-import org.apache.ignite.internal.schema.configuration.TableChange;
 import org.apache.ignite.internal.schema.configuration.TableView;
 import org.apache.ignite.internal.schema.configuration.TablesConfiguration;
 import org.apache.ignite.internal.schema.testutils.SchemaConfigurationConverter;
+import org.apache.ignite.internal.schema.testutils.SchemaToCatalogParamsConverter;
 import org.apache.ignite.internal.schema.testutils.builder.SchemaBuilders;
 import org.apache.ignite.internal.schema.testutils.definition.ColumnType;
 import org.apache.ignite.internal.schema.testutils.definition.TableDefinition;
@@ -389,7 +390,7 @@ public class TableManagerTest extends IgniteAbstractTest {
 
         TableManager tableManager = tblManagerFut.join();
 
-        await(tableManager.dropTableAsync(DYNAMIC_TABLE_FOR_DROP_NAME));
+        await(tableManager.dropTableAsync(DropTableParams.builder().schemaName("PUBLIC").tableName(DYNAMIC_TABLE_FOR_DROP_NAME).build()));
 
         verify(mvTableStorage).destroy();
         verify(txStateTableStorage).destroy();
@@ -414,33 +415,33 @@ public class TableManagerTest extends IgniteAbstractTest {
 
         createDistributionZone();
 
-        Consumer<TableChange> createTableChange = (TableChange change) ->
-                SchemaConfigurationConverter.convert(SchemaBuilders.tableBuilder("PUBLIC", DYNAMIC_TABLE_FOR_DROP_NAME).columns(
-                                SchemaBuilders.column("key", ColumnType.INT64).build(),
-                                SchemaBuilders.column("val", ColumnType.INT64).asNullable(true).build()
-                        ).withPrimaryKey("key").build(), change);
-
-        Function<TableChange, Boolean> addColumnChange = (TableChange change) -> {
-            change.changeColumns(cols -> {
-                int colIdx = change.columns().namedListKeys().stream().mapToInt(Integer::parseInt).max().getAsInt() + 1;
-
-                cols.create(String.valueOf(colIdx),
-                        colChg -> SchemaConfigurationConverter.convert(SchemaBuilders.column("name", ColumnType.string()).build(),
-                                colChg));
-
-            });
+        TableDefinition tableDef = SchemaBuilders.tableBuilder("PUBLIC", DYNAMIC_TABLE_FOR_DROP_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", ColumnType.INT64).asNullable(true).build()
+                )
+                .withPrimaryKey("key")
+                .build();
 
-            return true;
-        };
+        AlterTableAddColumnParams addColumnParams = AlterTableAddColumnParams.builder()
+                .schemaName("PUBLIC")
+                .tableName(DYNAMIC_TABLE_FOR_DROP_NAME)
+                .columns(List.of(
+                       SchemaToCatalogParamsConverter.convert(SchemaBuilders.column("name", ColumnType.string()).build())
+                ))
+                .build();
 
         TableManager igniteTables = tableManager;
 
         assertThrows(IgniteException.class,
-                () -> igniteTables.createTableAsync(DYNAMIC_TABLE_FOR_DROP_NAME, ZONE_NAME, createTableChange));
+                () -> igniteTables.createTableAsync(SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, tableDef)));
 
-        assertThrows(IgniteException.class, () -> igniteTables.alterTableAsync(DYNAMIC_TABLE_FOR_DROP_NAME, addColumnChange));
+        assertThrows(IgniteException.class, () -> igniteTables.alterTableAddColumnAsync(addColumnParams));
 
-        assertThrows(IgniteException.class, () -> igniteTables.dropTableAsync(DYNAMIC_TABLE_FOR_DROP_NAME));
+        assertThrows(IgniteException.class, () -> igniteTables.dropTableAsync(DropTableParams.builder()
+                .schemaName(tableDef.schemaName())
+                .tableName(tableDef.name())
+                .build()));
 
         assertThrows(IgniteException.class, () -> igniteTables.tables());
         assertThrows(IgniteException.class, () -> igniteTables.tablesAsync());
@@ -633,8 +634,9 @@ public class TableManagerTest extends IgniteAbstractTest {
         assertNotNull(table);
 
         assertThrows(RuntimeException.class,
-                () -> await(tblManagerFut.join().createTableAsync(DYNAMIC_TABLE_NAME, ZONE_NAME,
-                        tblCh -> SchemaConfigurationConverter.convert(scmTbl, tblCh))));
+                () -> await(tblManagerFut.join().createTableAsync(
+                        SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, scmTbl)
+                )));
 
         assertSame(table, tblManagerFut.join().table(scmTbl.name()));
     }
@@ -823,8 +825,8 @@ public class TableManagerTest extends IgniteAbstractTest {
 
         createDistributionZone();
 
-        CompletableFuture<Table> tbl2Fut = tableManager.createTableAsync(tableDefinition.name(), ZONE_NAME,
-                tblCh -> SchemaConfigurationConverter.convert(tableDefinition, tblCh)
+        CompletableFuture<Table> tbl2Fut = tableManager.createTableAsync(
+                SchemaToCatalogParamsConverter.toCreateTable(ZONE_NAME, tableDefinition)
         );
 
         assertTrue(createTblLatch.await(10, TimeUnit.SECONDS));