Skip to content

Commit c56e155

Browse files
committed
fix: add test for where clause and template change. correct pushdown in PBTree mode.
1 parent 4027f97 commit c56e155

File tree

3 files changed

+90
-36
lines changed

3 files changed

+90
-36
lines changed

integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBShowTimeseriesOrderByTimeseriesIT.java

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import java.util.Arrays;
3838
import java.util.Collections;
3939
import java.util.List;
40+
import java.util.stream.Collectors;
41+
import java.util.stream.Stream;
4042

4143
import static org.junit.Assert.assertEquals;
4244
import static org.junit.Assert.assertTrue;
@@ -45,18 +47,13 @@
4547
@Category({LocalStandaloneIT.class, ClusterIT.class})
4648
public class IoTDBShowTimeseriesOrderByTimeseriesIT extends AbstractSchemaIT {
4749

48-
private static final List<String> BASE_TIMESERIES =
49-
Arrays.asList(
50-
"root.db1.devA.m1",
51-
"root.db1.devA.m2",
52-
"root.db1.devB.m1",
53-
"root.db1.devB.x",
54-
"root.db2.devA.m1",
55-
"root.db2.devC.m0",
56-
"root.db2.devC.m3",
57-
"root.db3.z.m1",
58-
"root.db3.z.m10",
59-
"root.db3.z.m2");
50+
private static final List<String> BASE_TIMESERIES_DB1 =
51+
Arrays.asList("root.db1.devA.m1", "root.db1.devB.m1", "root.db1.devA.m2", "root.db1.devB.x");
52+
private static final List<String> BASE_TIMESERIES_DB2 =
53+
Arrays.asList("root.db2.devA.m1", "root.db2.devC.m3", "root.db2.devC.m0");
54+
private static final List<String> BASE_TIMESERIES = // combine db1 and db2
55+
Stream.concat(BASE_TIMESERIES_DB1.stream(), BASE_TIMESERIES_DB2.stream())
56+
.collect(Collectors.toList());
6057

6158
public IoTDBShowTimeseriesOrderByTimeseriesIT(SchemaTestMode schemaTestMode) {
6259
super(schemaTestMode);
@@ -84,7 +81,6 @@ private void prepareComplexSchema() throws Exception {
8481
Statement statement = connection.createStatement()) {
8582
statement.execute("CREATE DATABASE root.db1");
8683
statement.execute("CREATE DATABASE root.db2");
87-
statement.execute("CREATE DATABASE root.db3");
8884

8985
for (String ts : BASE_TIMESERIES) {
9086
statement.execute(
@@ -119,13 +115,13 @@ public void testOrderAscWithoutLimit() throws Exception {
119115
@Test
120116
public void testOrderDescWithOffsetLimit() throws Exception {
121117
prepareComplexSchema();
122-
List<String> expected = new ArrayList<>(BASE_TIMESERIES);
118+
List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
123119
Collections.sort(expected);
124120
Collections.reverse(expected);
125-
expected = expected.subList(2, 6); // offset 2 limit 4
121+
expected = expected.subList(1, 3); // offset 1 limit 2
126122

127123
List<String> actual =
128-
queryTimeseries("show timeseries root.db*.** order by timeseries desc offset 2 limit 4");
124+
queryTimeseries("show timeseries root.db1.** order by timeseries desc offset 1 limit 2");
129125
assertEquals(expected, actual);
130126
}
131127

@@ -135,14 +131,14 @@ public void testInsertThenQueryOrder() throws Exception {
135131
try (Connection connection = EnvFactory.getEnv().getConnection();
136132
Statement statement = connection.createStatement()) {
137133
statement.execute(
138-
"create timeseries root.db0.devX.a with datatype=INT32, encoding=RLE, compression=SNAPPY");
134+
"create timeseries root.db1.devX.a with datatype=INT32, encoding=RLE, compression=SNAPPY");
139135
}
140136

141-
List<String> expected = new ArrayList<>(BASE_TIMESERIES);
142-
expected.add("root.db0.devX.a");
137+
List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
138+
expected.add("root.db1.devX.a");
143139
Collections.sort(expected);
144140

145-
List<String> actual = queryTimeseries("show timeseries root.db*.** order by timeseries");
141+
List<String> actual = queryTimeseries("show timeseries root.db1.** order by timeseries");
146142
assertEquals(expected, actual);
147143
}
148144

@@ -154,12 +150,12 @@ public void testDeleteSubtreeThenQueryOrder() throws Exception {
154150
statement.execute("delete timeseries root.db2.devC.**");
155151
}
156152

157-
List<String> expected = new ArrayList<>(BASE_TIMESERIES);
153+
List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB2);
158154
expected.remove("root.db2.devC.m0");
159155
expected.remove("root.db2.devC.m3");
160156
Collections.sort(expected);
161157

162-
List<String> actual = queryTimeseries("show timeseries root.db*.** order by timeseries");
158+
List<String> actual = queryTimeseries("show timeseries root.db2.** order by timeseries");
163159
assertEquals(expected, actual);
164160
}
165161

@@ -172,18 +168,18 @@ public void testOffsetLimitAfterDeletesAndAdds() throws Exception {
172168
statement.execute(
173169
"create timeseries root.db1.devC.m0 with datatype=INT32, encoding=RLE, compression=SNAPPY");
174170
statement.execute(
175-
"create timeseries root.db4.devZ.z with datatype=INT32, encoding=RLE, compression=SNAPPY");
171+
"create timeseries root.db1.devZ.z with datatype=INT32, encoding=RLE, compression=SNAPPY");
176172
}
177173

178-
List<String> expected = new ArrayList<>(BASE_TIMESERIES);
174+
List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
179175
expected.remove("root.db1.devB.x");
180176
expected.add("root.db1.devC.m0");
181-
expected.add("root.db4.devZ.z");
177+
expected.add("root.db1.devZ.z");
182178
Collections.sort(expected);
183-
expected = expected.subList(5, 10); // offset 5 limit 5
179+
expected = expected.subList(2, 4); // offset 2 limit 2
184180

185181
List<String> actual =
186-
queryTimeseries("show timeseries root.db*.** order by timeseries offset 5 limit 5");
182+
queryTimeseries("show timeseries root.db1.** order by timeseries offset 2 limit 2");
187183
assertEquals(expected, actual);
188184
}
189185

@@ -218,4 +214,49 @@ public void testConflictWithTimeCondition() throws Exception {
218214
}
219215
}
220216
}
217+
218+
@Test
219+
public void testWhereClauseOffsetAppliedAfterFilter() throws Exception {
220+
try (Connection connection = EnvFactory.getEnv().getConnection();
221+
Statement statement = connection.createStatement()) {
222+
statement.execute("CREATE DATABASE root.ln");
223+
statement.execute(
224+
"create timeseries root.ln.wf01.wt01.status with datatype=INT32, encoding=RLE, compression=SNAPPY");
225+
statement.execute(
226+
"create timeseries root.ln.wf02.wt01.status with datatype=INT32, encoding=RLE, compression=SNAPPY");
227+
statement.execute(
228+
"create timeseries root.ln.wf02.wt02.status with datatype=INT32, encoding=RLE, compression=SNAPPY");
229+
}
230+
231+
List<String> actual =
232+
queryTimeseries(
233+
"show timeseries root.ln.** where timeseries contains 'wf02.wt' order by timeseries offset 1 limit 1");
234+
assertEquals(Collections.singletonList("root.ln.wf02.wt02.status"), actual);
235+
}
236+
237+
@Test
238+
public void testAlterTemplateUpdatesOffsetOrder() throws Exception {
239+
try (Connection connection = EnvFactory.getEnv().getConnection();
240+
Statement statement = connection.createStatement()) {
241+
statement.execute("CREATE DATABASE root.sg1");
242+
statement.execute("create device template t1 (s1 INT32)");
243+
statement.execute("set device template t1 to root.sg1.d1");
244+
statement.execute("create timeseries using device template on root.sg1.d1");
245+
statement.execute("set device template t1 to root.sg1.d2");
246+
statement.execute("create timeseries using device template on root.sg1.d2");
247+
}
248+
249+
List<String> before =
250+
queryTimeseries("show timeseries root.sg1.** order by timeseries desc offset 1 limit 1");
251+
assertEquals(Arrays.asList("root.sg1.d1.s1"), before);
252+
253+
try (Connection connection = EnvFactory.getEnv().getConnection();
254+
Statement statement = connection.createStatement()) {
255+
statement.execute("alter device template t1 add (s2 INT32)");
256+
}
257+
258+
List<String> after =
259+
queryTimeseries("show timeseries root.sg1.** order by timeseries desc offset 2 limit 2");
260+
assertEquals(Arrays.asList("root.sg1.d1.s2", "root.sg1.d1.s1"), after);
261+
}
221262
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.iotdb.db.queryengine.plan.planner;
2020

