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)); } }
