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

jackietien pushed a commit to branch ty/OptTypeMismatchErrorMsg
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 62aaf7943c8fea2966c08df25ee84740e4dfc974
Author: JackieTien97 <[email protected]>
AuthorDate: Wed Aug 21 21:35:39 2024 +0800

    Opt type mismatch error msg
---
 .../org/apache/iotdb/db/it/utils/TestUtils.java    |  2 +-
 .../scalar/IoTDBScalarFunctionTableIT.java         | 49 +++++++++++++++++
 .../fragment/FragmentInstanceContext.java          | 10 +++-
 .../execution/schedule/AbstractDriverThread.java   | 10 +++-
 .../queryengine/plan/execution/QueryExecution.java |  6 +++
 .../relational/metadata/TableMetadataImpl.java     | 11 ++--
 .../binary/CompareBinaryColumnTransformer.java     |  3 +-
 .../scalar/CastFunctionColumnTransformer.java      | 62 +++++++++++++---------
 8 files changed, 117 insertions(+), 36 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
index 2e6f975dac9..b4d8a521bd4 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
@@ -278,7 +278,7 @@ public class TestUtils {
       statement.executeQuery(sql);
       fail("No exception!");
     } catch (SQLException e) {
-      Assert.assertTrue(e.getMessage().contains(errMsg));
+      Assert.assertTrue(e.getMessage(), e.getMessage().contains(errMsg));
     }
   }
 
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBScalarFunctionTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBScalarFunctionTableIT.java
index dd67aa726d1..908eab95e1e 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBScalarFunctionTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBScalarFunctionTableIT.java
@@ -366,6 +366,43 @@ public class IoTDBScalarFunctionTableIT {
         DATABASE_NAME);
   }
 
+  @Test
+  public void testBlobCompare() {
+    // case 1: support INT32, INT64, FLOAT, DOUBLE
+    String[] expectedHeader = new String[] {"s10", "res1", "res2", "res3"};
+    String[] expectedAns =
+        new String[] {
+          "0xabcd,true,true,true,",
+        };
+    tableResultSetEqualTest(
+        "select s10, s10 > x'2d' as res1, s10 <> x'2d' as res2, s10 = X'abcd' 
as res3 from absTable",
+        expectedHeader,
+        expectedAns,
+        DATABASE_NAME);
+  }
+
+  @Test
+  public void testDateCompare() {
+    // case 1: support INT32, INT64, FLOAT, DOUBLE
+    String[] expectedHeader = new String[] {"s7", "res1", "res2", "res3"};
+    String[] expectedAns =
+        new String[] {
+          "2021-10-01,true,true,true,",
+        };
+    // add it back while supporting Implicit conversion
+    //    tableResultSetEqualTest(
+    //        "select s7, s7 < '2022-12-12' as res1, s7 <> '2022-12-12' as 
res2, s7 = '2021-10-01'
+    // as res3 from absTable",
+    //        expectedHeader,
+    //        expectedAns,
+    //        DATABASE_NAME);
+    tableResultSetEqualTest(
+        "select s7, s7 < CAST('2022-12-12' AS DATE) as res1, s7 <> 
CAST('2022-12-12' AS DATE) AS res2, s7 = CAST('2021-10-01' AS DATE) as res3 
from absTable",
+        expectedHeader,
+        expectedAns,
+        DATABASE_NAME);
+  }
+
   @Test
   public void absTestFail() {
     // case 1: more than one argument
@@ -409,6 +446,18 @@ public class IoTDBScalarFunctionTableIT {
         TSStatusCode.SEMANTIC_ERROR.getStatusCode()
             + ": Scalar function abs only accepts one argument and it must be 
TimeStamp, Double, Float, Int32 or Int64 data type.",
         DATABASE_NAME);
+
+    // case 7: wrong data type
+    tableAssertTestFail(
+        "select s7, s7 < '2022-12-12', s7 <> '2022-12-12', s7 = '2021-10-01' 
from absTable",
+        TSStatusCode.SEMANTIC_ERROR.getStatusCode() + ": Cannot apply 
operator: DATE < STRING",
+        DATABASE_NAME);
+
+    // case 7: wrong data type
+    tableAssertTestFail(
+        "select CAST(s1 AS INT32) from absTable",
+        TSStatusCode.SEMANTIC_ERROR.getStatusCode() + ": Cannot cast abcd to 
INT32 type",
+        DATABASE_NAME);
   }
 
   @Test
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
index 9648b1701fb..9519ecb0212 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.queryengine.execution.fragment;
 
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.exception.IoTDBException;
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
 import org.apache.iotdb.commons.path.IFullPath;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