21+
import org.apache.iotdb.commons.conf.CommonDescriptor;
2122
import org.apache.iotdb.commons.path.PartialPath;
2223
import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
2324
import org.apache.iotdb.commons.schema.template.Template;
@@ -90,6 +91,7 @@
9091
import org.apache.iotdb.db.queryengine.plan.statement.pipe.PipeEnrichedStatement;
9192
import org.apache.iotdb.db.queryengine.plan.statement.sys.ExplainAnalyzeStatement;
9293
import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowQueriesStatement;
94+
import org.apache.iotdb.db.schemaengine.SchemaEngineMode;
9395

9496
import org.apache.tsfile.enums.TSDataType;
9597
import org.apache.tsfile.file.metadata.IDeviceID;
@@ -582,17 +584,27 @@ public PlanNode visitShowTimeSeries(
582584
boolean singleSchemaRegion =
583585
analysis.getSchemaPartitionInfo() != null
584586
&& analysis.getSchemaPartitionInfo().getDistributionInfo().size() == 1;
587+
boolean isMemorySchemaEngine =
588+
CommonDescriptor.getInstance()
589+
.getConfig()
590+
.getSchemaEngineMode()
591+
.equals(SchemaEngineMode.Memory.toString());
592+
boolean isNeedSortDescInPBTree =
593+
!isMemorySchemaEngine && showTimeSeriesStatement.getNameOrdering() == Ordering.DESC;
585594
boolean canPushDownOffsetLimit =
586595
singleSchemaRegion
596+
&& !isNeedSortDescInPBTree
587597
&& !showTimeSeriesStatement.isOrderByHeat()
588598
&& showTimeSeriesStatement.getSchemaFilter() == null;
589599

590-
if (showTimeSeriesStatement.isOrderByHeat()) {
591-
limit = 0;
592-
offset = 0;
593-
} else if (!canPushDownOffsetLimit) {
594-
limit = showTimeSeriesStatement.getLimitWithOffset();
595-
offset = 0;
600+
if (!canPushDownOffsetLimit) {
601+
if (showTimeSeriesStatement.isOrderByHeat() || isNeedSortDescInPBTree) {
602+
limit = 0;
603+
offset = 0;
604+
} else {
605+
limit = showTimeSeriesStatement.getLimitWithOffset();
606+
offset = 0;
607+
}
596608
}
597609
boolean orderByTimeseries = showTimeSeriesStatement.isOrderByTimeseries();
598610
boolean orderByTimeseriesDesc =
@@ -613,8 +625,9 @@ public PlanNode visitShowTimeSeries(
613625
orderByTimeseriesDesc)
614626
.planSchemaQueryMerge(showTimeSeriesStatement.isOrderByHeat());
615627

616-
// order by timeseries name in multi-region case: still need global SortNode
617-
if (showTimeSeriesStatement.isOrderByTimeseries() && !singleSchemaRegion) {
628+
// order by timeseries name in multi-region or PBTree-DESC case: still need global SortNode
629+
if (showTimeSeriesStatement.isOrderByTimeseries()
630+
&& (!singleSchemaRegion || isNeedSortDescInPBTree)) {
618631
SortItem sortItem =
619632
new SortItem(ColumnHeaderConstant.TIMESERIES, showTimeSeriesStatement.getNameOrdering());
620633
planBuilder = planBuilder.planOrderBy(Collections.singletonList(sortItem));

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class BasicMNode implements IMemMNode {
4646
private IMemMNode parent;
4747
private final BasicMNodeInfo basicMNodeInfo;
4848

49-
/** Cached count of measurements in this node's subtree, restored on restart. */
49+
/** Cached count of measurements in this node's subtree, rebuilt on restart. */
5050
private long subtreeMeasurementCount = 0L;
5151

5252
/** from root to this node, only be set when used once for InternalMNode */

0 commit comments

Comments
 (0)