This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch ty/insertTime in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 8b7da66fe20d94ad8356638c8330ce9d80d98686 Author: JackieTien97 <[email protected]> AuthorDate: Fri Feb 23 16:26:04 2024 +0800 [IOTDB-6300] Support place time column at any column index in insert statement --- .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 18 ++-- .../db/queryengine/plan/parser/ASTVisitor.java | 101 ++++++++++++--------- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 index d64bbd4d1d6..1a3d09e4f47 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 @@ -806,21 +806,21 @@ insertStatement ; insertColumnsSpec - : LR_BRACKET (TIMESTAMP|TIME)? (COMMA? nodeNameWithoutWildcard)+ RR_BRACKET + : LR_BRACKET insertColumn (COMMA insertColumn)* RR_BRACKET ; -insertValuesSpec - : (COMMA? insertMultiValue)* +insertColumn + : identifier + | TIME + | TIMESTAMP ; -insertMultiValue - : LR_BRACKET timeValue (COMMA measurementValue)+ RR_BRACKET - | LR_BRACKET (measurementValue COMMA?)+ RR_BRACKET +insertValuesSpec + : row (COMMA row)* ; -measurementValue - : constant - | LR_BRACKET constant (COMMA constant)+ RR_BRACKET +row + : LR_BRACKET constant (COMMA constant)* RR_BRACKET ; // Delete Statement diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index 3b93613c294..7032653df8e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -1802,78 +1802,95 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> { public Statement visitInsertStatement(IoTDBSqlParser.InsertStatementContext ctx) { InsertStatement insertStatement = new InsertStatement(); insertStatement.setDevice(parsePrefixPath(ctx.prefixPath())); - boolean isTimeDefault = parseInsertColumnSpec(ctx.insertColumnsSpec(), insertStatement); - parseInsertValuesSpec(ctx.insertValuesSpec(), insertStatement, isTimeDefault); + int timeIndex = parseInsertColumnSpec(ctx.insertColumnsSpec(), insertStatement); + parseInsertValuesSpec(ctx.insertValuesSpec(), insertStatement, timeIndex); insertStatement.setAligned(ctx.ALIGNED() != null); return insertStatement; } - private boolean parseInsertColumnSpec( + private int parseInsertColumnSpec( IoTDBSqlParser.InsertColumnsSpecContext ctx, InsertStatement insertStatement) { List<String> measurementList = new ArrayList<>(); - for (IoTDBSqlParser.NodeNameWithoutWildcardContext measurementName : - ctx.nodeNameWithoutWildcard()) { - measurementList.add(parseNodeNameWithoutWildCard(measurementName)); + int timeIndex = -1; + + for (int i = 0, size = ctx.insertColumn().size(); i < size; i++) { + String measurement = parseInsertColumn(ctx.insertColumn(i)); + if ("time".equalsIgnoreCase(measurement) || "timestamp".equalsIgnoreCase(measurement)) { + if (timeIndex != -1) { + throw new SemanticException("One row should only have one time value"); + } else { + timeIndex = i; + } + } else { + measurementList.add(measurement); + } } insertStatement.setMeasurementList(measurementList.toArray(new String[0])); - return (ctx.TIME() == null && ctx.TIMESTAMP() == null); + return timeIndex; + } + + private String parseInsertColumn(IoTDBSqlParser.InsertColumnContext columnContext) { + return parseNodeString(columnContext.getText()); } private void parseInsertValuesSpec( - IoTDBSqlParser.InsertValuesSpecContext ctx, - InsertStatement insertStatement, - boolean isTimeDefault) { - List<IoTDBSqlParser.InsertMultiValueContext> insertMultiValues = ctx.insertMultiValue(); + IoTDBSqlParser.InsertValuesSpecContext ctx, InsertStatement insertStatement, int timeIndex) { + List<IoTDBSqlParser.RowContext> rows = ctx.row(); + if (timeIndex == -1 && rows.size() != 1) { + throw new SemanticException("need timestamps when insert multi rows"); + } List<String[]> valuesList = new ArrayList<>(); - long[] timeArray = new long[insertMultiValues.size()]; - for (int i = 0; i < insertMultiValues.size(); i++) { + long[] timeArray = new long[rows.size()]; + for (int i = 0, size = rows.size(); i < size; i++) { + IoTDBSqlParser.RowContext row = rows.get(i); // parse timestamp long timestamp; List<String> valueList = new ArrayList<>(); - - if (insertMultiValues.get(i).timeValue() != null) { - if (isTimeDefault) { - if (insertMultiValues.size() != 1) { - throw new SemanticException("need timestamps when insert multi rows"); - } - valueList.add(insertMultiValues.get(i).timeValue().getText()); - timestamp = CommonDateTimeUtils.currentTime(); - } else { - timestamp = - parseTimeValue( - insertMultiValues.get(i).timeValue(), CommonDateTimeUtils.currentTime()); - TimestampPrecisionUtils.checkTimestampPrecision(timestamp); - } + // using now() instead + if (timeIndex == -1) { + timestamp = CommonDateTimeUtils.currentTime(); } else { - if (!isTimeDefault) { - throw new SemanticException( - "the measurementList's size is not consistent with the valueList's size"); - } - if (insertMultiValues.size() != 1) { - throw new SemanticException("need timestamps when insert multi rows"); - } - timestamp = parseDateFormat(SqlConstant.NOW_FUNC); + timestamp = parseTimeValue(row.constant(timeIndex)); + TimestampPrecisionUtils.checkTimestampPrecision(timestamp); } timeArray[i] = timestamp; // parse values - List<IoTDBSqlParser.MeasurementValueContext> values = - insertMultiValues.get(i).measurementValue(); - for (IoTDBSqlParser.MeasurementValueContext value : values) { - for (IoTDBSqlParser.ConstantContext constant : value.constant()) { - if (constant.STRING_LITERAL() != null) { - valueList.add(parseStringLiteralInInsertValue(constant.getText())); + List<ConstantContext> values = row.constant(); + for (int j = 0, columnCount = values.size(); j < columnCount; j++) { + if (j != timeIndex) { + if (values.get(j).STRING_LITERAL() != null) { + valueList.add(parseStringLiteralInInsertValue(values.get(j).getText())); } else { - valueList.add(constant.getText()); + valueList.add(values.get(j).getText()); } } } + valuesList.add(valueList.toArray(new String[0])); } insertStatement.setTimes(timeArray); insertStatement.setValuesList(valuesList); } + private long parseTimeValue(ConstantContext constant) { + if (constant.INTEGER_LITERAL() != null) { + try { + if (constant.MINUS() != null) { + return -Long.parseLong(constant.INTEGER_LITERAL().getText()); + } + return Long.parseLong(constant.INTEGER_LITERAL().getText()); + } catch (NumberFormatException e) { + throw new SemanticException( + String.format("Can not parse %s to long value", constant.INTEGER_LITERAL().getText())); + } + } else if (constant.dateExpression() != null) { + return parseDateExpression(constant.dateExpression(), CommonDateTimeUtils.currentTime()); + } else { + throw new SemanticException(String.format("Can not parse %s to time", constant)); + } + } + // Load File @Override
