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

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


The following commit(s) were added to refs/heads/master by this push:
     new b1e69045f99 Support table model sql insertion without column name 
(#14310)
b1e69045f99 is described below

commit b1e69045f9934cadd99d07f8e2ae397b6ddfb001
Author: Jiang Tian <[email protected]>
AuthorDate: Fri Dec 6 09:33:31 2024 +0800

    Support table model sql insertion without column name (#14310)
    
    * Support table model sql insertion without column name
    
    * fix error message
---
 .../iotdb/session/it/IoTDBSessionRelationalIT.java |  62 ++++++++-
 .../protocol/thrift/impl/ClientRPCServiceImpl.java |   5 +-
 .../db/queryengine/plan/analyze/AnalyzeUtils.java  |   3 +-
 .../execution/config/TableConfigTaskVisitor.java   |   2 +-
 .../relational/analyzer/StatementAnalyzer.java     |   6 +-
 .../relational/sql/ast/WrappedInsertStatement.java |   3 +-
 .../plan/relational/sql/parser/AstBuilder.java     | 147 +++++++++++++++++++--
 .../plan/relational/sql/parser/SqlParser.java      |  28 ++--
 .../plan/statement/crud/InsertRowStatement.java    |   3 +-
 .../plan/relational/analyzer/AnalyzerTest.java     |   2 +-
 .../plan/relational/analyzer/TestUtils.java        |   2 +-
 .../plan/relational/planner/PlanTester.java        |   6 +-
 12 files changed, 233 insertions(+), 36 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionRelationalIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionRelationalIT.java
index d3e4cc4a23e..438c5844ca5 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionRelationalIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionRelationalIT.java
@@ -237,6 +237,22 @@ public class IoTDBSessionRelationalIT {
                 row, "id:" + row, "attr:" + row, row * 1.0));
       }
 
