You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2024/02/23 08:26:18 UTC
(iotdb) 01/01: [IOTDB-6300] Support place time column at any column index in insert statement
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 <ja...@gmail.com>
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