diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/selectinto/IoTDBSelectIntoIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/selectinto/IoTDBSelectIntoIT.java index 90c5ea657254..3e013c898ba8 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/selectinto/IoTDBSelectIntoIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/selectinto/IoTDBSelectIntoIT.java @@ -785,4 +785,53 @@ public void testNewDataType() { String expectedQueryHeader = "Time,root.db.d2.s7,root.db.d2.s8,root.db.d2.s9,root.db.d2.s10,"; resultSetEqualTest("select s7,s8,s9,s10 from root.db.d2;", expectedQueryHeader, resultSet); } + + // -------------------------------------- OTHER TEST ------------------------------------- + @Test + public void testRemoveBackQuote() { + String[] intoRetArray = + new String[] { + "count(root.sg.d1.s1),root.sg_agg1.d1.count_s1,1,", + "last_value(root.sg.d1.s2),root.sg_agg1.d1.last_value_s2,1,", + "count(root.sg.d2.s1),root.sg_agg1.d2.count_s1,1,", + "last_value(root.sg.d2.s2),root.sg_agg1.d2.last_value_s2,1," + }; + resultSetEqualTest( + "select count(d1.s1), last_value(d1.s2), count(d2.s1), last_value(d2.s2) " + + "into root.sg_agg1.`d1`(`count_s1`, last_value_s2), aligned root.sg_agg1.d2(count_s1, last_value_s2) " + + "from root.sg;", + selectIntoHeader, + intoRetArray); + + String expectedQueryHeader = + "Time,root.sg_agg1.d1.count_s1,root.sg_agg1.d2.count_s1,root.sg_agg1.d1.last_value_s2,root.sg_agg1.d2.last_value_s2,"; + String[] queryRetArray = new String[] {"0,10,7,12.0,11.0,"}; + resultSetEqualTest( + "select count_s1, last_value_s2 from root.sg_agg1.d1, root.sg_agg1.d2;", + expectedQueryHeader, + queryRetArray); + } + + @Test + public void testRemoveBackQuoteAlignByDevice() { + String[] intoRetArray = + new String[] { + "root.sg.d1,count(s1),root.sg_abd_agg1.d1.count_s1,1,", + "root.sg.d1,last_value(s2),root.sg_abd_agg1.d1.last_value_s2,1," + }; + resultSetEqualTest( + "select count(s1), last_value(s2) " + + "into root.sg_abd_agg1.`d1`(`count_s1`, last_value_s2) " + + "from root.sg.d1 align by device;", + selectIntoAlignByDeviceHeader, + intoRetArray); + + String expectedQueryHeader = + "Time,root.sg_abd_agg1.d1.count_s1," + "root.sg_abd_agg1.d1.last_value_s2,"; + String[] queryRetArray = new String[] {"0,10,12.0,"}; + resultSetEqualTest( + "select count_s1, last_value_s2 from root.sg_abd_agg1.d1, root.sg_abd_agg1.d2;", + expectedQueryHeader, + queryRetArray); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java index 5178a8488057..05c915b90817 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java @@ -211,8 +211,10 @@ import static org.apache.iotdb.db.queryengine.plan.analyze.SelectIntoUtils.constructTargetDevice; import static org.apache.iotdb.db.queryengine.plan.analyze.SelectIntoUtils.constructTargetMeasurement; import static org.apache.iotdb.db.queryengine.plan.analyze.SelectIntoUtils.constructTargetPath; +import static org.apache.iotdb.db.queryengine.plan.analyze.SelectIntoUtils.constructTargetPathWithoutPlaceHolder; import static org.apache.iotdb.db.queryengine.plan.optimization.LimitOffsetPushDown.canPushDownLimitOffsetInGroupByTimeForDevice; import static org.apache.iotdb.db.queryengine.plan.optimization.LimitOffsetPushDown.pushDownLimitOffsetInGroupByTimeForDevice; +import static org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor.parseNodeString; import static org.apache.iotdb.db.schemaengine.schemaregion.view.visitor.GetSourcePathsVisitor.getSourcePaths; import static org.apache.iotdb.db.storageengine.load.metrics.LoadTsFileCostMetricsSet.ANALYSIS; import static org.apache.iotdb.db.utils.constant.SqlConstant.COUNT_TIME_HEADER; @@ -2343,7 +2345,7 @@ private void analyzeInto( constructTargetMeasurement( sourceDevice.concatNode(sourceColumn.getExpressionString()), measurementTemplate); } else { - targetMeasurement = measurementTemplate; + targetMeasurement = parseNodeString(measurementTemplate); } deviceViewIntoPathDescriptor.specifyTargetDeviceMeasurement( sourceDevice, targetDevice, sourceColumn.getExpressionString(), targetMeasurement); @@ -2414,7 +2416,7 @@ private void analyzeInto( } targetPath = constructTargetPath(sourcePath, deviceTemplate, measurementTemplate); } else { - targetPath = deviceTemplate.concatNode(measurementTemplate); + targetPath = constructTargetPathWithoutPlaceHolder(deviceTemplate, measurementTemplate); } intoPathDescriptor.specifyTargetPath(sourceColumn, viewPath, targetPath); intoPathDescriptor.specifyDeviceAlignment( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/SelectIntoUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/SelectIntoUtils.java index d0c3617d530f..2a64f06d1868 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/SelectIntoUtils.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/SelectIntoUtils.java @@ -26,7 +26,6 @@ import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree; import org.apache.iotdb.db.queryengine.plan.expression.Expression; import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand; -import org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor; import org.apache.iotdb.db.utils.TypeInferenceUtils; import org.apache.tsfile.enums.TSDataType; @@ -41,6 +40,7 @@ import static com.google.common.base.Preconditions.checkState; import static org.apache.iotdb.commons.conf.IoTDBConstant.DOUBLE_COLONS; import static org.apache.iotdb.commons.conf.IoTDBConstant.LEVELED_PATH_TEMPLATE_PATTERN; +import static org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor.parseNodeString; public class SelectIntoUtils { @@ -48,6 +48,18 @@ private SelectIntoUtils() { // forbidding instantiation } + public static PartialPath constructTargetPathWithoutPlaceHolder( + PartialPath devicePath, String measurement) { + String[] originalDeviceNodes = devicePath.getNodes(); + String[] resNodes = new String[originalDeviceNodes.length + 1]; + + for (int i = 0; i < originalDeviceNodes.length; i++) { + resNodes[i] = parseNodeString(originalDeviceNodes[i]); + } + resNodes[resNodes.length - 1] = parseNodeString(measurement); + return new MeasurementPath(resNodes); + } + public static PartialPath constructTargetPath( PartialPath sourcePath, PartialPath deviceTemplate, String measurementTemplate) { PartialPath targetDevice = constructTargetDevice(sourcePath.getDevicePath(), deviceTemplate); @@ -108,7 +120,7 @@ private static String applyLevelPlaceholder(String templateNode, String[] source resNode = matcher.replaceFirst(sourceNodes[index]); matcher = LEVELED_PATH_TEMPLATE_PATTERN.matcher(resNode); } - return ASTVisitor.parseNodeString(resNode); + return parseNodeString(resNode); } public static boolean checkIsAllRawSeriesQuery(List expressions) {