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

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


The following commit(s) were added to refs/heads/main by this push:
     new e3221a56be4 IGNITE-25462 Get rid of SafeCustomTypeInternalConversion 
(#6623)
e3221a56be4 is described below

commit e3221a56be4cdc73b7f8902d7890d4b5e0c00a8c
Author: korlov42 <[email protected]>
AuthorDate: Mon Sep 22 14:00:09 2025 +0300

    IGNITE-25462 Get rid of SafeCustomTypeInternalConversion (#6623)
---
 .../engine/datatypes/tests/BaseDataTypeTest.java   |   3 +-
 modules/sql-engine/src/main/codegen/config.fmpp    |   1 -
 .../sql/engine/exec/exp/ConverterUtils.java        |   3 +-
 .../sql/engine/exec/exp/CustomTypesConversion.java |  93 ----------
 .../sql/engine/exec/exp/RexToLixTranslator.java    |   3 +-
 .../sql/engine/exec/exp/agg/Accumulators.java      |  11 +-
 .../internal/sql/engine/externalize/RelJson.java   |  12 --
 .../sql/engine/prepare/IgniteSqlValidator.java     |  96 +---------
 .../sql/engine/prepare/IgniteTypeCoercion.java     |  46 +----
 .../internal/sql/engine/rex/IgniteRexBuilder.java  |  16 +-
 .../sql/engine/sql/IgniteSqlTypeNameSpec.java      |  98 -----------
 .../sql/engine/sql/fun/IgniteSqlOperatorTable.java |  19 +-
 .../sql/fun/NotCustomTypeOperandTypeChecker.java   |  58 ------
 .../internal/sql/engine/type/IgniteCustomType.java | 148 ----------------
 .../engine/type/IgniteCustomTypeCoercionRules.java | 125 -------------
 .../sql/engine/type/IgniteCustomTypeSpec.java      | 160 -----------------
 .../sql/engine/type/IgniteTypeFactory.java         | 195 +--------------------
 .../util/SafeCustomTypeInternalConversion.java     |  66 -------
 .../ignite/internal/sql/engine/util/TypeUtils.java |  68 ++-----
 .../engine/prepare/LeastRestrictiveTypesTest.java  |  89 ----------
 .../internal/sql/engine/util/TypeUtilsTest.java    |  51 ------
 21 files changed, 44 insertions(+), 1317 deletions(-)

diff --git 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/tests/BaseDataTypeTest.java
 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/tests/BaseDataTypeTest.java
index 7018052a759..d8332b85bb0 100644
--- 
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/tests/BaseDataTypeTest.java
+++ 
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/datatypes/tests/BaseDataTypeTest.java
@@ -28,7 +28,6 @@ import java.util.stream.Stream;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.ignite.internal.app.IgniteImpl;
 import org.apache.ignite.internal.sql.BaseSqlIntegrationTest;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeSpec;
 import org.apache.ignite.internal.sql.engine.util.Commons;
 import org.apache.ignite.internal.sql.engine.util.NativeTypeWrapper;
 import org.apache.ignite.internal.sql.engine.util.QueryChecker;
@@ -40,7 +39,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.params.provider.Arguments;
 
 /**
- * Base class for test cases for data types including {@link 
IgniteCustomTypeSpec custom data types}.
+ * Base class for test cases for data types.
  *
  * <p>Usage:
  * <ul>
diff --git a/modules/sql-engine/src/main/codegen/config.fmpp 
b/modules/sql-engine/src/main/codegen/config.fmpp
index cdbd066449e..7fd7489719f 100644
--- a/modules/sql-engine/src/main/codegen/config.fmpp
+++ b/modules/sql-engine/src/main/codegen/config.fmpp
@@ -59,7 +59,6 @@ data: {
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlIndexType",
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlAlterZoneSet",
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlAlterZoneRenameTo",
-      "org.apache.ignite.internal.sql.engine.sql.IgniteSqlTypeNameSpec",
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlAlterZoneSetDefault",
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlKill",
       "org.apache.ignite.internal.sql.engine.sql.IgniteSqlKillObjectType",
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ConverterUtils.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ConverterUtils.java
index 18cffd6d5e5..5be9dd63e2a 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ConverterUtils.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/ConverterUtils.java
@@ -331,8 +331,7 @@ public class ConverterUtils {
             return Expressions.call(UUID.class, "fromString", operand);
         }
 
-        var toCustomType = CustomTypesConversion.INSTANCE.tryConvert(operand, 
toType);
-        return toCustomType != null ? toCustomType : 
EnumUtils.convert(operand, toType);
+        return EnumUtils.convert(operand, toType);
     }
 
     private static boolean isA(Type fromType, Primitive primitive) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/CustomTypesConversion.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/CustomTypesConversion.java
deleted file mode 100644
index f1dac993065..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/CustomTypesConversion.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.sql.engine.exec.exp;
-
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-import org.apache.calcite.linq4j.tree.Expression;
-import org.apache.calcite.linq4j.tree.Expressions;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.apache.ignite.internal.sql.engine.util.Commons;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Provides cast expressions for {@link IgniteCustomType custom data types}.
- */
-final class CustomTypesConversion {
-
-    static final CustomTypesConversion INSTANCE = new 
CustomTypesConversion(Commons.typeFactory());
-
-    private final Map<Class<?>, Function<Expression, Expression>> 
castByInternalType = new HashMap<>();
-
-    private final Map<String, Function<Expression, Expression>> castByTypeName 
= new HashMap<>();
-
-    private CustomTypesConversion(IgniteTypeFactory typeFactory) {
-        // IgniteCustomType: Add cast function implementations.
-        var customTypeSpecs = typeFactory.getCustomTypeSpecs();
-
-        for (var spec : customTypeSpecs.values()) {
-            // We use Object as an argument because:
-            //
-            // 1. type info is erased for dynamic parameters. See 
DataContextInputGetter in RexExecutorImpl.
-            // 2. so internal calls will throw a CastCastException instead of 
a NoSuchMethodError in runtime
-            // (It would be even better if such casts were not necessary).
-
-            Function<Expression, Expression> castExpr =
-                    (operand) ->  Expressions.call(spec.castFunction(), 
Expressions.convert_(operand, Object.class));
-            // ??? Should we add a hook here that can short-circuit when a 
custom type can not be converted?
-
-            castByInternalType.put(spec.storageType(), castExpr);
-            castByTypeName.put(spec.typeName(), castExpr);
-        }
-    }
-
-    /**
-     * If the specified {@code internalType} represents is a custom data type,
-     * then this method returns expression that converts an operand to it. 
Otherwise returns {@code null}.
-     * */
-    @Nullable
-    Expression tryConvert(Expression operand, Type internalType) {
-        // internal type is always a Class.
-        var cast = castByInternalType.get((Class<?>) internalType);
-        if (cast == null) {
-            return null;
-        }
-
-        return cast.apply(operand);
-    }
-
-    /**
-     * If the specified {@code targetType} represents is a custom data type,
-     * then this method returns expression that converts an operand to it. 
Otherwise returns {@code null}.
-     * */
-    @Nullable
-    Expression tryConvert(Expression operand, RelDataType targetType) {
-        if (!(targetType instanceof IgniteCustomType)) {
-            return null;
-        }
-
-        var customType = (IgniteCustomType) targetType;
-        Function<Expression, Expression> cast = 
castByTypeName.get(customType.getCustomTypeName());
-
-        return cast.apply(operand);
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
index 04f7ffb6d48..74f81490bb1 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java
@@ -418,8 +418,7 @@ public class RexToLixTranslator implements 
RexVisitor<RexToLixTranslator.Result>
       Expression roundingMode = 
Expressions.constant(typeFactory.getTypeSystem().roundingMode());
       return Expressions.call(BuiltInMethod.VARIANT_CREATE.method, 
roundingMode, operand, rtti);
     case ANY:
-      var toCustomType = CustomTypesConversion.INSTANCE.tryConvert(operand, 
targetType);
-      return (toCustomType != null) ? toCustomType: operand;
+      return operand;
 
     case VARBINARY:
     case BINARY:
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
index 2ff21e0e03a..a2681284095 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/agg/Accumulators.java
@@ -42,7 +42,6 @@ import org.apache.calcite.sql.fun.SqlLiteralAggFunction;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.ignite.internal.catalog.commands.CatalogUtils;
 import org.apache.ignite.internal.sql.engine.exec.exp.IgniteSqlFunctions;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.Commons;
 import org.apache.ignite.internal.sql.engine.util.IgniteMath;
@@ -191,9 +190,7 @@ public class Accumulators {
             case VARBINARY:
                 return min ? VarBinaryMinMax.MIN_FACTORY : 
VarBinaryMinMax.MAX_FACTORY;
             default:
-                if (type instanceof IgniteCustomType) {
-                    return MinMaxAccumulator.newAccumulator(min, typeFactory, 
type);
-                } else if (type.getSqlTypeName() == ANY) {
+                if (type.getSqlTypeName() == ANY) {
                     throw unsupportedAggregateFunction(call);
                 } else {
                     return MinMaxAccumulator.newAccumulator(min, typeFactory, 
type);
@@ -204,7 +201,7 @@ public class Accumulators {
     private Supplier<Accumulator> singleValueFactory(AggregateCall call) {
         RelDataType type = call.getType();
 
-        if (type.getSqlTypeName() == ANY && !(type instanceof 
IgniteCustomType)) {
+        if (type.getSqlTypeName() == ANY) {
             throw unsupportedAggregateFunction(call);
         }
 
@@ -214,7 +211,7 @@ public class Accumulators {
     private Supplier<Accumulator> anyValueFactory(AggregateCall call) {
         RelDataType type = call.getType();
 
-        if (type.getSqlTypeName() == ANY && !(type instanceof 
IgniteCustomType)) {
+        if (type.getSqlTypeName() == ANY) {
             throw unsupportedAggregateFunction(call);
         }
 
@@ -224,7 +221,7 @@ public class Accumulators {
     private Supplier<Accumulator> groupingFactory(AggregateCall call) {
         RelDataType type = call.getType();
 
-        if (type.getSqlTypeName() == ANY && !(type instanceof 
IgniteCustomType)) {
+        if (type.getSqlTypeName() == ANY) {
             throw unsupportedAggregateFunction(call);
         }
 
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
index e2e1af2e988..b01d0a50af2 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
@@ -116,7 +116,6 @@ import 
org.apache.ignite.internal.sql.engine.trait.DistributionFunction;
 import org.apache.ignite.internal.sql.engine.trait.DistributionTrait;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.Commons;
 import org.apache.ignite.internal.util.IgniteUtils;
@@ -383,13 +382,6 @@ class RelJson {
             if (node.getSqlTypeName().allowsScale()) {
                 map.put("scale", node.getScale());
             }
-            if (node instanceof IgniteCustomType) {
-                // In case of a custom data type we must store its name to 
correctly
-                // deserialize it because we want to distinguish a custom type 
from ANY.
-                IgniteCustomType customType = (IgniteCustomType) node;
-                map.put("type", toJson(SqlTypeName.ANY));
-                map.put("customType", customType.getCustomTypeName());
-            }
             return map;
         }
     }
@@ -730,8 +722,6 @@ class RelJson {
             }
 
             Object fields = map.get("fields");
-            // IgniteCustomType: In case of a custom data type JSON must 
contain a name of that type.
-            String customType = (String) map.get("customType");
 
             if (fields != null) {
                 return toType(typeFactory, fields);
@@ -753,8 +743,6 @@ class RelJson {
                             toType(typeFactory, map.get("keyType")),
                             toType(typeFactory, map.get("valueType"))
                     );
-                } else if (sqlTypeName == SqlTypeName.ANY && customType != 
null) {
-                    type = ((IgniteTypeFactory) 
typeFactory).createCustomType(customType, precision);
                 } else if (precision == null) {
                     type = typeFactory.createSqlType(sqlTypeName);
                 } else if (scale == null) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
index bb5bb0d9f8f..702241784ca 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
@@ -68,7 +68,6 @@ import org.apache.calcite.sql.SqlCharStringLiteral;
 import org.apache.calcite.sql.SqlDataTypeSpec;
 import org.apache.calcite.sql.SqlDelete;
 import org.apache.calcite.sql.SqlDynamicParam;
-import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlInsert;
 import org.apache.calcite.sql.SqlIntervalLiteral;
@@ -78,7 +77,6 @@ import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlMerge;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlNodeList;
-import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.SqlTypeNameSpec;
@@ -110,9 +108,6 @@ import 
org.apache.ignite.internal.sql.engine.schema.IgniteDataSource;
 import org.apache.ignite.internal.sql.engine.schema.IgniteSystemView;
 import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
 import org.apache.ignite.internal.sql.engine.sql.IgniteSqlExplain;
-import org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import 
org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeCoercionRules;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.Commons;
 import org.apache.ignite.internal.sql.engine.util.IgniteCustomAssignmentsRules;
@@ -346,13 +341,6 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
 
             boolean canAssign = SqlTypeUtil.canAssignFrom(targetType, 
sourceType);
 
-            if (canAssign && ((targetType instanceof IgniteCustomType) || 
(sourceType instanceof IgniteCustomType))) {
-                // SqlTypeUtil.canAssignFrom doesn't account for custom types, 
therefore need to check
-                // this explicitly. Since at the moment there are no custom 
types which can be assigned from
-                // each other, let's just check for equality.
-                canAssign = SqlTypeUtil.equalSansNullability(typeFactory, 
targetType, sourceType);
-            }
-
             if (!canAssign) {
                 // Throws proper exception if assignment is not possible due to
                 // problem with dynamic parameter type inference.
@@ -841,26 +829,6 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
             return dataType;
         }
 
-        // Comparison and arithmetic operators are SqlCalls.
-        SqlCall sqlCall = (SqlCall) expr;
-        var lhs = getValidatedNodeType(sqlCall.operand(0));
-        var rhs = getValidatedNodeType(sqlCall.operand(1));
-
-        // IgniteCustomType:
-        // Check compatibility for operands of binary comparison operation 
between custom data types vs built-in SQL types.
-        // We get here because in calcite ANY type can be assigned/casted to 
all other types.
-        // This check can be a part of some SqlOperandTypeChecker?
-
-        if (lhs instanceof IgniteCustomType || rhs instanceof 
IgniteCustomType) {
-            boolean lhsRhsCompatible = 
TypeUtils.typeFamiliesAreCompatible(typeFactory, lhs, rhs);
-            boolean rhsLhsCompatible = 
TypeUtils.typeFamiliesAreCompatible(typeFactory, rhs, lhs);
-
-            if (!lhsRhsCompatible && !rhsLhsCompatible) {
-                SqlCallBinding callBinding = new SqlCallBinding(this, scope, 
(SqlCall) expr);
-                throw callBinding.newValidationSignatureError();
-            }
-        }
-
         return dataType;
     }
 
@@ -992,24 +960,9 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
             return;
         }
 
-        RelDataType returnCustomType = returnType instanceof IgniteCustomType 
? returnType : null;
-        RelDataType operandCustomType = operandType instanceof 
IgniteCustomType ? operandType : null;
-
-        IgniteCustomTypeCoercionRules coercionRules = 
typeFactory().getCustomTypeCoercionRules();
-
-        boolean check;
-        if (operandCustomType != null && returnCustomType != null) {
-            // it`s not allowed to convert between different custom types for 
now.
-            check = SqlTypeUtil.equalSansNullability(typeFactory, operandType, 
returnType);
-        } else if (operandCustomType != null) {
-            check = coercionRules.needToCast(returnType, (IgniteCustomType) 
operandCustomType);
-        } else if (returnCustomType != null) {
-            check = coercionRules.needToCast(operandType, (IgniteCustomType) 
returnCustomType);
-        } else {
-            check = IgniteCustomAssignmentsRules.instance().canApplyFrom(
-                    returnType.getSqlTypeName(), operandType.getSqlTypeName()
-            );
-        }
+        boolean check = IgniteCustomAssignmentsRules.instance().canApplyFrom(
+                returnType.getSqlTypeName(), operandType.getSqlTypeName()
+        );
 
         if (!check) {
             throw newValidationError(expr,
@@ -1437,54 +1390,11 @@ public class IgniteSqlValidator extends 
SqlValidatorImpl {
                 throw newValidationError(call, 
IgniteResource.INSTANCE.unsupportedExpression("String literal expected"));
             }
             super.validateCall(call, scope);
-
-            checkCallsWithCustomTypes(call, scope);
         } finally {
             callScopes.pop();
         }
     }
 
-    private void checkCallsWithCustomTypes(SqlCall call, SqlValidatorScope 
scope) {
-        SqlOperator operator = call.getOperator();
-
-        // IgniteCustomType:
-        // Since custom data types use ANY that is a catch all type for type 
checkers,
-        // if a function is called with custom data type argument does not 
belong to CUSTOM_TYPE_FUNCTIONS,
-        // then this should be considered a validation error.
-
-        if (call.getOperandList().isEmpty()
-                || !(operator instanceof SqlFunction)
-                || 
IgniteSqlOperatorTable.CUSTOM_TYPE_FUNCTIONS.contains(operator)) {
-            return;
-        }
-
-        for (SqlNode node : call.getOperandList()) {
-            RelDataType type = getValidatedNodeTypeIfKnown(node);
-            // Argument type is not known yet (alias) or it is not a custom 
data type.
-            if ((!(type instanceof IgniteCustomType))) {
-                continue;
-            }
-
-            String name = call.getOperator().getName();
-
-            // Call to getAllowedSignatures throws NPE, if operandTypeChecker 
is null.
-            if (operator.getOperandTypeChecker() != null) {
-                // If signatures are available, then return:
-                // Cannot apply 'F' to arguments of type 'F(<ARG_TYPE>)'. 
Supported form(s): 'F(<TYPE>)'
-                String allowedSignatures = operator.getAllowedSignatures();
-                throw newValidationError(call,
-                        RESOURCE.canNotApplyOp2Type(name,
-                                call.getCallSignature(this, scope),
-                                allowedSignatures));
-            } else {
-                // Otherwise return an error w/o supported forms:
-                // Cannot apply 'F' to arguments of type 'F(<ARG_TYPE>)'
-                throw newValidationError(call, 
IgniteResource.INSTANCE.canNotApplyOp2Type(name,
-                        call.getCallSignature(this, scope)));
-            }
-        }
-    }
-
     /** {@inheritDoc} */
     @Override
     protected void inferUnknownTypes(RelDataType inferredType, 
SqlValidatorScope scope, SqlNode node) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
index f319fe74002..6a12754742a 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteTypeCoercion.java
@@ -62,12 +62,9 @@ import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.sql.validate.implicit.TypeCoercionImpl;
 import org.apache.calcite.util.Util;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import 
org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeCoercionRules;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.IgniteCustomAssignmentsRules;
 import org.apache.ignite.internal.sql.engine.util.IgniteResource;
-import org.apache.ignite.internal.sql.engine.util.TypeUtils;
 import org.jetbrains.annotations.Nullable;
 
 /** Implicit type cast implementation. */
@@ -465,9 +462,6 @@ public class IgniteTypeCoercion extends TypeCoercionImpl {
             if (SqlTypeUtil.isIntType(fromType) && fromType.getSqlTypeName() 
!= toType.getSqlTypeName()) {
                 return true;
             }
-        } else if (toType.getSqlTypeName() == SqlTypeName.ANY || 
fromType.getSqlTypeName() == SqlTypeName.ANY) {
-            // IgniteCustomType: whether we need implicit cast from one type 
to another.
-            return TypeUtils.customDataTypeNeedCast(typeFactory, fromType, 
toType);
         } else if (SqlTypeUtil.isNull(fromType)) {
             // Need to cast NULL literal because type-checkers of built-in 
function cannot properly handle explicit NULL
             // since it belongs to a particular type family.
@@ -620,46 +614,20 @@ public class IgniteTypeCoercion extends TypeCoercionImpl {
             return null;
         }
 
-        // IgniteCustomType: If one of the arguments is a custom data type,
-        // check whether it is possible to convert another type to it.
-        // Returns not null to indicate that a CAST operation can be added
-        // to convert another type to this custom data type.
-        if (type1 instanceof IgniteCustomType) {
-            IgniteCustomType to = (IgniteCustomType) type1;
-            return tryCustomTypeCoercionRules(type2, to);
-        } else if (type2 instanceof IgniteCustomType) {
-            IgniteCustomType to = (IgniteCustomType) type2;
-            return tryCustomTypeCoercionRules(type1, to);
-        } else {
-            SqlTypeName t1 = type1.getSqlTypeName();
-            SqlTypeName t2 = type2.getSqlTypeName();
-
-            if (t1 == SqlTypeName.TIMESTAMP && t2 == 
SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE
-                    || t1 == SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE && t2 
== SqlTypeName.TIMESTAMP) {
-                return typeFactory.leastRestrictive(List.of(type1, type2));
-            } else {
-                return super.commonTypeForBinaryComparison(type1, type2);
-            }
-        }
-    }
+        SqlTypeName t1 = type1.getSqlTypeName();
+        SqlTypeName t2 = type2.getSqlTypeName();
 
-    private @Nullable RelDataType tryCustomTypeCoercionRules(RelDataType from, 
IgniteCustomType to) {
-        IgniteCustomTypeCoercionRules typeCoercionRules = 
typeFactory.getCustomTypeCoercionRules();
-        if (typeCoercionRules.needToCast(from, to)) {
-            return to;
+        if (t1 == SqlTypeName.TIMESTAMP && t2 == 
SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE
+                || t1 == SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE && t2 == 
SqlTypeName.TIMESTAMP) {
+            return typeFactory.leastRestrictive(List.of(type1, type2));
         } else {
-            return null;
+            return super.commonTypeForBinaryComparison(type1, type2);
         }
     }
 
     private static SqlNode castTo(SqlNode node, RelDataType type) {
         SqlDataTypeSpec targetDataType;
-        if (type instanceof IgniteCustomType) {
-            var customType = (IgniteCustomType) type;
-            var nameSpec = customType.createTypeNameSpec();
-
-            targetDataType = new SqlDataTypeSpec(nameSpec, SqlParserPos.ZERO);
-        } else if (type.getSqlTypeName() == SqlTypeName.UUID) {
+        if (type.getSqlTypeName() == SqlTypeName.UUID) {
             targetDataType = new SqlDataTypeSpec(
                     new SqlBasicTypeNameSpec(SqlTypeName.UUID, 
SqlParserPos.ZERO), null, type.isNullable(), SqlParserPos.ZERO
             );
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
index abc6c611815..ae08c688f1a 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/rex/IgniteRexBuilder.java
@@ -30,12 +30,11 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.util.NlsString;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.jetbrains.annotations.Nullable;
 
 /**
- * {@link RexBuilder} that provides support for {@link IgniteCustomType custom 
data types}.
+ * Extension of {@link RexBuilder}.
  */
 public class IgniteRexBuilder extends RexBuilder {
     public static final IgniteRexBuilder INSTANCE = new 
IgniteRexBuilder(IgniteTypeFactory.INSTANCE);
@@ -52,18 +51,6 @@ public class IgniteRexBuilder extends RexBuilder {
     /** {@inheritDoc} **/
     @Override
     public RexNode makeLiteral(@Nullable Object value, RelDataType type, 
boolean allowCast, boolean trim) {
-        // We need to override this method because otherwise
-        // default implementation will call RexBuilder::guessType(@Nullable 
Object value)
-        // for a custom data type which will then raise the following 
assertion:
-        //
-        //  throw new AssertionError("unknown type " + value.getClass());
-        //
-        if (value != null && type instanceof IgniteCustomType) {
-            // IgniteCustomType: Not comparable types are not supported.
-            assert value instanceof Comparable : "Not comparable 
IgniteCustomType:" + type + ". value: " + value;
-            return makeLiteral((Comparable<?>) value, type, 
type.getSqlTypeName());
-        }
-
         if (value != null) {
             if (type.getSqlTypeName() == SqlTypeName.CHAR) {
                 if (type.isNullable()) {
@@ -123,6 +110,7 @@ public class IgniteRexBuilder extends RexBuilder {
     }
 
     // Copy-pasted from RexBuilder.
+    @SuppressWarnings("MethodOverridesInaccessibleMethodOfSuper")
     private RexNode makeCastIntervalToExact(SqlParserPos pos, RelDataType 
toType, RexNode exp) {
         TimeUnit endUnit = exp.getType().getSqlTypeName().getEndUnit();
         TimeUnit baseUnit = baseUnit(exp.getType().getSqlTypeName());
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlTypeNameSpec.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlTypeNameSpec.java
deleted file mode 100644
index 0a703e9aadb..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/IgniteSqlTypeNameSpec.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.sql.engine.sql;
-
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlLiteral;
-import org.apache.calcite.sql.SqlTypeNameSpec;
-import org.apache.calcite.sql.SqlWriter;
-import org.apache.calcite.sql.parser.SqlParserPos;
-import org.apache.calcite.sql.validate.SqlValidator;
-import org.apache.calcite.util.Litmus;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Type name specification that allows to derive custom data types.
- *
- * @see org.apache.ignite.internal.sql.engine.type.IgniteCustomType
- */
-public final class IgniteSqlTypeNameSpec extends SqlTypeNameSpec {
-
-    /** Undefined precision. Use the same value as apache calcite. **/
-    private static final int UNDEFINED_PRECISION = -1;
-
-    /** Precision, if specified. **/
-    private final int precision;
-
-    /**
-     * Creates a {@code SqlTypeNameSpec}.
-     *
-     * @param name Name of the type
-     * @param precision -1 if not specified.
-     * @param pos Parser position, must not be null
-     */
-    public IgniteSqlTypeNameSpec(SqlIdentifier name, @Nullable SqlLiteral 
precision, SqlParserPos pos) {
-        super(name, pos);
-        this.precision = precision != null ? precision.intValue(true) : 
UNDEFINED_PRECISION;
-    }
-
-    /**
-     * Creates a {@code SqlTypeNameSpec} for the specified type with undefined 
precision.
-     *
-     * @param name Name of the type
-     * @param pos Parser position, must not be null
-     */
-    public IgniteSqlTypeNameSpec(SqlIdentifier name, SqlParserPos pos) {
-        this(name, null, pos);
-    }
-
-    /** {@inheritDoc} **/
-    @Override
-    public RelDataType deriveType(SqlValidator validator) {
-        IgniteTypeFactory typeFactory = (IgniteTypeFactory) 
validator.getTypeFactory();
-        return typeFactory.createCustomType(getTypeName().getSimple(), 
precision);
-    }
-
-    /** {@inheritDoc} **/
-    @Override
-    public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
-        writer.keyword(getTypeName().getSimple());
-
-        if (precision != -1) {
-            SqlWriter.Frame frame = 
writer.startList(SqlWriter.FrameTypeEnum.FUN_CALL, "(", ")");
-            writer.print(precision);
-            writer.endList(frame);
-        }
-    }
-
-    /** {@inheritDoc} **/
-    @Override
-    public boolean equalsDeep(SqlTypeNameSpec spec, Litmus litmus) {
-        if (!(spec instanceof IgniteSqlTypeNameSpec)) {
-            return litmus.fail("{} != {}", this, spec);
-        } else {
-            IgniteSqlTypeNameSpec that = (IgniteSqlTypeNameSpec) spec;
-            if (that.precision != precision) {
-                return litmus.fail("{} != {}", this, spec);
-            }
-            return litmus.succeed();
-        }
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
index dd8edff3533..b34f59d1a0b 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
@@ -58,9 +58,6 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
     private static final SqlSingleOperandTypeChecker SAME_SAME =
             new SameFamilyOperandTypeChecker(2);
 
-    private static final SqlSingleOperandTypeChecker NOT_CUSTOM_TYPE =
-            new NotCustomTypeOperandTypeChecker();
-
     private static final SqlOperandTypeChecker DATETIME_MATCHING_INTERVAL =
             new SqlDateTimeIntervalTypeChecker(true);
 
@@ -70,22 +67,22 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
     private static final SqlOperandTypeChecker PLUS_OPERATOR_TYPES_CHECKER =
             OperandTypes.NUMERIC_NUMERIC.and(SAME_SAME)
                     .or(OperandTypes.INTERVAL_SAME_SAME)
-                    .or(DATETIME_MATCHING_INTERVAL.and(NOT_CUSTOM_TYPE))
-                    .or(MATCHING_INTERVAL_DATETIME.and(NOT_CUSTOM_TYPE));
+                    .or(DATETIME_MATCHING_INTERVAL)
+                    .or(MATCHING_INTERVAL_DATETIME);
 
     private static final SqlOperandTypeChecker MINUS_OPERATOR_TYPES_CHECKER =
             OperandTypes.NUMERIC_NUMERIC.and(SAME_SAME)
                     .or(OperandTypes.INTERVAL_SAME_SAME)
-                    
.or(OperandTypes.DATETIME_INTERVAL.and(DATETIME_MATCHING_INTERVAL).and(NOT_CUSTOM_TYPE));
+                    
.or(OperandTypes.DATETIME_INTERVAL.and(DATETIME_MATCHING_INTERVAL));
 
     private static final SqlSingleOperandTypeChecker 
DIVISION_OPERATOR_TYPES_CHECKER =
             OperandTypes.NUMERIC_NUMERIC.and(SAME_SAME)
-                    .or(OperandTypes.INTERVAL_NUMERIC.and(NOT_CUSTOM_TYPE));
+                    .or(OperandTypes.INTERVAL_NUMERIC);
 
     public static final SqlSingleOperandTypeChecker 
MULTIPLY_OPERATOR_TYPES_CHECKER =
             OperandTypes.NUMERIC_NUMERIC.and(SAME_SAME)
-                    .or(OperandTypes.INTERVAL_NUMERIC.and(NOT_CUSTOM_TYPE))
-                    .or(OperandTypes.NUMERIC_INTERVAL.and(NOT_CUSTOM_TYPE));
+                    .or(OperandTypes.INTERVAL_NUMERIC)
+                    .or(OperandTypes.NUMERIC_INTERVAL);
 
     public static final SqlFunction LENGTH =
             new SqlFunction(
@@ -458,13 +455,13 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
      * {@code EVERY} aggregate function.
      */
     public static final SqlAggFunction EVERY =
-            new SqlMinMaxAggFunction("EVERY", SqlKind.MIN, 
OperandTypes.BOOLEAN.and(NOT_CUSTOM_TYPE));
+            new SqlMinMaxAggFunction("EVERY", SqlKind.MIN, 
OperandTypes.BOOLEAN);
 
     /**
      * {@code SOME} aggregate function.
      */
     public static final SqlAggFunction SOME =
-            new SqlMinMaxAggFunction("SOME", SqlKind.MAX, 
OperandTypes.BOOLEAN.and(NOT_CUSTOM_TYPE));
+            new SqlMinMaxAggFunction("SOME", SqlKind.MAX, 
OperandTypes.BOOLEAN);
 
     /**
      * The <code>CURRENT_TIMESTAMP [(<i>precision</i>)]</code> function.
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/NotCustomTypeOperandTypeChecker.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/NotCustomTypeOperandTypeChecker.java
deleted file mode 100644
index 35116dca71f..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/NotCustomTypeOperandTypeChecker.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.sql.engine.sql.fun;
-
-import org.apache.calcite.sql.SqlCallBinding;
-import org.apache.calcite.sql.SqlNode;
-import org.apache.calcite.sql.SqlOperator;
-import org.apache.calcite.sql.type.SqlSingleOperandTypeChecker;
-import org.apache.ignite.internal.schema.AssemblyException;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-
-/**
- * Type checking strategy which makes sure there are no operands of custom 
types.
- */
-public class NotCustomTypeOperandTypeChecker implements 
SqlSingleOperandTypeChecker {
-    /*
-    By default, type checkers allows operands of type ANY. The problem is that 
it in fact may
-    represent custom type rather than be placeholder for any possible value. 
This type checker
-    makes sure that operand of type ANY is indeed placeholder for any type 
rather than operand
-    of a custom type.
-     */
-
-    @Override
-    public boolean checkSingleOperandType(SqlCallBinding callBinding, SqlNode 
operand, int operandIdx, boolean throwOnFailure) {
-        return !(callBinding.getOperandType(operandIdx) instanceof 
IgniteCustomType);
-    }
-
-    @Override
-    public boolean checkOperandTypes(SqlCallBinding callBinding, boolean 
throwOnFailure) {
-        for (int i = 0; i < callBinding.getOperandCount(); i++) {
-            if (!checkSingleOperandType(callBinding, callBinding.operand(i), 
i, throwOnFailure)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public String getAllowedSignatures(SqlOperator op, String opName) {
-        throw new AssemblyException("Should not be called");
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomType.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomType.java
deleted file mode 100644
index 7ab9711dad1..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomType.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.sql.engine.type;
-
-import org.apache.calcite.rel.type.RelDataTypeFamily;
-import org.apache.calcite.rel.type.RelDataTypeImpl;
-import org.apache.calcite.sql.SqlIdentifier;
-import org.apache.calcite.sql.SqlLiteral;
-import org.apache.calcite.sql.SqlNumericLiteral;
-import org.apache.calcite.sql.SqlTypeNameSpec;
-import org.apache.calcite.sql.parser.SqlParserPos;
-import org.apache.calcite.sql.type.SqlTypeFamily;
-import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.ignite.internal.sql.engine.exec.exp.agg.Accumulators;
-import org.apache.ignite.internal.sql.engine.prepare.IgniteSqlValidator;
-import org.apache.ignite.internal.sql.engine.sql.IgniteSqlTypeNameSpec;
-
-/**
- * A base class for custom data types.
- *
- * <p><b>Custom data type implementation check list.</b>
- *
- * <p>Create a subclass of {@link IgniteCustomType}.
- *
- * <p>Define {@link IgniteCustomTypeSpec type spec} for your type that 
describes the following properties:
- * <ul>
- *     <li>{@link IgniteCustomTypeSpec#typeName() type name}.</li>
- *     <li>{@link IgniteCustomTypeSpec#nativeType() native type}.</li>
- *     <li>{@link IgniteCustomTypeSpec#columnType() column type}.</li>
- *     <li>{@link IgniteCustomTypeSpec#storageType() storage type}.</li>
- *     <li>{@link IgniteCustomTypeSpec#castFunction() cast function}.
- *     See {@link IgniteCustomTypeSpec#getCastFunction(Class, String) 
getCastFunction}.
- *     </li>
- * </ul>
- *
- * <p>Code base contains comments that start with {@code IgniteCustomType:} to 
provide extra information.
- *
- * <p>Update {@link IgniteTypeFactory}'s constructor to register your type and 
to specify type coercion rules.
- *
- * <p>Update type inference for dynamic parameters in {@link 
IgniteSqlValidator}.
- *
- * <p>Further steps:
- * <ul>
- *     <li>Update an SQL parser generator code to support your type - see 
{@code DataTypeEx()}.</li>
- *     <li>Update {@link Accumulators}
- *     if your type supports some aggregation functions.
- *     By default all custom data type support {@code COUNT} and {@code 
ANY_VALUE}.</li>
- *     <li>Update serialisation/deserialisation in {@code RelJson} to store 
extra attributes if necessary.</li>
- *     <li>There probably some methods in {@link IgniteTypeSystem} that maybe 
subject to change
- *     when a custom data type is implemented.</li>
- * </ul>
- *
- * <p>Type conversion is implemented in {@code CustomTypesConversion} and uses 
rules defined for your custom type.
- *
- * <p>Client code/JDBC:
- * <ul>
- *     <li>Update {@code JdbcDatabaseMetadata::getTypeInfo} to return 
information about your type.</li>
- *     <li>Update {@code JdbcColumnMeta::typeName} to return the correct name 
for your time.</li>
- * </ul>
- *
- * <p><b>Update this documentation when you are going to change this 
procedure.</b>
- *
-*/
-public abstract class IgniteCustomType extends RelDataTypeImpl {
-
-    private final IgniteCustomTypeSpec spec;
-
-    private final boolean nullable;
-
-    private final int precision;
-
-    /** Constructor. */
-    protected IgniteCustomType(IgniteCustomTypeSpec spec, boolean nullable, 
int precision) {
-        this.spec = spec;
-        this.nullable = nullable;
-        this.precision = precision;
-
-        computeDigest();
-    }
-
-    /** Returns the name of this type. A short handfor {@code 
spec().typeName() }. **/
-    public final String getCustomTypeName() {
-        return spec.typeName();
-    }
-
-    /**
-     * Returns the {@link IgniteCustomTypeSpec specification} of this type.
-     */
-    public final IgniteCustomTypeSpec spec() {
-        return spec;
-    }
-
-    /** {@inheritDoc} */
-    @Override public final boolean isNullable() {
-        return nullable;
-    }
-
-    /** {@inheritDoc} */
-    @Override public RelDataTypeFamily getFamily() {
-        return SqlTypeFamily.ANY;
-    }
-
-    /** {@inheritDoc} */
-    @Override public final SqlTypeName getSqlTypeName() {
-        return SqlTypeName.ANY;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int getPrecision() {
-        return precision;
-    }
-
-    /** Creates an instance of this type with the specified nullability. **/
-    public abstract IgniteCustomType createWithNullability(boolean nullable);
-
-    /**
-     * Creates an {@link SqlTypeNameSpec} for this custom data type, which is 
used as an argument for the CAST function.
-     *
-     * @return An SQL type name spec.
-     */
-    public final SqlTypeNameSpec createTypeNameSpec() {
-        SqlIdentifier typeNameId = new SqlIdentifier(getCustomTypeName(), 
SqlParserPos.ZERO);
-
-        if (getPrecision() == PRECISION_NOT_SPECIFIED) {
-            return new IgniteSqlTypeNameSpec(typeNameId, SqlParserPos.ZERO);
-        } else {
-            SqlNumericLiteral precision = 
SqlLiteral.createExactNumeric(Integer.toString(getPrecision()), 
SqlParserPos.ZERO);
-
-            return new IgniteSqlTypeNameSpec(typeNameId, precision, 
SqlParserPos.ZERO);
-        }
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeCoercionRules.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeCoercionRules.java
deleted file mode 100644
index d74dc14ff44..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeCoercionRules.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.sql.engine.type;
-
-import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.calcite.sql.validate.implicit.TypeCoercion;
-import org.apache.ignite.internal.sql.engine.prepare.IgniteTypeCoercion;
-
-/**
- * Defines rules for coercing {@link SqlTypeName built-in SQL types} to {@link 
IgniteCustomType custom data types}.
- *
- * @see IgniteTypeCoercion ignite type coercion.
- * @see TypeCoercion calcite's TypeCoercion interface.
- */
-public final class IgniteCustomTypeCoercionRules {
-
-    private final Map<String, Set<SqlTypeName>> canCastFrom;
-
-    IgniteCustomTypeCoercionRules(Map<String, IgniteCustomTypeSpec> typeSpecs, 
Map<String, Set<SqlTypeName>> canCastFrom) {
-        for (var rule : canCastFrom.entrySet()) {
-            var typeName = rule.getKey();
-            if (!typeSpecs.containsKey(typeName)) {
-                var error = format("Unable to define type coercion rule. "
-                        + "Unexpected custom type: {}. Rules: {}. Known types: 
{}", typeName, rule.getValue(), typeSpecs.keySet()
-                );
-                throw new IllegalArgumentException(error);
-            }
-        }
-
-        this.canCastFrom = canCastFrom;
-    }
-
-    /**
-     * Checks whether the cast operation is needed to convert {@code fromType} 
to the custom type {@code toType}.
-     *
-     * <p>NOTE: <b>This method returns {@code false}, when called with the 
same argument as both parameters, because
-     * there is no need to add casts between the same types.</b>
-     *
-     * @param fromType  Source data type.
-     * @param toType  Target custom data type.
-     */
-    public boolean needToCast(RelDataType fromType, IgniteCustomType toType) {
-        // The implementation of this method must always use 
::canCastFrom(typeName),
-        // because canCastFrom is can be used to generate rules for runtime 
execution.
-        var rules = canCastFrom(toType.getCustomTypeName());
-
-        return rules.contains(fromType.getSqlTypeName());
-    }
-
-    /** Returns a set of built-in SQL types the given custom type can be 
converted from. **/
-    public Set<SqlTypeName> canCastFrom(String typeName) {
-        return canCastFrom.getOrDefault(typeName, Collections.emptySet());
-    }
-
-    /** Creates a builder to define a table of type coercion rules. **/
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * A builder for {@link IgniteCustomTypeCoercionRules}.
-     */
-    public static class Builder {
-
-        private final Map<String, Set<SqlTypeName>> canCastFrom = new 
HashMap<>();
-
-        Builder() {
-
-        }
-
-        /**
-         * Adds a rule that allows cast from the given custom type to the 
specified built-in SQL type.
-         */
-        public Builder addRule(String typeName, SqlTypeName to) {
-            var rules = canCastFrom.computeIfAbsent(typeName, (k) -> 
EnumSet.noneOf(SqlTypeName.class));
-            rules.add(to);
-            return this;
-        }
-
-        /**
-         * Adds rules that allow casts from the given custom type to the 
specified built-in SQL types.
-         */
-        public Builder addRules(String typeName, Collection<SqlTypeName> 
typeNames) {
-            var rules = canCastFrom.computeIfAbsent(typeName, (k) -> 
EnumSet.noneOf(SqlTypeName.class));
-            rules.addAll(typeNames);
-            return this;
-        }
-
-        /**
-         * Builds a table of type coercion rules for the given custom data 
types.
-         *
-         * @param typeSpecs A map of custom type specs.
-         * @return  A table of type coercion rules.
-         *
-         * @throws IllegalArgumentException if a this builder contains rules 
for custom types not present in {@code typeSpecs}.
-         */
-        public IgniteCustomTypeCoercionRules build(Map<String, 
IgniteCustomTypeSpec> typeSpecs) {
-            return new IgniteCustomTypeCoercionRules(typeSpecs, canCastFrom);
-        }
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeSpec.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeSpec.java
deleted file mode 100644
index 3641c8af36e..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteCustomTypeSpec.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.sql.engine.type;
-
-import java.lang.reflect.Method;
-import java.util.Objects;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.ignite.internal.sql.engine.exec.ExecutionServiceImpl;
-import org.apache.ignite.internal.sql.engine.exec.exp.ExpressionFactoryImpl;
-import org.apache.ignite.internal.tostring.S;
-import org.apache.ignite.internal.type.NativeType;
-import org.apache.ignite.sql.ColumnMetadata;
-import org.apache.ignite.sql.ColumnType;
-
-/**
- * Specification that defines properties of a {@link IgniteCustomType custom 
data type} that are shared by all instances of that type.
- *
- * @see IgniteCustomType custom data type.
- */
-public final class IgniteCustomTypeSpec {
-
-    private final String typeName;
-
-    private final NativeType nativeType;
-
-    private final ColumnType columnType;
-
-    private final Class<?> storageType;
-
-    private final Method castFunction;
-
-    /**
-     * Creates a specification for a type that with the specified {@code 
storage type}.
-     *
-     * @param typeName Type name.
-     * @param nativeType Native type.
-     * @param columnType Column type.
-     * @param storageType Storage type.
-     * @param castFunction Cast function.
-     */
-    public IgniteCustomTypeSpec(String typeName, NativeType nativeType, 
ColumnType columnType,
-            Class<? extends Comparable<?>> storageType, Method castFunction) {
-
-        this.typeName = typeName;
-        this.nativeType = nativeType;
-        this.columnType = columnType;
-        this.storageType = storageType;
-        this.castFunction = castFunction;
-    }
-
-    /** Returns the name of the type. */
-    public String typeName() {
-        return typeName;
-    }
-
-    /**
-     * Returns the {@link NativeType} for this custom data type.
-     *
-     * <p>At the moment it serves the following purpose:
-     * <ul>
-     *     <li>
-     *         Used by {@link 
IgniteTypeFactory#relDataTypeToNative(RelDataType)} to retrieve underlying
-     *        {@link NativeType} for DDL queries.
-     *     </li>
-     *     <li>
-     *         To retrieve a java type to perform type conversions by
-     *         {@link ExecutionServiceImpl}.
-     *     </li>
-     * </ul>
-     */
-    public NativeType nativeType() {
-        return nativeType;
-    }
-
-    /**
-     * Returns the {@link ColumnType} of this data type. Provides type 
information for {@link ColumnMetadata}.
-     */
-    public ColumnType columnType() {
-        return columnType;
-    }
-
-    /**
-     * Returns the storage type of this data type.
-     *
-     * <p>This method is called by {@link 
IgniteTypeFactory#getJavaClass(RelDataType)} to provide types for a expression 
interpreter.
-     *
-     * @see ExpressionFactoryImpl
-     */
-    public Class<?> storageType() {
-        return storageType;
-    }
-
-    /** Implementation of a cast function for this type. */
-    public Method castFunction() {
-        return castFunction;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        IgniteCustomTypeSpec that = (IgniteCustomTypeSpec) o;
-        return typeName.equals(that.typeName) && 
nativeType.equals(that.nativeType) && storageType.equals(that.storageType)
-                && columnType == that.columnType;
-    }
-
-    /**
-     * Returns a method that implements a cast function for a custom data type.
-     *
-     * <p>Requirements:
-     * <ul>
-     *     <li>It must be a {@code public static} method.</li>
-     *     <li>It must have the following signature: {@code Object -> 
typeSpec::nativeType.javaClass}.</li>
-     *     <li>It must implement conversion from the type itself.</li>
-     *     <li>It must implement conversion from String to {@code 
typeSpec::nativeType.javaClass}.</li>
-     * </ul>
-     *
-     * @param clazz A class that defines a cast function.
-     * @param method A name of a method.
-     * @return A method that implements a cast function.
-     */
-    public static Method getCastFunction(Class<?> clazz, String method) {
-        try {
-            return clazz.getMethod(method, Object.class);
-        } catch (NoSuchMethodException e) {
-            throw new IllegalArgumentException("Incorrect cast function 
method: " + method, e);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return Objects.hash(typeName, nativeType, storageType, columnType);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return S.toString(IgniteCustomTypeSpec.class, this);
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
index a784a2cad48..570fc8e947b 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeFactory.java
@@ -33,17 +33,12 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Period;
-import java.util.Collection;
-import java.util.EnumSet;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Objects;
-import java.util.Set;
 import java.util.UUID;
 import java.util.function.Supplier;
-import java.util.stream.Collectors;
 import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.avatica.util.TimeUnit;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
@@ -82,9 +77,6 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
     /** Default charset. */
     private final Charset charset;
 
-    /** A registry that contains custom data types. **/
-    private final CustomDataTypes customDataTypes;
-
     {
         implementedJavaTypes.put(LocalDate.class, () ->
                 createTypeWithNullability(createSqlType(SqlTypeName.DATE), 
true));
@@ -115,8 +107,6 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
             // If JVM default charset is not supported by Calcite - use UTF-8.
             charset = StandardCharsets.UTF_8;
         }
-
-        customDataTypes = new CustomDataTypes(Set.of());
     }
 
     /** {@inheritDoc} */
@@ -173,7 +163,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
     public Type getJavaClass(RelDataType type) {
         if (type instanceof JavaType) {
             return ((JavaType) type).getJavaClass();
-        } else if (type instanceof BasicSqlType || type instanceof 
IntervalSqlType || type instanceof IgniteCustomType) {
+        } else if (type instanceof BasicSqlType || type instanceof 
IntervalSqlType) {
             switch (type.getSqlTypeName()) {
                 case VARCHAR:
                 case CHAR:
@@ -221,11 +211,6 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
                 case SYMBOL:
                     return Enum.class;
                 case ANY:
-                    if (type instanceof IgniteCustomType) {
-                        var customType = (IgniteCustomType) type;
-                        return customType.spec().storageType();
-                    }
-                    // fallthrough
                 case OTHER:
                     return Object.class;
                 case NULL:
@@ -257,8 +242,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
      */
     public static NativeType relDataTypeToNative(RelDataType relType) {
         assert relType instanceof BasicSqlType
-                || relType instanceof IntervalSqlType
-                || relType instanceof IgniteCustomType : "Not supported:" + 
relType;
+                || relType instanceof IntervalSqlType : "Not supported:" + 
relType;
 
         switch (relType.getSqlTypeName()) {
             case BOOLEAN:
@@ -319,11 +303,6 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
             case UUID:
                 return NativeTypes.UUID;
             case ANY:
-                if (relType instanceof IgniteCustomType) {
-                    var customType = (IgniteCustomType) relType;
-                    return customType.spec().nativeType();
-                }
-                // fallthrough
             default:
                 throw new IllegalArgumentException("Type is not supported: " + 
relType);
         }
@@ -346,7 +325,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
     public Type getResultClass(RelDataType type) {
         if (type instanceof JavaType) {
             return ((JavaType) type).getJavaClass();
-        } else if (type instanceof BasicSqlType || type instanceof 
IntervalSqlType || type instanceof IgniteCustomType) {
+        } else if (type instanceof BasicSqlType || type instanceof 
IntervalSqlType) {
             switch (type.getSqlTypeName()) {
                 case VARCHAR:
                 case CHAR:
@@ -400,12 +379,6 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
                 case SYMBOL:
                     return Enum.class;
                 case ANY:
-                    if (type instanceof IgniteCustomType) {
-                        var customType = (IgniteCustomType) type;
-                        var nativeType = customType.spec().nativeType();
-                        return nativeType.spec().javaClass();
-                    }
-                    // fallthrough
                 case OTHER:
                     return Object.class;
                 case NULL:
@@ -445,13 +418,10 @@ public class IgniteTypeFactory extends 
JavaTypeFactoryImpl {
             return first(types);
         }
 
-        IgniteCustomType firstCustomType = null;
         boolean hasAnyType = false;
         boolean hasNullOrNullable = false;
         boolean hasUuidType = false;
         boolean hasBuiltInType = false;
-        boolean hasNullable = false;
-        IgniteCustomType firstNullable = null;
 
         for (var type : types) {
             SqlTypeName sqlTypeName = type.getSqlTypeName();
@@ -465,23 +435,7 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
                 hasNullOrNullable = true;
             }
 
-            if (type instanceof IgniteCustomType) {
-                if (firstCustomType == null) {
-                    firstCustomType = (IgniteCustomType) type;
-                } else {
-                    IgniteCustomType customType = (IgniteCustomType) type;
-                    if (!Objects.equals(firstCustomType.getCustomTypeName(), 
customType.getCustomTypeName())) {
-                        // IgniteCustomType: Conversion between custom data 
types is not supported.
-                        return null;
-                    }
-                }
-
-                if (type.isNullable() && firstNullable == null) {
-                    hasNullable = type.isNullable();
-                    firstNullable = (IgniteCustomType) type;
-                }
-
-            } else if (sqlTypeName == SqlTypeName.ANY) {
+            if (sqlTypeName == SqlTypeName.ANY) {
                 hasAnyType = true;
             } else {
                 if (sqlTypeName == SqlTypeName.UUID) {
@@ -534,19 +488,10 @@ public class IgniteTypeFactory extends 
JavaTypeFactoryImpl {
         // when at least one of its arguments have sqlTypeName = ANY.
         assert resultType instanceof BasicSqlType : "leastRestrictive is 
expected to return a new instance of a type: " + resultType;
 
-        if (hasAnyType && hasBuiltInType && firstCustomType != null) {
-            // There is no least restrictive type between ANY, built-in type, 
and a custom data type.
-            return null;
-        } else if ((hasAnyType && hasBuiltInType) || (hasAnyType && 
firstCustomType != null)) {
+        if (hasAnyType && hasBuiltInType) {
             // When at least one of arguments have sqlTypeName = ANY,
             // return it in order to be consistent with default implementation.
             return resultType;
-        } else if (firstCustomType != null && !hasBuiltInType) {
-            // When there is only one custom data type and no other built-in 
types,
-            // return the custom data type.
-            // We must return a nullable type, when there are nullable and 
not-nullable types,
-            // because nullable type is less restrictive than not-nullable.
-            return hasNullable ? firstNullable : firstCustomType;
         } else {
             return null;
         }
@@ -647,76 +592,12 @@ public class IgniteTypeFactory extends 
JavaTypeFactoryImpl {
         //noinspection SuspiciousMethodCalls
         if (implementedJavaTypes.containsKey(type)) {
             return createJavaType((Class<?>) type);
-        } else if (customDataTypes.javaTypes.contains(type)) {
-            throw new IllegalArgumentException("Custom data type should not be 
created via createType call: " + type);
         } else {
             return super.createType(type);
         }
     }
 
-    /** {@inheritDoc} **/
-    @Override
-    public RelDataType createTypeWithNullability(RelDataType type, boolean 
nullable) {
-        if (type instanceof IgniteCustomType) {
-            return canonize(((IgniteCustomType) 
type).createWithNullability(nullable));
-        } else {
-            return super.createTypeWithNullability(type, nullable);
-        }
-    }
-
-    /** {@inheritDoc} **/
-    @Override
-    public RelDataType createJavaType(Class clazz) {
-        if (customDataTypes.javaTypes.contains(clazz)) {
-            throw new IllegalArgumentException("Custom data type should not be 
created via createJavaType call: " + clazz);
-        } else {
-            return super.createJavaType(clazz);
-        }
-    }
-
-    /**
-     * Creates a custom data type with the given {@code typeName} and 
precision.
-     *
-     * @param typeName Type name.
-     * @param precision Precision if supported.
-     * @return A custom data type.
-     */
-    public IgniteCustomType createCustomType(String typeName, int precision) {
-        IgniteCustomTypeFactory customTypeFactory = 
customDataTypes.typeFactories.get(typeName);
-        if (customTypeFactory == null) {
-            throw new IllegalArgumentException("Unexpected custom data type: " 
+ typeName);
-        }
-
-        // By default a type must not be nullable.
-        // See SqlTypeFactory::createSqlType.
-        IgniteCustomType customType = customTypeFactory.newType(false, 
precision);
-        assert !customType.isNullable() : "makeCustomType must not return a 
nullable type: " + typeName + " " + customType;
-        return (IgniteCustomType) canonize(customType);
-    }
-
-    /**
-     * Creates a custom data type with the given {@code typeName} and without 
precision.
-     *
-     * <p>A shorthand for {@code createCustomType(typeName, -1)}.
-     *
-     * @param typeName Type name.
-     * @return A custom data type.
-     */
-    public IgniteCustomType createCustomType(String typeName) {
-        return createCustomType(typeName, PRECISION_NOT_SPECIFIED);
-    }
-
-    /** Returns {@link IgniteCustomTypeSpec type specifications} of registered 
custom data types. */
-    public Map<String, IgniteCustomTypeSpec> getCustomTypeSpecs() {
-        return customDataTypes.typeSpecs;
-    }
-
-    /** Returns type coercion rules to custom data types. */
-    public IgniteCustomTypeCoercionRules getCustomTypeCoercionRules() {
-        return customDataTypes.typeCoercionRules;
-    }
-
-    private boolean allEquals(List<RelDataType> types) {
+    private static boolean allEquals(List<RelDataType> types) {
         assert types.size() > 1;
 
         RelDataType first = first(types);
@@ -728,68 +609,4 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
 
         return true;
     }
-
-    private static final class CustomDataTypes {
-
-        /**
-         * Contains java types used by registered custom data types.
-         *
-         * <p>We need those to reject attempts to create custom data types via
-         * {@link IgniteTypeFactory#createType(Type)}/{@link 
IgniteTypeFactory#createJavaType(Class)}
-         * methods of {@link IgniteTypeFactory}.
-         */
-        private final Set<Type> javaTypes;
-
-        /**
-         * Stores functions that are being used by {@link 
#createCustomType(String, int)} to create type instances.
-         */
-        private final Map<String, IgniteCustomTypeFactory> typeFactories;
-
-        private final Map<String, IgniteCustomTypeSpec> typeSpecs;
-
-        private final IgniteCustomTypeCoercionRules typeCoercionRules;
-
-        CustomDataTypes(Set<NewCustomType> customDataTypes) {
-            this.javaTypes = customDataTypes.stream()
-                    .map(t -> t.spec.storageType())
-                    .collect(Collectors.toSet());
-
-            this.typeSpecs = customDataTypes.stream()
-                    .map(t -> Map.entry(t.spec.typeName(), t.spec))
-                    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
-
-            this.typeFactories = 
customDataTypes.stream().collect(Collectors.toMap((v) -> v.spec.typeName(), (v) 
-> v.typeFactory));
-
-            var builder = IgniteCustomTypeCoercionRules.builder();
-            for (var newType : customDataTypes) {
-                builder.addRules(newType.spec.typeName(), 
newType.canBeCoercedTo);
-            }
-            this.typeCoercionRules = builder.build(typeSpecs);
-        }
-    }
-
-    private static final class NewCustomType {
-        final IgniteCustomTypeSpec spec;
-
-        final IgniteCustomTypeFactory typeFactory;
-
-        final Set<SqlTypeName> canBeCoercedTo = 
EnumSet.noneOf(SqlTypeName.class);
-
-        NewCustomType(IgniteCustomTypeSpec spec, IgniteCustomTypeFactory 
typeFactory) {
-            this.spec = spec;
-            this.typeFactory = typeFactory;
-        }
-
-        /**
-         * Adds a type coercion rule to from the given built-in SQL types to 
this custom data type.
-         */
-        void addCoercionRules(Collection<SqlTypeName> types) {
-            canBeCoercedTo.addAll(types);
-        }
-    }
-
-    @FunctionalInterface
-    interface IgniteCustomTypeFactory {
-        IgniteCustomType newType(boolean nullable, int precision);
-    }
 }
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/SafeCustomTypeInternalConversion.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/SafeCustomTypeInternalConversion.java
deleted file mode 100644
index ca278219033..00000000000
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/SafeCustomTypeInternalConversion.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.sql.engine.util;
-
-import java.util.EnumMap;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeSpec;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.apache.ignite.sql.ColumnType;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * The sole purpose of this class is to provide safe-conversion to and from 
internal types,
- * preventing class cast exceptions inside when using {@link TypeUtils} 
methods for to/from type conversion.
- */
-final class SafeCustomTypeInternalConversion {
-
-    static final SafeCustomTypeInternalConversion INSTANCE = new 
SafeCustomTypeInternalConversion(Commons.typeFactory());
-
-    private final EnumMap<ColumnType, Class<?>> internalTypes = new 
EnumMap<>(ColumnType.class);
-
-    private SafeCustomTypeInternalConversion(IgniteTypeFactory typeFactory) {
-        // IgniteCustomType: We can automatically compute val -> internal type 
mapping
-        // by using type specs from the type factory.
-        var customTypes = typeFactory.getCustomTypeSpecs();
-
-        for (IgniteCustomTypeSpec t : customTypes.values()) {
-            internalTypes.put(t.nativeType().spec(), t.storageType());
-        }
-    }
-
-    @Nullable
-    Object tryConvertToInternal(Object val, ColumnType storageType) {
-        Class<?> internalType = internalTypes.get(storageType);
-
-        assert internalType == null || internalType.isInstance(val) : 
storageTypeMismatch(val, internalType);
-
-        return val;
-    }
-
-    Object tryConvertFromInternal(Object val, ColumnType storageType) {
-        Class<?> internalType = internalTypes.get(storageType);
-
-        assert internalType == null || internalType.isInstance(val) : 
storageTypeMismatch(val, internalType);
-
-        return val;
-    }
-
-    private static String storageTypeMismatch(Object value, Class<?> type) {
-        return String.format("storageType is %s value must also be %s but it 
was: %s", type, type, value);
-    }
-}
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
index 368ef3d4033..e3c7c85d806 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/TypeUtils.java
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.sql.engine.util;
 import static org.apache.calcite.sql.type.SqlTypeName.BINARY_TYPES;
 import static org.apache.calcite.sql.type.SqlTypeName.CHAR_TYPES;
 import static org.apache.calcite.sql.type.SqlTypeName.STRING_TYPES;
-import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+import static 
org.apache.ignite.internal.sql.engine.util.IgniteMath.convertToIntExact;
 import static org.apache.ignite.lang.ErrorGroups.Sql.STMT_VALIDATION_ERR;
 
 import java.lang.reflect.Type;
@@ -38,7 +38,6 @@ import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -67,8 +66,6 @@ import 
org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
 import org.apache.ignite.internal.sql.engine.exec.row.RowType;
 import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
 import org.apache.ignite.internal.sql.engine.prepare.ParameterType;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import 
org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeCoercionRules;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.type.DecimalNativeType;
 import org.apache.ignite.internal.type.NativeType;
@@ -353,16 +350,13 @@ public class TypeUtils {
             case BOOLEAN:
                 assert val instanceof Boolean : val.getClass();
                 return val;
-            // TODO https://issues.apache.org/jira/browse/IGNITE-23295 Support 
native types for DURATION and PERIOD
-            // case DURATION:
-            //     return TimeUnit.SECONDS.toMillis(((Duration) 
val).getSeconds())
-            //             + TimeUnit.NANOSECONDS.toMillis(((Duration) 
val).getNano());
-            // case PREIOD:
-            //     return (int) ((Period) val).toTotalMonths();
+            case DURATION:
+                return ((Duration) val).toMillis();
+            case PERIOD:
+                return convertToIntExact(((Period) val).toTotalMonths());
 
             default: {
-                var customType = 
SafeCustomTypeInternalConversion.INSTANCE.tryConvertToInternal(val, spec);
-                return customType != null ? customType : val;
+                throw new AssertionError("Type is not supported: " + spec);
             }
         }
     }
@@ -408,6 +402,7 @@ public class TypeUtils {
             case DECIMAL:
             case UUID:
             case STRING:
+            case BOOLEAN:
                 return val;
             case BYTE_ARRAY:
                 return ((ByteString) val).getBytes();
@@ -419,8 +414,6 @@ public class TypeUtils {
                 return LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) 
val), ZoneOffset.UTC);
             case TIMESTAMP:
                 return Instant.ofEpochMilli((Long) val);
-            case BOOLEAN:
-                return val;
             case DURATION: {
                 assert val instanceof Long;
                 return Duration.ofMillis((Long) val);
@@ -430,7 +423,7 @@ public class TypeUtils {
                 return Period.of((Integer) val / 12, (Integer) val % 12, 0);
             }
             default: {
-                return 
SafeCustomTypeInternalConversion.INSTANCE.tryConvertFromInternal(val, spec);
+                throw new AssertionError("Type is not supported: " + spec);
             }
         }
     }
@@ -472,11 +465,6 @@ public class TypeUtils {
             case BINARY:
             case VARBINARY:
             case ANY:
-                if (type instanceof IgniteCustomType) {
-                    IgniteCustomType customType = (IgniteCustomType) type;
-                    return customType.spec().columnType();
-                }
-                // fallthrough
             case OTHER:
                 return ColumnType.BYTE_ARRAY;
             case INTERVAL_YEAR:
@@ -673,25 +661,6 @@ public class TypeUtils {
         return true;
     }
 
-    /**
-     * Checks whether one type can be casted to another if one of type is a 
custom data type.
-     *
-     * <p>This method expects at least one of its arguments to be a custom 
data type.
-     */
-    public static boolean customDataTypeNeedCast(IgniteTypeFactory factory, 
RelDataType fromType, RelDataType toType) {
-        IgniteCustomTypeCoercionRules typeCoercionRules = 
factory.getCustomTypeCoercionRules();
-        if (toType instanceof IgniteCustomType) {
-            IgniteCustomType to = (IgniteCustomType) toType;
-            return typeCoercionRules.needToCast(fromType, to);
-        } else if (fromType instanceof IgniteCustomType) {
-            boolean sameType = SqlTypeUtil.equalSansNullability(fromType, 
toType);
-            return !sameType;
-        } else {
-            String message = format("Invalid arguments. Expected at least one 
custom data type but got {} and {}", fromType, toType);
-            throw new AssertionError(message);
-        }
-    }
-
     /**
      * Checks that {@code toType} and {@code fromType} have compatible type 
families taking into account custom data types. Types {@code T1}
      * and {@code T2} have compatible type families if {@code T1} can be 
assigned to {@code T2} and vice-versa.
@@ -726,20 +695,8 @@ public class TypeUtils {
             return true;
         }
 
-        if (fromType instanceof IgniteCustomType && toType instanceof 
IgniteCustomType) {
-            IgniteCustomType fromCustom = (IgniteCustomType) fromType;
-            IgniteCustomType toCustom = (IgniteCustomType) toType;
-
-            // IgniteCustomType: different custom data types are not 
compatible.
-            return Objects.equals(fromCustom.getCustomTypeName(), 
toCustom.getCustomTypeName());
-        } else if (fromType instanceof IgniteCustomType || toType instanceof 
IgniteCustomType) {
-            // IgniteCustomType: custom data types are not compatible with 
other types.
-            return false;
-        } else if (SqlTypeUtil.canAssignFrom(toType, fromType)) {
-            return SqlTypeUtil.canAssignFrom(fromType, toType);
-        } else {
-            return false;
-        }
+        return SqlTypeUtil.canAssignFrom(toType, fromType)
+                && SqlTypeUtil.canAssignFrom(fromType, toType);
     }
 
     /**
@@ -799,10 +756,7 @@ public class TypeUtils {
         boolean simpleType = type instanceof BasicSqlType;
         boolean nullable = type.isNullable();
 
-        if (type instanceof IgniteCustomType) {
-            NativeType nativeType = 
IgniteTypeFactory.relDataTypeToNative(type);
-            return RowSchemaTypes.nativeTypeWithNullability(nativeType, 
nullable);
-        } else if (SqlTypeName.ANY == type.getSqlTypeName()) {
+        if (SqlTypeName.ANY == type.getSqlTypeName()) {
             // TODO Some JSON functions that return ANY as well : 
https://issues.apache.org/jira/browse/IGNITE-20163
             return new BaseTypeSpec(null, nullable);
         } else if (SqlTypeUtil.isNull(type)) {
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/LeastRestrictiveTypesTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/LeastRestrictiveTypesTest.java
index 55454714d24..7ae53bde1ef 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/LeastRestrictiveTypesTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/prepare/LeastRestrictiveTypesTest.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.sql.engine.prepare;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -26,14 +25,9 @@ import java.util.List;
 import java.util.stream.Stream;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeSpec;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.util.Commons;
-import org.apache.ignite.internal.type.NativeTypes;
-import org.apache.ignite.sql.ColumnType;
 import org.jetbrains.annotations.Nullable;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
@@ -63,15 +57,9 @@ public class LeastRestrictiveTypesTest {
 
     private static final RelDataType VARCHAR = 
TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR, 36);
 
-    private static final TestCustomType CUSTOM_TYPE = new 
TestCustomType(false);
-
-    private static final RelDataType NULLABLE_CUSTOM_TYPE = 
CUSTOM_TYPE.createWithNullability(true);
-
     // ANY produced by the default implementation of leastRestrictiveType has 
nullability = true
     private static final RelDataType ANY = 
TYPE_FACTORY.createTypeWithNullability(TYPE_FACTORY.createSqlType(SqlTypeName.ANY),
 true);
 
-    private static final RelDataType NULL = 
TYPE_FACTORY.createTypeWithNullability(TYPE_FACTORY.createSqlType(SqlTypeName.NULL),
 true);
-
     @ParameterizedTest
     @MethodSource("tinyIntTests")
     public void testTinyInt(RelDataType t1, RelDataType t2, 
LeastRestrictiveType leastRestrictiveType) {
@@ -226,32 +214,6 @@ public class LeastRestrictiveTypesTest {
         return tests.stream();
     }
 
-    @ParameterizedTest
-    @MethodSource("customTypeTests")
-    public void testUuid(RelDataType t1, RelDataType t2, LeastRestrictiveType 
leastRestrictiveType) {
-        expectLeastRestrictiveType(t1, t2, leastRestrictiveType);
-        expectLeastRestrictiveType(t2, t1, leastRestrictiveType);
-    }
-
-    private static Stream<Arguments> customTypeTests() {
-        List<Arguments> tests = new ArrayList<>();
-
-        tests.add(Arguments.arguments(CUSTOM_TYPE, TINYINT, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, SMALLINT, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, INTEGER, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, FLOAT, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, REAL, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, DOUBLE, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, DECIMAL, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, BIGINT, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, VARCHAR, 
LeastRestrictiveType.none()));
-        tests.add(Arguments.arguments(CUSTOM_TYPE, CUSTOM_TYPE, new 
LeastRestrictiveType(CUSTOM_TYPE)));
-        tests.add(Arguments.arguments(NULLABLE_CUSTOM_TYPE, CUSTOM_TYPE, new 
LeastRestrictiveType(NULLABLE_CUSTOM_TYPE)));
-        tests.add(Arguments.arguments(NULL, CUSTOM_TYPE, new 
LeastRestrictiveType(CUSTOM_TYPE)));
-
-        return tests.stream();
-    }
-
     @ParameterizedTest
     @MethodSource("anyTests")
     public void testAny(RelDataType t1, RelDataType t2, LeastRestrictiveType 
leastRestrictiveType) {
@@ -272,35 +234,10 @@ public class LeastRestrictiveTypesTest {
         tests.add(Arguments.arguments(ANY, DECIMAL, anyType));
         tests.add(Arguments.arguments(ANY, BIGINT, anyType));
         tests.add(Arguments.arguments(ANY, VARCHAR, anyType));
-        tests.add(Arguments.arguments(ANY, CUSTOM_TYPE, anyType));
 
         return tests.stream();
     }
 
-    @Test
-    public void testCustomDataTypeLeastRestrictiveTypeForMoreThanTwoTypes() {
-        // no least restrictive type between ANY, a built-in type and a custom 
data type.
-        assertNull(TYPE_FACTORY.leastRestrictive(List.of(CUSTOM_TYPE, INTEGER, 
ANY)));
-        assertNull(TYPE_FACTORY.leastRestrictive(List.of(INTEGER, ANY, 
CUSTOM_TYPE)));
-        assertNull(TYPE_FACTORY.leastRestrictive(List.of(ANY, CUSTOM_TYPE, 
INTEGER)));
-        assertNull(TYPE_FACTORY.leastRestrictive(List.of(ANY, CUSTOM_TYPE, 
NULLABLE_CUSTOM_TYPE, INTEGER)));
-        assertNull(TYPE_FACTORY.leastRestrictive(List.of(ANY, NULL, 
CUSTOM_TYPE, NULLABLE_CUSTOM_TYPE, INTEGER)));
-    }
-
-    @Test
-    public void testCustomDataTypeNullableTypesAreLessRestrictive() {
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(NULLABLE_CUSTOM_TYPE, CUSTOM_TYPE, 
CUSTOM_TYPE)));
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(CUSTOM_TYPE, NULLABLE_CUSTOM_TYPE, 
CUSTOM_TYPE)));
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(CUSTOM_TYPE, CUSTOM_TYPE, 
NULLABLE_CUSTOM_TYPE)));
-    }
-
-    @Test
-    public void testCustomDataTypeIgnoreNulls() {
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(NULLABLE_CUSTOM_TYPE, CUSTOM_TYPE, 
NULL)));
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(NULL, NULLABLE_CUSTOM_TYPE, 
CUSTOM_TYPE)));
-        assertEquals(NULLABLE_CUSTOM_TYPE, 
TYPE_FACTORY.leastRestrictive(List.of(CUSTOM_TYPE, NULL, 
NULLABLE_CUSTOM_TYPE)));
-    }
-
     @ParameterizedTest
     @MethodSource("types")
     public void testLeastRestrictiveTypeForAnyAndMoreThanTwoTypes(RelDataType 
type) {
@@ -323,7 +260,6 @@ public class LeastRestrictiveTypesTest {
         tests.add(Arguments.arguments(DECIMAL));
         tests.add(Arguments.arguments(BIGINT));
         tests.add(Arguments.arguments(VARCHAR));
-        tests.add(Arguments.arguments(CUSTOM_TYPE));
 
         return tests.stream();
     }
@@ -349,29 +285,4 @@ public class LeastRestrictiveTypesTest {
         RelDataType actualType = 
TYPE_FACTORY.leastRestrictive(Arrays.asList(type1, type2));
         assertEquals(expectedType.relDataType, actualType, "leastRestrictive(" 
+ type1 + "," + type2 + ")");
     }
-
-    private static final class TestCustomType extends IgniteCustomType {
-
-        private static final IgniteCustomTypeSpec SPEC = new 
IgniteCustomTypeSpec("TestType",
-                NativeTypes.INT8, ColumnType.INT8, Byte.class,
-                IgniteCustomTypeSpec.getCastFunction(TestCustomType.class, 
"cast"));
-
-        @Override
-        public IgniteCustomType createWithNullability(boolean nullable) {
-            return new TestCustomType(nullable);
-        }
-
-        private TestCustomType(boolean nullable) {
-            super(SPEC, nullable, -1);
-        }
-
-        @Override
-        protected void generateTypeString(StringBuilder sb, boolean 
withDetail) {
-            sb.append("TestType");
-        }
-
-        public static byte cast(Object ignore) {
-            throw new AssertionError();
-        }
-    }
 }
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
index 9c066eebfdf..6cead4f4e85 100644
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
+++ 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/TypeUtilsTest.java
@@ -56,8 +56,6 @@ import 
org.apache.ignite.internal.sql.engine.exec.row.RowSchemaTypes;
 import org.apache.ignite.internal.sql.engine.exec.row.RowType;
 import org.apache.ignite.internal.sql.engine.exec.row.TypeSpec;
 import org.apache.ignite.internal.sql.engine.framework.ArrayRowHandler;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
-import org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeSpec;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
 import org.apache.ignite.internal.type.NativeTypes;
@@ -329,27 +327,6 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
         return supportedTypes().map(t -> expectCompatible(t, nullType));
     }
 
-    /** Type compatibility rules for custom data types. */
-    @TestFactory
-    public Stream<DynamicTest> testCustomDataTypeCompatibility() {
-        IgniteCustomType type1 = new TestCustomType("type1");
-        IgniteCustomType type2 = new TestCustomType("type2");
-        RelDataType someType = TYPE_FACTORY.createSqlType(SqlTypeName.ANY);
-
-        return Stream.of(
-                // types with same custom type name are compatible.
-                expectCompatible(type1, new 
TestCustomType(type1.getCustomTypeName())),
-
-                // different custom types are never compatible.
-                expectIncompatible(type1, type2),
-                expectIncompatible(type2, type1),
-
-                // custom types are not compatible with other data types.
-                expectIncompatible(someType, type1),
-                expectIncompatible(type1, someType)
-        );
-    }
-
     private static Stream<RelDataType> supportedTypes() {
         List<SqlTypeName> types = new ArrayList<>();
 
@@ -366,10 +343,6 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
             relDataTypes.add(TYPE_FACTORY.createSqlType(typeName));
         });
 
-        for (String typeName : TYPE_FACTORY.getCustomTypeSpecs().keySet()) {
-            relDataTypes.add(TYPE_FACTORY.createCustomType(typeName));
-        }
-
         return relDataTypes.stream();
     }
 
@@ -604,30 +577,6 @@ public class TypeUtilsTest extends BaseIgniteAbstractTest {
         );
     }
 
-    private static final class TestCustomType extends IgniteCustomType {
-
-        private TestCustomType(String typeName) {
-            super(new IgniteCustomTypeSpec(typeName,
-                    NativeTypes.INT8, ColumnType.INT8, Byte.class,
-                    IgniteCustomTypeSpec.getCastFunction(TestCustomType.class, 
"cast")), false, -1);
-        }
-
-        @Override
-        protected void generateTypeString(StringBuilder sb, boolean 
withDetail) {
-            sb.append(getCustomTypeName());
-        }
-
-        @Override
-        public IgniteCustomType createWithNullability(boolean nullable) {
-            throw new AssertionError();
-        }
-
-        @SuppressWarnings("unused")
-        public static byte cast(Object ignore) {
-            throw new AssertionError();
-        }
-    }
-
     static class RelToExecTestCase {
 
         final RelDataType input;


Reply via email to