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

ivandasch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new b7b53690410 IGNITE-17599 SQL Calcite: Support insertion of 
LocalDateTime, LocalDate and LocalTime (#10399)
b7b53690410 is described below

commit b7b53690410ec72a23fbc28a31e08fd21f881e80
Author: Ivan Daschinskiy <[email protected]>
AuthorDate: Tue Nov 29 21:11:32 2022 +0300

    IGNITE-17599 SQL Calcite: Support insertion of LocalDateTime, LocalDate and 
LocalTime (#10399)
    
    * IGNITE-17599 SQL Calcite: Support insertion of LocalDateTime, LocalDate 
and LocalTime
    
    * Review fixes
    
    * Add additional tests.
---
 .../query/calcite/externalize/RelJsonReader.java   |   3 +
 .../query/calcite/type/IgniteTypeFactory.java      |  11 +-
 .../processors/query/calcite/util/TypeUtils.java   |  50 +++-
 .../integration/LocalDateTimeSupportTest.java      | 288 +++++++++++++++++++++
 .../ignite/testsuites/IntegrationTestSuite.java    |   2 +
 .../processors/query/GridQueryIndexing.java        |  13 -
 .../processors/query/QueryTypeDescriptorImpl.java  |  11 +-
 .../internal/processors/query/QueryUtils.java      |  18 +-
 .../processors/query/DummyQueryIndexing.java       |   5 -
 .../internal/processors/query/h2/H2Utils.java      |  40 ---
 .../processors/query/h2/IgniteH2Indexing.java      |  17 --
 .../h2/H2ColumnTypeConversionCheckSelfTest.java    |  57 ----
 .../IgniteBinaryCacheQueryTestSuite3.java          |   2 -
 13 files changed, 369 insertions(+), 148 deletions(-)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJsonReader.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJsonReader.java
index 522ec373125..d740af19174 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJsonReader.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJsonReader.java
@@ -243,6 +243,9 @@ public class RelJsonReader {
         /** {@inheritDoc} */
         @Override public List<RexNode> getExpressionList(String tag) {
             List<Object> jsonNodes = (List)jsonRel.get(tag);
+            if (jsonNodes == null)
+                return null;
+
             List<RexNode> nodes = new ArrayList<>();
             for (Object jsonNode : jsonNodes)
                 nodes.add(relJson.toRex(this, jsonNode));
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/type/IgniteTypeFactory.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/type/IgniteTypeFactory.java
index 94c9cd6f96a..d2ca9a6b3ca 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/type/IgniteTypeFactory.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/type/IgniteTypeFactory.java
@@ -23,6 +23,7 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.sql.Timestamp;
 import java.time.Duration;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Period;
@@ -40,6 +41,7 @@ import org.apache.calcite.sql.SqlUtil;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.BasicSqlType;
 import org.apache.calcite.sql.type.IntervalSqlType;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.ignite.internal.util.typedef.F;
 
 /**
@@ -265,6 +267,12 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl 
{
                 return 
createTypeWithNullability(createSqlIntervalType(INTERVAL_QUALIFIER_DAY_TIME), 
true);
             else if (clazz == Period.class)
                 return 
createTypeWithNullability(createSqlIntervalType(INTERVAL_QUALIFIER_YEAR_MONTH), 
true);
+            else if (clazz == LocalDateTime.class)
+                return 
createTypeWithNullability(createSqlType(SqlTypeName.TIMESTAMP), true);
+            else if (clazz == LocalDate.class)
+                return 
createTypeWithNullability(createSqlType(SqlTypeName.DATE), true);
+            else if (clazz == LocalTime.class)
+                return 
createTypeWithNullability(createSqlType(SqlTypeName.TIME), true);
             else {
                 RelDataType relType = createCustomType(clazz);
 
@@ -301,7 +309,8 @@ public class IgniteTypeFactory extends JavaTypeFactoryImpl {
 
     /** {@inheritDoc} */
     @Override public RelDataType createType(Type type) {
-        if (type == Duration.class || type == Period.class)
+        if (type == Duration.class || type == Period.class || type == 
LocalDateTime.class || type == LocalTime.class
+            || type == LocalDate.class)
             return createJavaType((Class<?>)type);
 
         RelDataType customType = createCustomType(type, false);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
index a01b6d90d2f..4455f4a387f 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
@@ -23,7 +23,12 @@ import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.Period;
+import java.time.ZoneOffset;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -59,6 +64,7 @@ import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.TimeString;
 import org.apache.calcite.util.TimestampString;
 import org.apache.ignite.IgniteException;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DateValueUtils;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
 import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler;
@@ -81,6 +87,9 @@ public class TypeUtils {
         java.sql.Date.class,
         java.sql.Time.class,
         java.sql.Timestamp.class,
+        LocalDateTime.class,
+        LocalDate.class,
+        LocalTime.class,
         Duration.class,
         Period.class,
         byte[].class
@@ -316,13 +325,19 @@ public class TypeUtils {
         if (val == null)
             return null;
         else if (storageType == java.sql.Date.class)
-            return (int)(SqlFunctions.toLong((java.util.Date)val, 
DataContext.Variable.TIME_ZONE.get(ctx)) / DateTimeUtils.MILLIS_PER_DAY);
+            return (int)(toLong(ctx, val) / DateTimeUtils.MILLIS_PER_DAY);
+        else if (storageType == LocalDate.class)
+            return (int)(toLong(ctx, val) / DateTimeUtils.MILLIS_PER_DAY);
         else if (storageType == java.sql.Time.class)
-            return (int)(SqlFunctions.toLong((java.util.Date)val, 
DataContext.Variable.TIME_ZONE.get(ctx)) % DateTimeUtils.MILLIS_PER_DAY);
-        else if (storageType == Timestamp.class)
-            return SqlFunctions.toLong((java.util.Date)val, 
DataContext.Variable.TIME_ZONE.get(ctx));
+            return (int)(toLong(ctx, val) % DateTimeUtils.MILLIS_PER_DAY);
+        else if (storageType == LocalTime.class)
+            return (int)(toLong(ctx, val) % DateTimeUtils.MILLIS_PER_DAY);
+        else if (storageType == Timestamp.class || storageType == 
LocalDateTime.class)
+            return toLong(ctx, val);
         else if (storageType == java.util.Date.class)
-            return SqlFunctions.toLong((java.util.Date)val, 
DataContext.Variable.TIME_ZONE.get(ctx));
+            return toLong(ctx, val);
+        else if (storageType == java.util.Date.class)
+            return toLong(ctx, val);
         else if (storageType == Duration.class) {
             return TimeUnit.SECONDS.toMillis(((Duration)val).getSeconds())
                 + TimeUnit.NANOSECONDS.toMillis(((Duration)val).getNano());
@@ -348,16 +363,41 @@ public class TypeUtils {
             return val;
     }
 
+    /** Converts temporal objects to long.
+     *
+     * @param ctx Data context.
+     * @param val Temporal value.
+     * @return Millis value.
+     */
+    private static long toLong(DataContext ctx, Object val) {
+        if (val instanceof LocalDateTime)
+            return 
SqlFunctions.toLong(DateValueUtils.convertToTimestamp((LocalDateTime)val), 
DataContext.Variable.TIME_ZONE.get(ctx));
+
+        if (val instanceof LocalDate)
+            return 
SqlFunctions.toLong(DateValueUtils.convertToSqlDate((LocalDate)val), 
DataContext.Variable.TIME_ZONE.get(ctx));
+
+        if (val instanceof LocalTime)
+            return 
SqlFunctions.toLong(DateValueUtils.convertToSqlTime((LocalTime)val), 
DataContext.Variable.TIME_ZONE.get(ctx));
+
+        return SqlFunctions.toLong((java.util.Date)val, 
DataContext.Variable.TIME_ZONE.get(ctx));
+    }
+
     /** */
     public static Object fromInternal(DataContext ctx, Object val, Type 
storageType) {
         if (val == null)
             return null;
         else if (storageType == java.sql.Date.class && val instanceof Integer)
             return new java.sql.Date(fromLocalTs(ctx, (Integer)val * 
DateTimeUtils.MILLIS_PER_DAY));
+        else if (storageType == LocalDate.class && val instanceof Integer)
+            return new java.sql.Date(fromLocalTs(ctx, (Integer)val * 
DateTimeUtils.MILLIS_PER_DAY)).toLocalDate();
         else if (storageType == java.sql.Time.class && val instanceof Integer)
             return new java.sql.Time(fromLocalTs(ctx, (Integer)val));
+        else if (storageType == LocalTime.class && val instanceof Integer)
+            return 
Instant.ofEpochMilli((Integer)val).atZone(ZoneOffset.UTC).toLocalTime();
         else if (storageType == Timestamp.class && val instanceof Long)
             return new Timestamp(fromLocalTs(ctx, (Long)val));
+        else if (storageType == LocalDateTime.class && val instanceof Long)
+            return new Timestamp(fromLocalTs(ctx, 
(Long)val)).toLocalDateTime();
         else if (storageType == java.util.Date.class && val instanceof Long)
             return new java.util.Date(fromLocalTs(ctx, (Long)val));
         else if (storageType == Duration.class && val instanceof Long)
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/LocalDateTimeSupportTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/LocalDateTimeSupportTest.java
new file mode 100644
index 00000000000..2b10ea90388
--- /dev/null
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/LocalDateTimeSupportTest.java
@@ -0,0 +1,288 @@
+/*
+ * 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.processors.query.calcite.integration;
+
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Function;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.G;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static java.util.Collections.singletonList;
+import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DateValueUtils.convertToSqlDate;
+import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DateValueUtils.convertToSqlTime;
+import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DateValueUtils.convertToTimestamp;
+
+/** */
+@RunWith(Parameterized.class)
+public class LocalDateTimeSupportTest extends AbstractBasicIntegrationTest {
+    /** */
+    @Parameterized.Parameter()
+    public boolean isValidationEnabled;
+
+    /** */
+    @Parameterized.Parameter(1)
+    public String sqlType;
+
+    /** */
+    @Parameterized.Parameter(2)
+    public Class<?> colType;
+
+    /** */
+    @Parameterized.Parameter(3)
+    public Class<?> objType;
+
+    /** */
+    @Parameterized.Parameter(4)
+    public Function<Object, Object> sqlTypeConverter;
+
+    /** */
+    @Parameterized.Parameter(5)
+    public boolean isOldDate;
+
+    /** */
+    @Parameterized.Parameters(name = "isValidationEnabled={0}, sqlType={1}, 
columnCls={2}, testObjCls={3}, beforeGregorian={5}")
+    public static Collection<Object[]> parameters() {
+        Collection<Object[]> params = new ArrayList<>();
+
+        for (boolean isOldDate: Arrays.asList(true, false)) {
+            for (boolean isV : Arrays.asList(true, false)) {
+                params.add(new Object[] {
+                    isV, "TIMESTAMP", null, LocalDateTime.class, f(ts -> 
convertToTimestamp((LocalDateTime)ts)), isOldDate
+                });
+                params.add(new Object[] {
+                    isV, "TIMESTAMP", null, Date.class, f(ts -> new 
Timestamp(((Date)ts).getTime())), isOldDate
+                });
+                params.add(new Object[] {
+                    isV, "TIMESTAMP", null, java.sql.Date.class, f(ts -> new 
Timestamp(((Date)ts).getTime())), isOldDate
+                });
+
+                for (Class<?> testObjCls : Arrays.asList(Timestamp.class, 
LocalDateTime.class, Date.class, java.sql.Date.class)) {
+                    params.add(new Object[] {
+                        isV, null, Timestamp.class, testObjCls, f(ts -> {
+                            if (ts instanceof LocalDateTime)
+                                return convertToTimestamp((LocalDateTime)ts);
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+
+                    params.add(new Object[] {
+                        isV, null, Date.class, testObjCls, f(ts -> {
+                            if (testObjCls == LocalDateTime.class)
+                                return new 
Date(convertToTimestamp((LocalDateTime)ts).getTime());
+                            else if (testObjCls == Timestamp.class)
+                                return new Date(((Timestamp)ts).getTime());
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+
+                    params.add(new Object[] {
+                        isV, null, LocalDateTime.class, testObjCls, f(ts -> {
+                            if (testObjCls == Timestamp.class)
+                                return ((Timestamp)ts).toLocalDateTime();
+                            else if (testObjCls == java.util.Date.class)
+                                return new 
Timestamp(((Date)ts).getTime()).toLocalDateTime();
+                            else if (testObjCls == java.sql.Date.class)
+                                return 
((java.sql.Date)ts).toLocalDate().atStartOfDay();
+                            else
+                                return ts;
+                        }),
+                        isOldDate
+                    });
+                }
+
+                params.add(new Object[] {
+                    isV, "DATE", null, LocalDate.class, f(d -> 
convertToSqlDate((LocalDate)d)), isOldDate
+                });
+
+                for (Class<?> testObjCls : Arrays.asList(LocalDate.class, 
java.sql.Date.class)) {
+                    params.add(new Object[] {
+                        isV, null, java.sql.Date.class, testObjCls, f(ts -> {
+                            if (testObjCls == LocalDate.class)
+                                return convertToSqlDate((LocalDate)ts);
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+
+                    params.add(new Object[] {
+                        isV, null, LocalDate.class, testObjCls, f(ts -> {
+                            if (testObjCls == java.sql.Date.class)
+                                return ((java.sql.Date)ts).toLocalDate();
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+                }
+
+                params.add(new Object[] {
+                    isV, "TIME", null, LocalTime.class, f(t -> 
convertToSqlTime((LocalTime)t)), isOldDate
+                });
+
+                for (Class<?> testObjCls : Arrays.asList(LocalTime.class, 
java.sql.Time.class)) {
+                    params.add(new Object[] {
+                        isV, null, java.sql.Time.class, testObjCls, f(ts -> {
+                            if (testObjCls == LocalTime.class)
+                                return convertToSqlTime((LocalTime)ts);
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+
+                    params.add(new Object[] {
+                        isV, null, LocalTime.class, testObjCls, f(ts -> {
+                            if (testObjCls == java.sql.Time.class)
+                                return ((java.sql.Time)ts).toLocalTime();
+                            return ts;
+                        }),
+                        isOldDate
+                    });
+                }
+            }
+        }
+
+        return params;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.getSqlConfiguration().setValidationEnabled(isValidationEnabled);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void beforeTest() throws Exception {
+        if (!G.allGrids().isEmpty())
+            return;
+
+        startGrids(nodeCount());
+
+        client = startClientGrid("client");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /** */
+    @Test
+    public void testTemporalTypes() {
+        createTable();
+
+        executeSql("CREATE INDEX DATA_IDX ON DATA(data DESC);");
+
+        Object testObj = generateTestObject(objType, isOldDate);
+
+        executeSql("INSERT INTO DATA(_key, id, data) values(?, ?, ?)", 0, 0, 
testObj);
+
+        grid(0).cache(DEFAULT_CACHE_NAME).put(1, new Data(1, testObj));
+
+        grid(0).cache(DEFAULT_CACHE_NAME).put(2, grid(0).binary().toBinary(new 
Data(2, testObj)));
+
+        List<List<?>> selectData = executeSql("SELECT data FROM DATA");
+
+        Object sqlObj = sqlTypeConverter.apply(testObj);
+
+        selectData.forEach(d -> assertEquals(sqlObj, d.get(0)));
+    }
+
+    /** */
+    private void createTable() {
+        if (sqlType != null) {
+            executeSql("CREATE TABLE DATA (id INT PRIMARY KEY, data " + 
sqlType + ") WITH" +
+                " \"KEY_TYPE=java.lang.Integer" +
+                ", VALUE_TYPE=" + Data.class.getName() +
+                ", CACHE_NAME=default\"");
+        }
+        else {
+            QueryEntity projEntity = new QueryEntity();
+            projEntity.setKeyType(Integer.class.getName());
+            projEntity.setValueType(Data.class.getName());
+            projEntity.addQueryField("id", Integer.class.getName(), null);
+            projEntity.addQueryField("data", colType.getName(), null);
+
+            projEntity.setTableName("DATA");
+
+            grid(0).createCache(new CacheConfiguration<>(DEFAULT_CACHE_NAME)
+                .setQueryEntities(singletonList(projEntity))
+                .setSqlSchema("PUBLIC"));
+        }
+    }
+
+    /** */
+    private static Object generateTestObject(Class<?> cls, boolean isOldDate) {
+        LocalDateTime oldDateTime = LocalDateTime.of(1042, Month.APRIL, 1, 12, 
45, 0);
+        LocalDate oldDate = LocalDate.of(1042, Month.APRIL, 1);
+        if (cls == LocalDateTime.class)
+            return isOldDate ? oldDateTime : LocalDateTime.now();
+        else if (cls == LocalTime.class)
+            return LocalTime.now();
+        else if (cls == LocalDate.class)
+            return isOldDate ? oldDate : LocalDate.now();
+        else if (cls == Date.class)
+            return isOldDate ? new 
Date(convertToTimestamp(oldDateTime).getTime()) : Date.from(Instant.now());
+        else if (cls == java.sql.Date.class)
+            return isOldDate ? java.sql.Date.valueOf(oldDate) : 
java.sql.Date.valueOf(LocalDate.now());
+        else if (cls == java.sql.Time.class)
+            return java.sql.Time.valueOf(LocalTime.now());
+        else if (cls == java.sql.Timestamp.class)
+            return isOldDate ? convertToTimestamp(oldDateTime) : 
java.sql.Timestamp.valueOf(LocalDateTime.now());
+        else
+            throw new IllegalStateException();
+    }
+
+    /** */
+    private static <T, R> Function<Object, Object> f(Function<T, R> f) {
+        return (Function<Object, Object>)f;
+    }
+
+    /** */
+    public static class Data {
+        /** */
+        public int id;
+
+        /** */
+        public Object data;
+
+        /** */
+        public Data(int id, Object data) {
+            this.id = id;
+            this.data = data;
+        }
+    }
+}
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
 
b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
index 9a11cac9cf7..44a6113e9bf 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
@@ -39,6 +39,7 @@ import 
org.apache.ignite.internal.processors.query.calcite.integration.JoinInteg
 import 
org.apache.ignite.internal.processors.query.calcite.integration.KeepBinaryIntegrationTest;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.KillCommandDdlIntegrationTest;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.KillQueryCommandDdlIntegrationTest;
+import 
org.apache.ignite.internal.processors.query.calcite.integration.LocalDateTimeSupportTest;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.MemoryQuotasIntegrationTest;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.MetadataIntegrationTest;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.QueryEngineConfigurationIntegrationTest;
@@ -111,6 +112,7 @@ import org.junit.runners.Suite;
     KeepBinaryIntegrationTest.class,
     QueryMetadataIntegrationTest.class,
     MemoryQuotasIntegrationTest.class,
+    LocalDateTimeSupportTest.class
 })
 public class IntegrationTestSuite {
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
index c8c91394e96..273a3d73289 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
@@ -275,17 +275,4 @@ public interface GridQueryIndexing {
      * @throws IgniteCheckedException On bean registration error.
      */
     public void registerMxBeans(IgniteMBeansManager mbMgr) throws 
IgniteCheckedException;
-
-    /**
-     * Checks if object of the specified class can be stored in the specified 
table column by the query engine.
-     *
-     * @param schemaName Schema name.
-     * @param tblName Table name.
-     * @param colName Name of the column.
-     * @param cls Class to perform check on.
-     * @return Whether object of the specified class can be successfully 
stored and accessed from the SQL column by the
-     *         query engine.
-     * @throws IgniteSQLException if table or column with specified name was 
not found.
-     */
-    public boolean isConvertibleToColumnType(String schemaName, String 
tblName, String colName, Class<?> cls);
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
index 4da4d68b249..78a9d509767 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -635,7 +635,7 @@ public class QueryTypeDescriptorImpl implements 
GridQueryTypeDescriptor {
                     isKey ? NULL_KEY : NULL_VALUE);
             }
 
-            if (validateTypes && propVal != null && 
!isCompatibleWithPropertyType(propVal, prop.name(), prop.type())) {
+            if (validateTypes && propVal != null && 
!isCompatibleWithPropertyType(propVal, prop.type())) {
                 throw new IgniteSQLException("Type for a column '" + 
prop.name() + "' is not compatible with table definition." +
                     " Expected '" + prop.type().getSimpleName() + "', actual 
type '" + typeName(propVal) + "'");
             }
@@ -702,7 +702,7 @@ public class QueryTypeDescriptorImpl implements 
GridQueryTypeDescriptor {
                 if (propVal == null)
                     continue;
 
-                if (!isCompatibleWithPropertyType(propVal, idxField, 
propType)) {
+                if (!isCompatibleWithPropertyType(propVal, propType)) {
                     throw new IgniteSQLException("Type for a column '" + 
idxField + "' is not compatible with index definition." +
                         " Expected '" + prop.type().getSimpleName() + "', 
actual type '" + typeName(propVal) + "'");
                 }
@@ -714,17 +714,14 @@ public class QueryTypeDescriptorImpl implements 
GridQueryTypeDescriptor {
      * Checks if the specified object is compatible with the type of the 
column through which this object will be accessed.
      *
      * @param val Object to check.
-     * @param colName Name of the column to which current property corresponds.
      * @param expColType Type of the column based on Query Property info.
      */
-    private boolean isCompatibleWithPropertyType(Object val, String colName, 
Class<?> expColType) {
+    private boolean isCompatibleWithPropertyType(Object val, Class<?> 
expColType) {
         if (!(val instanceof BinaryObject) || val instanceof BinaryArray) {
             if (U.box(expColType).isAssignableFrom(U.box(val.getClass())))
                 return true;
 
-            GridQueryIndexing indexing = 
coCtx.kernalContext().query().getIndexing();
-
-            if (indexing != null && 
indexing.isConvertibleToColumnType(schemaName, tableName(), colName, 
val.getClass()))
+            if (QueryUtils.isConvertibleTypes(val, expColType))
                 return true;
 
             return expColType.isArray()
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index d9270156dd3..ecf9eaf28da 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -38,7 +38,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
-
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteSystemProperties;
@@ -1748,6 +1747,23 @@ public class QueryUtils {
         return DEFAULT_DELIM;
     }
 
+    /** */
+    public static boolean isConvertibleTypes(Object val, Class<?> expCls) {
+        if (val == null)
+            return true;
+
+        if (expCls == java.sql.Date.class || expCls == 
java.time.LocalDate.class)
+            return val instanceof java.sql.Date || val instanceof 
java.time.LocalDate;
+
+        if (expCls == java.sql.Time.class || expCls == 
java.time.LocalTime.class)
+            return val instanceof java.sql.Time || val instanceof 
java.time.LocalTime;
+
+        if (expCls == java.sql.Timestamp.class || expCls == 
java.util.Date.class || expCls == java.time.LocalDateTime.class)
+            return val instanceof java.time.LocalDateTime || val instanceof 
java.util.Date;
+
+        return false;
+    }
+
     /**
      * Private constructor.
      */
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java
index f1206050285..37f8f8ff12f 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/DummyQueryIndexing.java
@@ -202,9 +202,4 @@ public class DummyQueryIndexing implements 
GridQueryIndexing {
     @Override public void registerMxBeans(IgniteMBeansManager mbMgr) {
 
     }
-
-    /** {@inheritDoc} */
-    @Override public boolean isConvertibleToColumnType(String schemaName, 
String tblName, String colName, Class<?> cls) {
-        return false;
-    }
 }
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
index d5144301e5c..bfc03a5f190 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
@@ -30,20 +30,14 @@ import java.sql.SQLException;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.UUID;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
@@ -154,21 +148,6 @@ public class H2Utils {
     /** Quotation character. */
     private static final char ESC_CH = '\"';
 
-    /** Types that can be implicitly converted to H2 column type. */
-    private static final Map<Integer, Set<Class<?>>> CONVERTABLE_TYPES = new 
HashMap<Integer, Set<Class<?>>>() {
-        {
-            put(Value.TIMESTAMP, new HashSet<Class<?>>() {
-                {
-                    add(LocalDateTime.class);
-                    add(java.util.Date.class);
-                    add(java.sql.Date.class);
-                }
-            });
-            put(Value.TIME, Collections.singleton(LocalTime.class));
-            put(Value.DATE, Collections.singleton(LocalDate.class));
-        }
-    };
-
     /**
      * @param c1 First column.
      * @param c2 Second column.
@@ -535,33 +514,14 @@ public class H2Utils {
         return false;
     }
 
-    /**
-     * @param cls The class whose convertibility is to be tested.
-     * @param colType Column target type.
-     * @return Whether specified class can be implicitly converted to the 
specified type.
-     * @see #wrap(CacheObjectValueContext, Object, int)
-     */
-    public static boolean isConvertableToColumnType(Class<?> cls, int colType) 
{
-        assert cls != null;
-
-        if (DataType.getTypeClassName(colType).equals(cls.getName()))
-            return true;
-
-        Set<Class<?>> types = CONVERTABLE_TYPES.get(colType);
-
-        return types != null && types.contains(cls);
-    }
-
     /**
      * Wraps object to respective {@link Value}.
      *
-     * Note, implicit type conversions must be also included into {@link 
#CONVERTABLE_TYPES}.
      *
      * @param obj Object.
      * @param type Value type.
      * @return Value.
      * @throws IgniteCheckedException If failed.
-     * @see #isConvertableToColumnType(Class, int)
      */
     @SuppressWarnings("ConstantConditions")
     public static Value wrap(CacheObjectValueContext coCtx, Object obj, int 
type) throws IgniteCheckedException {
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index dbf55a4aef2..7b700a776c1 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -153,7 +153,6 @@ import org.h2.api.ErrorCode;
 import org.h2.api.JavaObjectSerializer;
 import org.h2.engine.Session;
 import org.h2.engine.SysProperties;
-import org.h2.message.DbException;
 import org.h2.util.JdbcUtils;
 import org.h2.value.CompareMode;
 import org.jetbrains.annotations.Nullable;
@@ -1805,22 +1804,6 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
         );
     }
 
-    /** {@inheritDoc} */
-    @Override public boolean isConvertibleToColumnType(String schemaName, 
String tblName, String colName, Class<?> cls) {
-        GridH2Table table = schemaMgr.dataTable(schemaName, tblName);
-
-        if (table == null)
-            throw new IgniteSQLException("Table was not found [schemaName=" + 
schemaName + ", tableName=" + tblName + ']');
-
-        try {
-            return H2Utils.isConvertableToColumnType(cls, 
table.getColumn(colName).getType());
-        }
-        catch (DbException e) {
-            throw new IgniteSQLException("Colum with specified name was not 
found for the table [schemaName=" + schemaName +
-                ", tableName=" + tblName + ", colName=" + colName + ']', e);
-        }
-    }
-
     /** {@inheritDoc} */
     @Override public boolean isStreamableInsertStatement(String schemaName, 
SqlFieldsQuery qry) throws SQLException {
         QueryParserResult parsed = parser.parse(schemaName, qry, true);
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/H2ColumnTypeConversionCheckSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/H2ColumnTypeConversionCheckSelfTest.java
deleted file mode 100644
index ed73d1edc7b..00000000000
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/H2ColumnTypeConversionCheckSelfTest.java
+++ /dev/null
@@ -1,57 +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.processors.query.h2;
-
-import java.sql.Timestamp;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-
-/** */
-public class H2ColumnTypeConversionCheckSelfTest extends 
GridCommonAbstractTest {
-    /** */
-    @Test
-    public void testConversions() throws Exception {
-        startGrid(0);
-
-        grid(0).context().query().querySqlFields(
-            new SqlFieldsQuery("CREATE TABLE TBL (id INT PRIMARY KEY, 
timestamp TIMESTAMP, date DATE, time TIME)"), false);
-
-        assertTrue(isConvertible("TIMESTAMP", Timestamp.class));
-        assertTrue(isConvertible("TIMESTAMP", java.sql.Date.class));
-        assertTrue(isConvertible("TIMESTAMP", java.util.Date.class));
-        assertTrue(isConvertible("TIMESTAMP", LocalDateTime.class));
-        assertFalse(isConvertible("TIMESTAMP", Integer.class));
-
-        assertTrue(isConvertible("DATE", java.sql.Date.class));
-        assertTrue(isConvertible("DATE", LocalDate.class));
-        assertFalse(isConvertible("DATE", Integer.class));
-
-        assertTrue(isConvertible("TIME", java.sql.Time.class));
-        assertTrue(isConvertible("TIME", LocalTime.class));
-        assertFalse(isConvertible("TIME", Integer.class));
-    }
-
-    /** */
-    private boolean isConvertible(String colName, Class<?> cls) {
-        return 
grid(0).context().query().getIndexing().isConvertibleToColumnType("PUBLIC", 
"TBL", colName, cls);
-    }
-}
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java
 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java
index f5f95b6c64a..93eefe1bf72 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite3.java
@@ -136,7 +136,6 @@ import 
org.apache.ignite.internal.processors.query.SqlQueryIndexWithDifferentTyp
 import org.apache.ignite.internal.processors.query.SqlSystemViewsSelfTest;
 import org.apache.ignite.internal.processors.query.h2.GridIndexRebuildSelfTest;
 import org.apache.ignite.internal.processors.query.h2.GridIndexRebuildTest;
-import 
org.apache.ignite.internal.processors.query.h2.H2ColumnTypeConversionCheckSelfTest;
 import 
org.apache.ignite.internal.processors.query.h2.QueryParserMetricsHolderSelfTest;
 import 
org.apache.ignite.internal.processors.query.h2.RowCountTableStatisticsSurvivesNodeRestartTest;
 import 
org.apache.ignite.internal.processors.query.h2.RowCountTableStatisticsUsageTest;
@@ -372,7 +371,6 @@ import org.junit.runners.Suite;
     InlineIndexKeyTypeRegistryTest.class,
 
     IgniteQueryConvertibleTypesValidationTest.class,
-    H2ColumnTypeConversionCheckSelfTest.class,
 
     IgniteStatisticsTestSuite.class,
 


Reply via email to