@@ -316,11 +317,16 @@ public class FragmentInstanceContext extends QueryContext 
{
 
   public Optional<TSStatus> getErrorCode() {
     return stateMachine.getFailureCauses().stream()
-        .filter(IoTDBException.class::isInstance)
+        .filter(e -> e instanceof IoTDBException || e instanceof 
IoTDBRuntimeException)
         .findFirst()
         .flatMap(
             t -> {
-              TSStatus status = new TSStatus(((IoTDBException) 
t).getErrorCode());
+              TSStatus status;
+              if (t instanceof IoTDBException) {
+                status = new TSStatus(((IoTDBException) t).getErrorCode());
+              } else {
+                status = new TSStatus(((IoTDBRuntimeException) 
t).getErrorCode());
+              }
               status.setMessage(t.getMessage());
               return Optional.of(status);
             });
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/schedule/AbstractDriverThread.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/schedule/AbstractDriverThread.java
index 381c9b9378a..b4664703b45 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/schedule/AbstractDriverThread.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/schedule/AbstractDriverThread.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.execution.schedule;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.exception.MemoryNotEnoughException;
 import 
org.apache.iotdb.db.queryengine.execution.schedule.queue.IndexedBlockingQueue;
 import org.apache.iotdb.db.queryengine.execution.schedule.task.DriverTask;
@@ -78,8 +79,13 @@ public abstract class AbstractDriverThread extends Thread 
implements Closeable {
           // reset the thread name here
           try (SetThreadName driverTaskName =
               new 
SetThreadName(next.getDriver().getDriverTaskId().getFullId())) {
-            logger.warn("[ExecuteFailed]", e);
-            next.setAbortCause(getAbortCause(e));
+            Throwable rootCause = ErrorHandlingUtils.getRootCause(e);
+            if (rootCause instanceof SemanticException) {
+              next.setAbortCause(e.getMessage());
+            } else {
+              logger.warn("[ExecuteFailed]", e);
+              next.setAbortCause(getAbortCause(e));
+            }
             scheduler.toAborted(next);
           }
         } finally {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
index d7cfc4bc240..59056f5c2b5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.IoTDBException;
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
 import org.apache.iotdb.commons.service.metric.PerformanceOverviewMetrics;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
@@ -478,6 +479,11 @@ public class QueryExecution implements IQueryExecution {
           stateMachine.getFailureStatus().getMessage(), 
stateMachine.getFailureStatus().code);
     } else if (stateMachine.getFailureException() != null) {
       Throwable rootCause = stateMachine.getFailureException();
+      if (rootCause instanceof IoTDBRuntimeException) {
+        throw (IoTDBRuntimeException) rootCause;
+      } else if (rootCause instanceof IoTDBException) {
+        throw (IoTDBException) rootCause;
+      }
       throw new IoTDBException(rootCause, 
TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
     } else {
       throwIfUnchecked(t);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index bfe07f693f4..01ce776d4f3 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -44,7 +44,7 @@ import 
org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.db.utils.constant.SqlConstant;
 
 import org.apache.tsfile.file.metadata.IDeviceID;
-import org.apache.tsfile.read.common.type.DateType;
+import org.apache.tsfile.read.common.type.BlobType;
 import org.apache.tsfile.read.common.type.StringType;
 import org.apache.tsfile.read.common.type.TimestampType;
 import org.apache.tsfile.read.common.type.Type;
@@ -667,6 +667,10 @@ public class TableMetadataImpl implements Metadata {
     return TEXT.equals(type) || StringType.STRING.equals(type);
   }
 
+  public static boolean isBlobType(Type type) {
+    return BlobType.BLOB.equals(type);
+  }
+
   public static boolean isSupportedMathNumericType(Type type) {
     return DOUBLE.equals(type) || FLOAT.equals(type) || INT32.equals(type) || 
INT64.equals(type);
   }
@@ -694,9 +698,6 @@ public class TableMetadataImpl implements Metadata {
     }
 
     // Boolean type and Binary Type can not be compared with other types
-    return (isNumericType(left) && isNumericType(right))
-        || (isCharType(left) && isCharType(right))
-        || (isCharType(left) && DateType.DATE.equals(right))
-        || (DateType.DATE.equals(left) && isCharType(right));
+    return (isNumericType(left) && isNumericType(right)) || (isCharType(left) 
&& isCharType(right));
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareBinaryColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareBinaryColumnTransformer.java
index 17c4abe41e7..04f6f87436f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareBinaryColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/CompareBinaryColumnTransformer.java
@@ -28,6 +28,7 @@ import 
org.apache.tsfile.read.common.block.column.RunLengthEncodedColumn;
 import org.apache.tsfile.read.common.type.Type;
 import org.apache.tsfile.read.common.type.TypeEnum;
 
+import static 
org.apache.iotdb.db.queryengine.plan.relational.metadata.TableMetadataImpl.isBlobType;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.metadata.TableMetadataImpl.isCharType;
 
 public abstract class CompareBinaryColumnTransformer extends 
BinaryColumnTransformer {
@@ -51,7 +52,7 @@ public abstract class CompareBinaryColumnTransformer extends 
BinaryColumnTransfo
       if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
         boolean flag = false;
         // compare binary type
-        if (isCharType(leftTransformer.getType())) {
+        if (isCharType(leftTransformer.getType()) || 
isBlobType(leftTransformer.getType())) {
           flag =
               transform(
                   TransformUtils.compare(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
index 7ef2b156935..41bc76a0ff5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import 
org.apache.iotdb.db.queryengine.plan.expression.multi.builtin.helper.CastFunctionHelper;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
 import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
@@ -30,6 +31,9 @@ import org.apache.tsfile.read.common.type.Type;
 import org.apache.tsfile.read.common.type.TypeEnum;
 import org.apache.tsfile.utils.Binary;
 import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.DateUtils;
+
+import java.time.format.DateTimeParseException;
 
 public class CastFunctionColumnTransformer extends UnaryColumnTransformer {
 
@@ -237,31 +241,39 @@ public class CastFunctionColumnTransformer extends 
UnaryColumnTransformer {
 
   private void cast(ColumnBuilder columnBuilder, Binary value) {
     String stringValue = value.getStringValue(TSFileConfig.STRING_CHARSET);
-    switch (returnType.getTypeEnum()) {
-      case INT32:
-      case DATE:
-        returnType.writeInt(columnBuilder, Integer.parseInt(stringValue));
-        break;
-      case INT64:
-      case TIMESTAMP:
-        returnType.writeLong(columnBuilder, Long.parseLong(stringValue));
-        break;
-      case FLOAT:
-        returnType.writeFloat(columnBuilder, 
CastFunctionHelper.castTextToFloat(stringValue));
-        break;
-      case DOUBLE:
-        returnType.writeDouble(columnBuilder, 
CastFunctionHelper.castTextToDouble(stringValue));
-        break;
-      case BOOLEAN:
-        returnType.writeBoolean(columnBuilder, 
CastFunctionHelper.castTextToBoolean(stringValue));
-        break;
-      case TEXT:
-      case STRING:
-      case BLOB:
-        returnType.writeBinary(columnBuilder, value);
-        break;
-      default:
-        throw new UnsupportedOperationException(String.format(ERROR_MSG, 
returnType.getTypeEnum()));
+    try {
+      switch (returnType.getTypeEnum()) {
+        case INT32:
+          returnType.writeInt(columnBuilder, Integer.parseInt(stringValue));
+          break;
+        case DATE:
+          returnType.writeInt(columnBuilder, 
DateUtils.parseDateExpressionToInt(stringValue));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          returnType.writeLong(columnBuilder, Long.parseLong(stringValue));
+          break;
+        case FLOAT:
+          returnType.writeFloat(columnBuilder, 
CastFunctionHelper.castTextToFloat(stringValue));
+          break;
+        case DOUBLE:
+          returnType.writeDouble(columnBuilder, 
CastFunctionHelper.castTextToDouble(stringValue));
+          break;
+        case BOOLEAN:
+          returnType.writeBoolean(columnBuilder, 
CastFunctionHelper.castTextToBoolean(stringValue));
+          break;
+        case TEXT:
+        case STRING:
+        case BLOB:
+          returnType.writeBinary(columnBuilder, value);
+          break;
+        default:
+          throw new UnsupportedOperationException(
+              String.format(ERROR_MSG, returnType.getTypeEnum()));
+      }
+    } catch (DateTimeParseException | NumberFormatException e) {
+      throw new SemanticException(
+          String.format("Cannot cast %s to %s type", stringValue, 
returnType.getDisplayName()));
     }
   }
 }

Reply via email to