Skip to content

Commit aedc429

Browse files
committed
fix
Signed-off-by: Weihao Li <18110526956@163.com>
1 parent 402e399 commit aedc429

2 files changed

Lines changed: 143 additions & 1 deletion

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.relational.it.query.recent;
21+
22+
import org.apache.iotdb.it.env.EnvFactory;
23+
import org.apache.iotdb.it.framework.IoTDBTestRunner;
24+
import org.apache.iotdb.itbase.category.TableClusterIT;
25+
import org.apache.iotdb.itbase.category.TableLocalStandaloneIT;
26+
27+
import org.junit.AfterClass;
28+
import org.junit.BeforeClass;
29+
import org.junit.Test;
30+
import org.junit.experimental.categories.Category;
31+
import org.junit.runner.RunWith;
32+
33+
import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData;
34+
import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest;
35+
36+
@RunWith(IoTDBTestRunner.class)
37+
@Category({TableLocalStandaloneIT.class, TableClusterIT.class})
38+
public class IoTDBPruneFillGroupPreviousFlatIT {
39+
40+
private static final String DATABASE_NAME = "test";
41+
42+
private static final String[] createSqls =
43+
new String[] {
44+
"CREATE DATABASE " + DATABASE_NAME,
45+
"USE " + DATABASE_NAME,
46+
"CREATE TABLE m1(device_id STRING TAG, s1 INT64 FIELD)",
47+
"INSERT INTO m1(time, device_id, s1) values(2024-09-24T06:15:46.565+00:00, 'd1', 2)",
48+
"INSERT INTO m1(time, device_id, s1) values(2024-09-24T07:16:15.297+00:00, 'd1', 10)",
49+
"INSERT INTO m1(time, device_id, s1) values(2024-09-24T08:16:21.907+00:00, 'd2', 20)",
50+
};
51+
52+
private static final String FLAT_PREVIOUS_FILL_SQL =
53+
"SELECT date_bin_gapfill(1h, time) AS h, device_id, avg(s1) AS v "
54+
+ "FROM m1 "
55+
+ "WHERE time >= 2024-09-24T04:00:00.000+00:00 AND time < 2024-09-24T12:00:00.00+00:00 "
56+
+ "GROUP BY 1, 2 "
57+
+ "FILL METHOD PREVIOUS TIME_COLUMN 1 FILL_GROUP 2 "
58+
+ "ORDER BY 1, 2";
59+
60+
private static final String NESTED_OMIT_DEVICE_SQL =
61+
"SELECT h AS tm, sum(v) AS sv "
62+
+ "FROM ( "
63+
+ " SELECT date_bin_gapfill(1h, time) AS h, device_id, avg(s1) AS v "
64+
+ " FROM m1 "
65+
+ " WHERE time >= 2024-09-24T04:00:00.000+00:00 AND time < 2024-09-24T12:00:00.00+00:00 "
66+
+ " GROUP BY 1, 2 "
67+
+ " FILL METHOD PREVIOUS TIME_COLUMN 1 FILL_GROUP 2 "
68+
+ ") t "
69+
+ "GROUP BY h ORDER BY h";
70+
71+
@BeforeClass
72+
public static void setUp() {
73+
EnvFactory.getEnv().getConfig().getCommonConfig().setSortBufferSize(128 * 1024);
74+
EnvFactory.getEnv().getConfig().getCommonConfig().setEnableCrossSpaceCompaction(false);
75+
EnvFactory.getEnv().initClusterEnvironment();
76+
prepareTableData(createSqls);
77+
}
78+
79+
@AfterClass
80+
public static void tearDown() {
81+
EnvFactory.getEnv().cleanClusterEnvironment();
82+
}
83+
84+
@Test
85+
public void flatPreviousFill() {
86+
String[] header = new String[] {"h", "device_id", "v"};
87+
String[] rows =
88+
new String[] {
89+
"2024-09-24T04:00:00.000Z,d1,null,",
90+
"2024-09-24T04:00:00.000Z,d2,null,",
91+
"2024-09-24T05:00:00.000Z,d1,null,",
92+
"2024-09-24T05:00:00.000Z,d2,null,",
93+
"2024-09-24T06:00:00.000Z,d1,2.0,",
94+
"2024-09-24T06:00:00.000Z,d2,null,",
95+
"2024-09-24T07:00:00.000Z,d1,10.0,",
96+
"2024-09-24T07:00:00.000Z,d2,null,",
97+
"2024-09-24T08:00:00.000Z,d1,10.0,",
98+
"2024-09-24T08:00:00.000Z,d2,20.0,",
99+
"2024-09-24T09:00:00.000Z,d1,10.0,",
100+
"2024-09-24T09:00:00.000Z,d2,20.0,",
101+
"2024-09-24T10:00:00.000Z,d1,10.0,",
102+
"2024-09-24T10:00:00.000Z,d2,20.0,",
103+
"2024-09-24T11:00:00.000Z,d1,10.0,",
104+
"2024-09-24T11:00:00.000Z,d2,20.0,",
105+
};
106+
tableResultSetEqualTest(FLAT_PREVIOUS_FILL_SQL, header, rows, DATABASE_NAME);
107+
}
108+
109+
@Test
110+
public void nestedOmitTag() {
111+
String[] header = new String[] {"tm", "sv"};
112+
String[] rows =
113+
new String[] {
114+
"2024-09-24T04:00:00.000Z,null,",
115+
"2024-09-24T05:00:00.000Z,null,",
116+
"2024-09-24T06:00:00.000Z,2.0,",
117+
"2024-09-24T07:00:00.000Z,10.0,",
118+
"2024-09-24T08:00:00.000Z,30.0,",
119+
"2024-09-24T09:00:00.000Z,30.0,",
120+
"2024-09-24T10:00:00.000Z,30.0,",
121+
"2024-09-24T11:00:00.000Z,30.0,",
122+
};
123+
tableResultSetEqualTest(NESTED_OMIT_DEVICE_SQL, header, rows, DATABASE_NAME);
124+
}
125+
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PruneFillColumns.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
import org.apache.iotdb.commons.queryengine.plan.planner.plan.node.PlanNode;
2323
import org.apache.iotdb.commons.queryengine.plan.relational.planner.Symbol;
2424
import org.apache.iotdb.commons.queryengine.plan.relational.planner.node.FillNode;
25+
import org.apache.iotdb.commons.queryengine.plan.relational.planner.node.LinearFillNode;
26+
import org.apache.iotdb.commons.queryengine.plan.relational.planner.node.PreviousFillNode;
27+
28+
import com.google.common.collect.ImmutableSet;
2529

2630
import java.util.Optional;
2731
import java.util.Set;
@@ -38,6 +42,19 @@ public PruneFillColumns() {
3842
@Override
3943
protected Optional<PlanNode> pushDownProjectOff(
4044
Context context, FillNode fillNode, Set<Symbol> referencedOutputs) {
41-
return restrictChildOutputs(context.getIdAllocator(), fillNode, referencedOutputs);
45+
// Like PruneGapFillColumns: TIME_COLUMN / helper and FILL_GROUP symbols must remain in the
46+
// child's output even if no outer consumer references them (e.g. nested subquery pruning).
47+
ImmutableSet.Builder<Symbol> referencedInputs = ImmutableSet.builder();
48+
referencedInputs.addAll(referencedOutputs);
49+
if (fillNode instanceof PreviousFillNode) {
50+
PreviousFillNode previousFillNode = (PreviousFillNode) fillNode;
51+
previousFillNode.getHelperColumn().ifPresent(referencedInputs::add);
52+
previousFillNode.getGroupingKeys().ifPresent(keys -> referencedInputs.addAll(keys));
53+
} else if (fillNode instanceof LinearFillNode) {
54+
LinearFillNode linearFillNode = (LinearFillNode) fillNode;
55+
referencedInputs.add(linearFillNode.getHelperColumn());
56+
linearFillNode.getGroupingKeys().ifPresent(keys -> referencedInputs.addAll(keys));
57+
}
58+
return restrictChildOutputs(context.getIdAllocator(), fillNode, referencedInputs.build());
4259
}
4360
}

0 commit comments

Comments
 (0)