Make slimit and soffset available in align by device with template
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateIT.java index 78cda6b..9d64fa8 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateIT.java
@@ -578,6 +578,88 @@ } @Test + public void sLimitOffsetTest() { + // 1. original + String[] expectedHeader = new String[] {"Time,Device,s1"}; + String[] retArray = + new String[] { + "1,root.sg1.d1,1.1,", + "2,root.sg1.d1,2.2,", + "1,root.sg1.d2,11.1,", + "2,root.sg1.d2,22.2,", + "1,root.sg1.d3,111.1,", + "4,root.sg1.d3,444.4,", + "1,root.sg1.d4,1111.1,", + "5,root.sg1.d4,5555.5,", + }; + resultSetEqualTest( + "SELECT * FROM root.sg1.** slimit 1 soffset 1 ALIGN BY DEVICE;", expectedHeader, retArray); + retArray = + new String[] { + "1,root.sg2.d1,1.1,", + "2,root.sg2.d1,2.2,", + "1,root.sg2.d2,11.1,", + "2,root.sg2.d2,22.2,", + "1,root.sg2.d3,111.1,", + "4,root.sg2.d3,444.4,", + "1,root.sg2.d4,1111.1,", + "5,root.sg2.d4,5555.5,", + }; + resultSetEqualTest( + "SELECT * FROM root.sg2.** slimit 1 soffset 1 ALIGN BY DEVICE;", expectedHeader, retArray); + + expectedHeader = new String[] {"Time,Device,s1,s2"}; + retArray = + new String[] { + "1,root.sg1.d1,1.1,false,", + "2,root.sg1.d1,2.2,false,", + "1,root.sg1.d2,11.1,false,", + "2,root.sg1.d2,22.2,false,", + "1,root.sg1.d3,111.1,true,", + "4,root.sg1.d3,444.4,true,", + "1,root.sg1.d4,1111.1,true,", + "5,root.sg1.d4,5555.5,false,", + }; + resultSetEqualTest( + "SELECT *, s1 FROM root.sg1.** slimit 2 soffset 1 ALIGN BY DEVICE;", + expectedHeader, + retArray); + retArray = + new String[] { + "1,root.sg2.d1,1.1,false,", + "2,root.sg2.d1,2.2,false,", + "1,root.sg2.d2,11.1,false,", + "2,root.sg2.d2,22.2,false,", + "1,root.sg2.d3,111.1,true,", + "4,root.sg2.d3,444.4,true,", + "1,root.sg2.d4,1111.1,true,", + "5,root.sg2.d4,5555.5,false,", + }; + resultSetEqualTest( + "SELECT *, s1 FROM root.sg2.** slimit 2 soffset 1 ALIGN BY DEVICE;", + expectedHeader, + retArray); + + expectedHeader = new String[] {"Time,Device,s1"}; + retArray = + new String[] { + "1,root.sg1.d1,1.1,", "2,root.sg1.d1,2.2,", "1,root.sg1.d2,11.1,", "2,root.sg1.d2,22.2,", + }; + resultSetEqualTest( + "SELECT * FROM root.sg1.d1,root.sg1.d2,root.sg1.d6 soffset 1 slimit 1 ALIGN BY DEVICE;", + expectedHeader, + retArray); + retArray = + new String[] { + "1,root.sg2.d1,1.1,", "2,root.sg2.d1,2.2,", "1,root.sg2.d2,11.1,", "2,root.sg2.d2,22.2,", + }; + resultSetEqualTest( + "SELECT * FROM root.sg2.d1,root.sg2.d2,root.sg2.d6 soffset 1 slimit 1 ALIGN BY DEVICE;", + expectedHeader, + retArray); + } + + @Test public void emptyResultTest() { String[] expectedHeader = new String[] {"Time,Device,s3,s1,s2"}; String[] retArray = new String[] {};
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java index 5ec7997..a98503d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TemplatedAnalyze.java
@@ -113,29 +113,47 @@ Template template = templates.get(0); List<Pair<Expression, String>> outputExpressions = new ArrayList<>(); + ColumnPaginationController paginationController = + new ColumnPaginationController( + queryStatement.getSeriesLimit(), queryStatement.getSeriesOffset(), false); if (template != null) { for (ResultColumn resultColumn : queryStatement.getSelectComponent().getResultColumns()) { Expression expression = resultColumn.getExpression(); if ("*".equals(expression.getOutputSymbol())) { for (Map.Entry<String, IMeasurementSchema> entry : template.getSchemaMap().entrySet()) { - String measurementName = entry.getKey(); - IMeasurementSchema measurementSchema = entry.getValue(); - TimeSeriesOperand measurementPath = - new TimeSeriesOperand( - new MeasurementPath(new String[] {measurementName}, measurementSchema)); - outputExpressions.add(new Pair<>(measurementPath, null)); + if (paginationController.hasCurOffset()) { + paginationController.consumeOffset(); + } else if (paginationController.hasCurLimit()) { + String measurementName = entry.getKey(); + IMeasurementSchema measurementSchema = entry.getValue(); + TimeSeriesOperand measurementPath = + new TimeSeriesOperand( + new MeasurementPath(new String[] {measurementName}, measurementSchema)); + outputExpressions.add(new Pair<>(measurementPath, null)); + paginationController.consumeLimit(); + } else { + break; + } } - if (queryStatement.getSelectComponent().getResultColumns().size() == 1) { + if (queryStatement.getSelectComponent().getResultColumns().size() == 1 + && !paginationController.hasCurOffset() + && !paginationController.hasCurLimit()) { analysis.setTemplateWildCardQuery(); } } else if (expression instanceof TimeSeriesOperand) { String measurementName = ((TimeSeriesOperand) expression).getPath().getMeasurement(); if (template.getSchemaMap().containsKey(measurementName)) { - IMeasurementSchema measurementSchema = template.getSchemaMap().get(measurementName); - TimeSeriesOperand measurementPath = - new TimeSeriesOperand( - new MeasurementPath(new String[] {measurementName}, measurementSchema)); - outputExpressions.add(new Pair<>(measurementPath, resultColumn.getAlias())); + if (paginationController.hasCurOffset()) { + paginationController.consumeOffset(); + } else if (paginationController.hasCurLimit()) { + IMeasurementSchema measurementSchema = template.getSchemaMap().get(measurementName); + TimeSeriesOperand measurementPath = + new TimeSeriesOperand( + new MeasurementPath(new String[] {measurementName}, measurementSchema)); + outputExpressions.add(new Pair<>(measurementPath, resultColumn.getAlias())); + } else { + break; + } } } else { return false;