+      // without specifying column name
+      for (long row = 30; row < 40; row++) {
+        session.executeNonQueryStatement(
+            String.format(
+                "INSERT INTO table1 VALUES (%d, '%s', '%s', %f)",
+                row, "id:" + row, "attr:" + row, row * 1.0));
+      }
+
+      // auto data type conversion
+      for (long row = 40; row < 50; row++) {
+        session.executeNonQueryStatement(
+            String.format(
+                "INSERT INTO table1 VALUES (%d, '%s', '%s', %d)",
+                row, "id:" + row, "attr:" + row, row));
+      }
+
       SessionDataSet dataSet = session.executeQueryStatement("select * from 
table1 order by time");
       int cnt = 0;
       while (dataSet.hasNext()) {
@@ -247,7 +263,7 @@ public class IoTDBSessionRelationalIT {
         assertEquals(timestamp * 1.0, 
rowRecord.getFields().get(3).getDoubleV(), 0.0001);
         cnt++;
       }
-      assertEquals(30, cnt);
+      assertEquals(50, cnt);
 
       // sql cannot create column
       assertThrows(
@@ -257,6 +273,50 @@ public class IoTDBSessionRelationalIT {
                   String.format(
                       "INSERT INTO table1 (id1, id2, attr1, m1) VALUES ('%s', 
'%s', '%s', %f)",
                       "id:" + 100, "id:" + 100, "attr:" + 100, 100 * 1.0)));
+
+      // fewer columns than defined
+      assertThrows(
+          StatementExecutionException.class,
+          () ->
+              session.executeNonQueryStatement(
+                  String.format(
+                      "INSERT INTO table1 VALUES ( '%s', %f)", "attr:" + 100, 
100 * 1.0)));
+
+      // more columns than defined
+      assertThrows(
+          StatementExecutionException.class,
+          () ->
+              session.executeNonQueryStatement(
+                  String.format(
+                      "INSERT INTO table1 VALUES ('%s', '%s', '%s', '%s', %f)",
+                      "id:" + 100, "id:" + 100, "id:" + 100, "attr:" + 100, 
100 * 1.0)));
+
+      // invalid conversion - id column
+      assertThrows(
+          StatementExecutionException.class,
+          () ->
+              session.executeNonQueryStatement(
+                  String.format(
+                      "INSERT INTO table1 VALUES ('%d', '%s', '%s', %f)",
+                      100, 100, "attr:" + 100, 100 * 1.0)));
+
+      // invalid conversion - attr column
+      assertThrows(
+          StatementExecutionException.class,
+          () ->
+              session.executeNonQueryStatement(
+                  String.format(
+                      "INSERT INTO table1 VALUES ('%d', '%s', '%s', %f)",
+                      100, "id:" + 100, 100, 100 * 1.0)));
+
+      // invalid conversion - measurement column
+      assertThrows(
+          StatementExecutionException.class,
+          () ->
+              session.executeNonQueryStatement(
+                  String.format(
+                      "INSERT INTO table1 VALUES ('%d', '%s', '%s', %s)",
+                      100, "id:" + 100, "attr:" + 100, "measurement" + (100 * 
1.0))));
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
index 0bb353bb2c6..d038c07cbe7 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
@@ -343,7 +343,7 @@ public class ClientRPCServiceImpl implements 
IClientRPCServiceWithHandler {
                 req.getTimeout());
       } else {
         org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement s =
-            relationSqlParser.createStatement(statement, 
clientSession.getZoneId());
+            relationSqlParser.createStatement(statement, 
clientSession.getZoneId(), clientSession);
 
         if (s instanceof Use) {
           useDatabase = true;
@@ -1672,7 +1672,8 @@ public class ClientRPCServiceImpl implements 
IClientRPCServiceWithHandler {
           } else {
 
             org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement 
s =
-                relationSqlParser.createStatement(statement, 
clientSession.getZoneId());
+                relationSqlParser.createStatement(
+                    statement, clientSession.getZoneId(), clientSession);
 
             if (s instanceof Use) {
               useDatabase = true;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
index b997e1e886c..a59c614902d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
@@ -76,6 +76,7 @@ import java.util.stream.Collectors;
 
 import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT;
 import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
+import static 
org.apache.iotdb.db.queryengine.plan.execution.config.TableConfigTaskVisitor.DATABASE_NOT_SPECIFIED;
 
 public class AnalyzeUtils {
 
@@ -349,7 +350,7 @@ public class AnalyzeUtils {
     } else if (queryContext.getDatabaseName().isPresent()) {
       databaseName = queryContext.getDatabaseName().get();
     } else {
-      throw new SemanticException("Database is not specified");
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
     node.setDatabaseName(databaseName);
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index 86e8c691dd1..58efa1b5350 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -166,7 +166,7 @@ import static 
org.apache.tsfile.common.constant.TsFileConstant.PATH_SEPARATOR_CH
 
 public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, 
MPPQueryContext> {
 
-  private static final String DATABASE_NOT_SPECIFIED = "database is not 
specified";
+  public static final String DATABASE_NOT_SPECIFIED = "database is not 
specified";
 
   private final IClientSession clientSession;
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 8fdc1d2ae89..c29f337f725 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -188,6 +188,7 @@ import static java.util.Objects.requireNonNull;
 import static 
org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES;
 import static org.apache.iotdb.commons.schema.table.TsTable.TIME_COLUMN_NAME;
 import static 
org.apache.iotdb.db.queryengine.execution.warnings.StandardWarningCode.REDUNDANT_ORDER_BY;
+import static 
org.apache.iotdb.db.queryengine.plan.execution.config.TableConfigTaskVisitor.DATABASE_NOT_SPECIFIED;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.AggregationAnalyzer.verifyOrderByAggregations;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.AggregationAnalyzer.verifySourceAggregations;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.CanonicalizationAware.canonicalizationAwareKey;
@@ -496,7 +497,8 @@ public class StatementAnalyzer {
 
     @Override
     protected Scope visitInsert(Insert insert, Optional<Scope> scope) {
-      throw new SemanticException("Insert statement is not supported yet.");
+      throw new SemanticException(
+          "This kind of insert statement is not supported yet, please check 
your grammar.");
     }
 
     @Override
@@ -583,7 +585,7 @@ public class StatementAnalyzer {
           // If database is not specified, use the database from current 
session.
           // If still not specified, throw an exception.
           if (!queryContext.getDatabaseName().isPresent()) {
-            throw new SemanticException("Database is not specified");
+            throw new SemanticException(DATABASE_NOT_SPECIFIED);
           }
           loadTsFile.setDatabase(queryContext.getDatabaseName().get());
         }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/WrappedInsertStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/WrappedInsertStatement.java
index b951c02cc49..06d0003a9f5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/WrappedInsertStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/WrappedInsertStatement.java
@@ -44,6 +44,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static 
org.apache.iotdb.db.queryengine.plan.execution.config.TableConfigTaskVisitor.DATABASE_NOT_SPECIFIED;
 import static 
org.apache.iotdb.db.utils.EncodingInferenceUtils.getDefaultEncoding;
 
 public abstract class WrappedInsertStatement extends WrappedStatement
@@ -223,7 +224,7 @@ public abstract class WrappedInsertStatement extends 
WrappedStatement
   public String getDatabase() {
     String databaseName = 
AnalyzeUtils.getDatabaseName(getInnerTreeStatement(), context);
     if (databaseName == null) {
-      throw new SemanticException("database is not specified");
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
     return databaseName;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 2408ff12907..eb81b2a900c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -23,10 +23,14 @@ import 
org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.schema.cache.CacheClearOptions;
+import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
 import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
 import org.apache.iotdb.commons.utils.PathUtils;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.protocol.session.IClientSession;
 import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AliasedRelation;
@@ -83,7 +87,6 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Identifier;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InListExpression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InPredicate;
-import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Insert;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InsertRows;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Intersect;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IsNotNullPredicate;
@@ -175,6 +178,7 @@ import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.Ta
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlBaseVisitor;
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlLexer;
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlParser;
+import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.db.storageengine.load.config.LoadTsFileConfigurator;
 import org.apache.iotdb.db.utils.DateTimeUtils;
 import org.apache.iotdb.db.utils.TimestampPrecisionUtils;
@@ -184,7 +188,10 @@ import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.Token;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.exception.write.NoTableException;
 import org.apache.tsfile.utils.TimeDuration;
+import org.apache.tsfile.write.schema.MeasurementSchema;
 
 import javax.annotation.Nullable;
 
@@ -215,6 +222,7 @@ import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.ID;
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.MEASUREMENT;
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.TIME;
+import static 
org.apache.iotdb.db.queryengine.plan.execution.config.TableConfigTaskVisitor.DATABASE_NOT_SPECIFIED;
 import static 
org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor.parseDateTimeFormat;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets.Type.CUBE;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets.Type.EXPLICIT;
@@ -234,9 +242,12 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
   private final ZoneId zoneId;
 
-  AstBuilder(@Nullable NodeLocation baseLocation, ZoneId zoneId) {
+  private final IClientSession clientSession;
+
+  AstBuilder(@Nullable NodeLocation baseLocation, ZoneId zoneId, 
IClientSession clientSession) {
     this.baseLocation = baseLocation;
     this.zoneId = zoneId;
+    this.clientSession = clientSession;
   }
 
   @Override
@@ -436,24 +447,67 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
   @Override
   public Node visitInsertStatement(RelationalSqlParser.InsertStatementContext 
ctx) {
+    QualifiedName qualifiedName = getQualifiedName(ctx.tableName);
+    String tableName = qualifiedName.getSuffix();
+    String databaseName =
+        qualifiedName
+            .getPrefix()
+            .map(QualifiedName::toString)
+            .orElse(clientSession.getDatabaseName());
+    if (databaseName == null) {
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
+    }
+    tableName = tableName.toLowerCase();
+    databaseName = databaseName.toLowerCase();
+
+    Query query = (Query) visit(ctx.query());
     if (ctx.columnAliases() != null) {
-      Query query = (Query) visit(ctx.query());
       List<Identifier> identifiers = visit(ctx.columnAliases().identifier(), 
Identifier.class);
       if (query.getQueryBody() instanceof Values) {
         return visitInsertValues(
-            getQualifiedName(ctx.tableName), identifiers, ((Values) 
query.getQueryBody()));
+            databaseName, tableName, identifiers, ((Values) 
query.getQueryBody()));
+      } else {
+        throw new SemanticException("Only support insert by values.");
       }
-      return new Insert(new Table(getQualifiedName(ctx.tableName)), 
identifiers, query);
     } else {
-      return new Insert(new Table(getQualifiedName(ctx.tableName)), (Query) 
visit(ctx.query()));
+      if (query.getQueryBody() instanceof Values) {
+        TsTable table = 
DataNodeTableCache.getInstance().getTable(databaseName, tableName);
+        if (table == null) {
+          throw new SemanticException(new NoTableException(tableName));
+        }
+        return visitInsertValues(databaseName, table, ((Values) 
query.getQueryBody()));
+      } else {
+        throw new SemanticException("Only support insert by values.");
+      }
     }
   }
 
-  private Node visitInsertValues(
-      QualifiedName qualifiedTableName, List<Identifier> identifiers, Values 
queryBody) {
-    Optional<String> databaseName = 
qualifiedTableName.getPrefix().map(QualifiedName::toString);
-    String tableName = qualifiedTableName.getSuffix();
+  private Node visitInsertValues(String databaseName, TsTable table, Values 
queryBody) {
+    List<Expression> rows = queryBody.getRows();
+    List<InsertRowStatement> rowStatements =
+        rows.stream()
+            .map(
+                r -> {
+                  List<Expression> expressions;
+                  if (r instanceof Row) {
+                    expressions = ((Row) r).getItems();
+                  } else if (r instanceof Literal) {
+                    expressions = Collections.singletonList(r);
+                  } else {
+                    throw new SemanticException("unexpected expression: " + r);
+                  }
+                  return toInsertRowStatement(expressions, table, 
databaseName);
+                })
+            .collect(toList());
+
+    InsertRowsStatement insertRowsStatement = new InsertRowsStatement();
+    insertRowsStatement.setInsertRowStatementList(rowStatements);
+    insertRowsStatement.setWriteToTable(true);
+    return new InsertRows(insertRowsStatement, null);
+  }
 
+  private Node visitInsertValues(
+      String databaseName, String tableName, List<Identifier> identifiers, 
Values queryBody) {
     List<String> columnNames = 
identifiers.stream().map(Identifier::getValue).collect(toList());
     int timeColumnIndex = -1;
     for (int i = 0; i < columnNames.size(); i++) {
@@ -468,6 +522,7 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     if (timeColumnIndex != -1) {
       columnNames.remove(timeColumnIndex);
     }
+
     String[] columnNameArray = columnNames.toArray(new String[0]);
 
     List<Expression> rows = queryBody.getRows();
@@ -498,12 +553,79 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     return new InsertRows(insertRowsStatement, null);
   }
 
+  private InsertRowStatement toInsertRowStatement(
+      List<Expression> expressions, TsTable table, String databaseName) {
+    InsertRowStatement insertRowStatement = new InsertRowStatement();
+    insertRowStatement.setWriteToTable(true);
+    insertRowStatement.setDevicePath(new PartialPath(new String[] 
{table.getTableName()}));
+
+    List<TsTableColumnSchema> columnList = table.getColumnList();
+    if (expressions.size() != columnList.size()) {
+      throw new SemanticException(
+          "expressions and columns do not match, expressions size: "
+              + expressions.size()
+              + ", columns size: "
+              + columnList.size());
+    }
+
+    String[] nonTimeColumnNames = new String[columnList.size() - 1];
+    Object[] nonTimeValues = new Object[columnList.size() - 1];
+    TsTableColumnCategory[] nonTimeColumnCategories =
+        new TsTableColumnCategory[columnList.size() - 1];
+    MeasurementSchema[] columnSchemas = new 
MeasurementSchema[columnList.size() - 1];
+    TSDataType[] dataTypes = new TSDataType[columnList.size() - 1];
+    int nonTimeColumnIndex = 0;
+    long timestamp = -1;
+    for (int i = 0; i < columnList.size(); i++) {
+      TsTableColumnSchema columnSchema = columnList.get(i);
+      Expression expression = expressions.get(i);
+
+      if (columnSchema.getColumnCategory().equals(TIME)) {
+        if (expression instanceof LongLiteral) {
+          timestamp = ((LongLiteral) expression).getParsedValue();
+        } else {
+          timestamp =
+              parseDateTimeFormat(
+                  ((StringLiteral) expression).getValue(),
+                  CommonDateTimeUtils.currentTime(),
+                  zoneId);
+        }
+      } else {
+        Object value = AstUtil.expressionToTsValue(expression);
+        nonTimeValues[nonTimeColumnIndex] = value;
+        nonTimeColumnNames[nonTimeColumnIndex] = columnSchema.getColumnName();
+        dataTypes[nonTimeColumnIndex] = columnSchema.getDataType();
+        nonTimeColumnCategories[nonTimeColumnIndex] = 
columnSchema.getColumnCategory();
+        columnSchemas[nonTimeColumnIndex] =
+            new MeasurementSchema(columnSchema.getColumnName(), 
columnSchema.getDataType());
+        nonTimeColumnIndex++;
+      }
+    }
+
+    TimestampPrecisionUtils.checkTimestampPrecision(timestamp);
+    insertRowStatement.setTime(timestamp);
+    insertRowStatement.setMeasurements(nonTimeColumnNames);
+    insertRowStatement.setDataTypes(dataTypes);
+    insertRowStatement.setMeasurementSchemas(columnSchemas);
+    insertRowStatement.setValues(nonTimeValues);
+    insertRowStatement.setColumnCategories(nonTimeColumnCategories);
+    insertRowStatement.setNeedInferType(false);
+    insertRowStatement.setDatabaseName(databaseName);
+
+    try {
+      insertRowStatement.transferType(zoneId);
+    } catch (QueryProcessException e) {
+      throw new SemanticException(e);
+    }
+    return insertRowStatement;
+  }
+
   private InsertRowStatement toInsertRowStatement(
       List<Expression> expressions,
       int timeColumnIndex,
       String[] nonTimeColumnNames,
       String tableName,
-      Optional<String> databaseName) {
+      String databaseName) {
     InsertRowStatement insertRowStatement = new InsertRowStatement();
     insertRowStatement.setWriteToTable(true);
     insertRowStatement.setDevicePath(new PartialPath(new String[] 
{tableName}));
@@ -547,8 +669,7 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
     insertRowStatement.setValues(values);
     insertRowStatement.setNeedInferType(true);
-    databaseName.ifPresent(
-        databaseName1 -> 
insertRowStatement.setDatabaseName(databaseName1.toLowerCase()));
+    insertRowStatement.setDatabaseName(databaseName);
     return insertRowStatement;
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
index 1ee59aea651..377c88dfdb7 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.plan.relational.sql.parser;
 
 import org.apache.iotdb.commons.service.metric.PerformanceOverviewMetrics;
+import org.apache.iotdb.db.protocol.session.IClientSession;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DataType;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
@@ -99,35 +100,41 @@ public class SqlParser {
     this.initializer = requireNonNull(initializer, "initializer is null");
   }
 
-  public Statement createStatement(String sql, ZoneId zoneId) {
-    return (Statement) invokeParser("statement", sql, 
RelationalSqlParser::singleStatement, zoneId);
+  public Statement createStatement(String sql, ZoneId zoneId, IClientSession 
clientSession) {
+    return (Statement)
+        invokeParser("statement", sql, RelationalSqlParser::singleStatement, 
zoneId, clientSession);
   }
 
-  public Statement createStatement(String sql, NodeLocation location, ZoneId 
zoneId) {
+  public Statement createStatement(
+      String sql, NodeLocation location, ZoneId zoneId, IClientSession 
clientSession) {
     return (Statement)
         invokeParser(
             "statement",
             sql,
             Optional.ofNullable(location),
             RelationalSqlParser::singleStatement,
-            zoneId);
+            zoneId,
+            clientSession);
   }
 
   public Expression createExpression(String expression, ZoneId zoneId) {
     return (Expression)
-        invokeParser("expression", expression, 
RelationalSqlParser::standaloneExpression, zoneId);
+        invokeParser(
+            "expression", expression, 
RelationalSqlParser::standaloneExpression, zoneId, null);
   }
 
   public DataType createType(String expression, ZoneId zoneId) {
-    return (DataType) invokeParser("type", expression, 
RelationalSqlParser::standaloneType, zoneId);
+    return (DataType)
+        invokeParser("type", expression, RelationalSqlParser::standaloneType, 
zoneId, null);
   }
 
   private Node invokeParser(
       String name,
       String sql,
       Function<RelationalSqlParser, ParserRuleContext> parseFunction,
-      ZoneId zoneId) {
-    return invokeParser(name, sql, Optional.empty(), parseFunction, zoneId);
+      ZoneId zoneId,
+      IClientSession clientSession) {
+    return invokeParser(name, sql, Optional.empty(), parseFunction, zoneId, 
clientSession);
   }
 
   private Node invokeParser(
@@ -135,7 +142,8 @@ public class SqlParser {
       String sql,
       Optional<NodeLocation> location,
       Function<RelationalSqlParser, ParserRuleContext> parseFunction,
-      ZoneId zoneId) {
+      ZoneId zoneId,
+      IClientSession clientSession) {
     long startTime = System.nanoTime();
     try {
       RelationalSqlLexer lexer =
@@ -193,7 +201,7 @@ public class SqlParser {
         throw e;
       }
 
-      return new AstBuilder(location.orElse(null), zoneId).visit(tree);
+      return new AstBuilder(location.orElse(null), zoneId, 
clientSession).visit(tree);
     } catch (StackOverflowError e) {
       throw new ParsingException(name + " is too large (stack overflow while 
parsing)");
     } finally {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
index 45a381293a3..47905b362fa 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowStatement.java
@@ -226,8 +226,7 @@ public class InsertRowStatement extends InsertBaseStatement 
implements ISchemaVa
       dataTypes[i] = measurementSchemas[i].getType();
       try {
         // if the type is binary and the value is already binary, do not 
convert
-        if (values[i] instanceof String
-            || values[i] != null && !(dataTypes[i].isBinary() && values[i] 
instanceof Binary)) {
+        if (values[i] != null && !(dataTypes[i].isBinary() && values[i] 
instanceof Binary)) {
           values[i] = CommonUtils.parseValue(dataTypes[i], 
values[i].toString(), zoneId);
         }
       } catch (Exception e) {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index 2463e552c9b..780add1a7f9 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -1214,7 +1214,7 @@ public class AnalyzerTest {
 
   public static Analysis analyzeSQL(String sql, Metadata metadata, final 
MPPQueryContext context) {
     SqlParser sqlParser = new SqlParser();
-    Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault());
+    Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault(), null);
     SessionInfo session =
         new SessionInfo(
             0, "test", ZoneId.systemDefault(), "testdb", 
IClientSession.SqlDialect.TABLE);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestUtils.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestUtils.java
index 84bb5ba1a6e..e0628feff9a 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestUtils.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestUtils.java
@@ -143,7 +143,7 @@ public class TestUtils {
   public static void assertAnalyzeSemanticException(String sql, String 
message) {
     try {
       SqlParser sqlParser = new SqlParser();
-      Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault());
+      Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault(), null);
       SessionInfo session =
           new SessionInfo(
               0, "test", ZoneId.systemDefault(), "testdb", 
IClientSession.SqlDialect.TABLE);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanTester.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanTester.java
index 199942012d2..e8862d61a19 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanTester.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/PlanTester.java
@@ -41,6 +41,8 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.security.AllowAllAccessCo
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
 
+import org.mockito.Mockito;
+
 import java.time.ZoneId;
 import java.util.Collections;
 import java.util.List;
@@ -126,13 +128,15 @@ public class PlanTester {
 
   public static Analysis analyze(String sql, Metadata metadata) {
     SqlParser sqlParser = new SqlParser();
-    Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault());
     String databaseName;
     if (metadata instanceof TSBSMetadata) {
       databaseName = "tsbs";
     } else {
       databaseName = "testdb";
     }
+    IClientSession clientSession = Mockito.mock(IClientSession.class);
+    Mockito.when(clientSession.getDatabaseName()).thenReturn(databaseName);
+    Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault(), clientSession);
     SessionInfo session =
         new SessionInfo(
             0, "test", ZoneId.systemDefault(), databaseName, 
IClientSession.SqlDialect.TABLE);

Reply via email to