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

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

commit d140df3b80c29fa7316e6813bafe6720594e479b
Author: Tian Jiang <[email protected]>
AuthorDate: Tue Aug 20 10:17:12 2024 +0800

    Fix insert statement creation when there is only one column.
---
 .../relational/it/db/it/IoTDBInsertTableIT.java    | 37 ++++++++++++++++++++++
 .../fetcher/TableHeaderSchemaValidator.java        |  2 +-
 .../plan/relational/sql/parser/AstBuilder.java     | 28 ++++++++++------
 3 files changed, 57 insertions(+), 10 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java
index b56726f333b..a0e7361dff4 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java
@@ -711,6 +711,43 @@ public class IoTDBInsertTableIT {
     }
   }
 
+  @Test
+  public void testInsertSingleColumn() throws SQLException {
+    try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+        Statement st1 = connection.createStatement()) {
+      st1.execute("use \"test\"");
+      st1.execute(
+          "create table if not exists sg21 (id1 string id, ss1 string 
attribute, ss2 int32 measurement)");
+      // only id
+      st1.execute("insert into sg21(id1) values('1')");
+      // only time
+      try {
+        st1.execute("insert into sg21(time) values(1)");
+      } catch (SQLException e) {
+        assertEquals("305: [INTERNAL_SERVER_ERROR(305)] Exception occurred: 
\"insert into sg21(time) values(1)\". executeStatement failed. No column other 
than Time present, please check the request", e.getMessage());
+      }
+      // only attribute
+      st1.execute("insert into sg21(ss1) values('1')");
+      // only measurement
+      st1.execute("insert into sg21(ss2) values(1)");
+
+      ResultSet rs1 = st1.executeQuery("show devices from sg21");
+      assertTrue(rs1.next());
+      // from "insert into sg21(ss2) values(1)"
+      assertEquals(null, rs1.getString("id1"));
+      assertTrue(rs1.next());
+      // from "insert into sg21(id1) values('1')"
+      assertEquals("1", rs1.getString("id1"));
+      assertFalse(rs1.next());
+
+      rs1 = st1.executeQuery("select time, ss1, ss2 from sg21 order by time");
+      assertTrue(rs1.next());
+      assertEquals("1", rs1.getString("ss1"));
+      assertEquals(1, rs1.getInt("ss2"));
+      assertFalse(rs1.next());
+    }
+  }
+
   private List<Integer> checkHeader(
       ResultSetMetaData resultSetMetaData, String expectedHeaderStrings, int[] 
expectedTypes)
       throws SQLException {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
index a6103521040..3bd069e2a0a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
@@ -88,7 +88,7 @@ public class TableHeaderSchemaValidator {
     List<ColumnSchema> inputColumnList = tableSchema.getColumns();
     if (inputColumnList == null || inputColumnList.isEmpty()) {
       throw new IllegalArgumentException(
-          "Column List in TableSchema should never be null or empty.");
+          "No column other than Time present, please check the request");
     }
     TsTable table = DataNodeTableCache.getInstance().getTable(database, 
tableSchema.getTableName());
     List<ColumnSchema> missingColumnList = new ArrayList<>();
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 1780c5e0061..499ad9575b1 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
@@ -82,6 +82,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.JoinOn;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.JoinUsing;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LikePredicate;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Limit;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NaturalJoin;
@@ -416,9 +417,18 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     List<InsertRowStatement> rowStatements =
         rows.stream()
             .map(
-                r ->
-                    toInsertRowStatement(
-                        ((Row) r), finalTimeColumnIndex, columnNameArray, 
tableName, databaseName))
+                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, finalTimeColumnIndex, columnNameArray, 
tableName, databaseName);
+                })
             .collect(toList());
 
     InsertRowsStatement insertRowsStatement = new InsertRowsStatement();
@@ -428,7 +438,7 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
   }
 
   private InsertRowStatement toInsertRowStatement(
-      Row row,
+      List<Expression> expressions,
       int timeColumnIndex,
       String[] nonTimeColumnNames,
       String tableName,
@@ -440,9 +450,9 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     int nonTimeColCnt;
     if (timeColumnIndex == -1) {
       timestamp = CommonDateTimeUtils.currentTime();
-      nonTimeColCnt = row.getItems().size();
+      nonTimeColCnt = expressions.size();
     } else {
-      Expression timeExpression = row.getItems().get(timeColumnIndex);
+      Expression timeExpression = expressions.get(timeColumnIndex);
       if (timeExpression instanceof LongLiteral) {
         timestamp = ((LongLiteral) timeExpression).getParsedValue();
       } else {
@@ -452,7 +462,7 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
                 CommonDateTimeUtils.currentTime(),
                 zoneId);
       }
-      nonTimeColCnt = row.getItems().size() - 1;
+      nonTimeColCnt = expressions.size() - 1;
     }
 
     if (nonTimeColCnt != nonTimeColumnNames.length) {
@@ -468,9 +478,9 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
     Object[] values = new Object[nonTimeColumnNames.length];
     int valuePos = 0;
-    for (int i = 0; i < row.getItems().size(); i++) {
+    for (int i = 0; i < expressions.size(); i++) {
       if (i != timeColumnIndex) {
-        values[valuePos++] = 
AstUtil.expressionToTsValue(row.getItems().get(i));
+        values[valuePos++] = AstUtil.expressionToTsValue(expressions.get(i));
       }
     }
 

Reply via email to