Skip to content

Commit 12c9a41

Browse files
committed
add logical plan optimize of row pattern
1 parent a78d605 commit 12c9a41

File tree

4 files changed

+281
-1
lines changed

4 files changed

+281
-1
lines changed

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@
7777

7878
import com.google.common.collect.ImmutableList;
7979
import com.google.common.collect.ImmutableSet;
80-
import javax.annotation.Nonnull;
8180
import org.apache.tsfile.common.conf.TSFileConfig;
8281
import org.apache.tsfile.file.metadata.IDeviceID;
8382
import org.apache.tsfile.utils.Pair;
8483

84+
import javax.annotation.Nonnull;
85+
8586
import java.util.ArrayList;
8687
import java.util.Collections;
8788
import java.util.Comparator;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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.db.queryengine.plan.relational.planner.iterative.rule;
21+
22+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
23+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.PatternRecognitionNode;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrPatternAlternationOptimizer;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrRowPattern;
26+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrRowPatternFlattener;
27+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
28+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
29+
30+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns.patternRecognition;
31+
32+
public class OptimizeRowPattern implements Rule<PatternRecognitionNode> {
33+
private static final Pattern<PatternRecognitionNode> PATTERN = patternRecognition();
34+
35+
@Override
36+
public Pattern<PatternRecognitionNode> getPattern() {
37+
return PATTERN;
38+
}
39+
40+
@Override
41+
public Result apply(PatternRecognitionNode node, Captures captures, Context context) {
42+
IrRowPattern optimizedPattern =
43+
IrPatternAlternationOptimizer.optimize(IrRowPatternFlattener.optimize(node.getPattern()));
44+
45+
if (optimizedPattern.equals(node.getPattern())) {
46+
return Result.empty();
47+
}
48+
49+
return Result.ofPlanNode(
50+
new PatternRecognitionNode(
51+
node.getPlanNodeId(),
52+
node.getChild(),
53+
node.getPartitionBy(),
54+
node.getOrderingScheme(),
55+
node.getHashSymbol(),
56+
node.getMeasures(),
57+
node.getRowsPerMatch(),
58+
node.getSkipToLabels(),
59+
node.getSkipToPosition(),
60+
optimizedPattern,
61+
node.getVariableDefinitions()));
62+
}
63+
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/LogicalOptimizeFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.MergeLimitWithSort;
3333
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.MergeLimits;
3434
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.MultipleDistinctAggregationToMarkDistinct;
35+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.OptimizeRowPattern;
3536
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneAggregationColumns;
3637
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneAggregationSourceColumns;
3738
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneApplyColumns;
@@ -154,6 +155,13 @@ public LogicalOptimizeFactory(PlannerContext plannerContext) {
154155
ImmutableList.Builder<PlanOptimizer> optimizerBuilder = ImmutableList.builder();
155156

156157
optimizerBuilder.add(
158+
new IterativeOptimizer(
159+
plannerContext,
160+
ruleStats,
161+
ImmutableSet.<Rule<?>>builder()
162+
.addAll(new CanonicalizeExpressions(plannerContext, typeAnalyzer).rules())
163+
.add(new OptimizeRowPattern())
164+
.build()),
157165
new IterativeOptimizer(
158166
plannerContext,
159167
ruleStats,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
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.db.queryengine.execution.operator.process.rowpattern;
21+
22+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrPatternAlternationOptimizer;
23+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrRowPattern;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.IrRowPatternFlattener;
25+
26+
import org.junit.Assert;
27+
import org.junit.Test;
28+
29+
import java.util.Optional;
30+
31+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.alternation;
32+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.concatenation;
33+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.empty;
34+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.excluded;
35+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.label;
36+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.permutation;
37+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.plusQuantified;
38+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.questionMarkQuantified;
39+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.rangeQuantified;
40+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.rowpattern.Patterns.starQuantified;
41+
42+
public class IrRowPatternOptimizationTest {
43+
@Test
44+
public void testFlattenAlternation() {
45+
assertFlattened(
46+
alternation(label("A"), alternation(label("B"), label("C"))),
47+
alternation(label("A"), label("B"), label("C")));
48+
49+
assertFlattened(
50+
alternation(
51+
alternation(
52+
label("A"),
53+
alternation(
54+
alternation(label("B"), label("C")), alternation(label("D"), label("E")))),
55+
alternation(label("F"), label("G"))),
56+
alternation(
57+
label("A"), label("B"), label("C"), label("D"), label("E"), label("F"), label("G")));
58+
}
59+
60+
@Test
61+
public void testOptimizeAlternation() {
62+
assertOptimized(
63+
alternation(alternation(label("A"), empty()), label("B")),
64+
alternation(questionMarkQuantified(label("A"), true), label("B")));
65+
66+
assertOptimized(
67+
alternation(alternation(empty(), label("A")), label("B")),
68+
alternation(questionMarkQuantified(label("A"), false), label("B")));
69+
}
70+
71+
@Test
72+
public void testFlattenAndOptimizeAlternation() {
73+
assertFlattenedOptimized(
74+
alternation(alternation(label("A"), label("B")), label("C")),
75+
alternation(label("A"), label("B"), label("C")));
76+
77+
assertFlattenedOptimized(
78+
alternation(alternation(label("A"), label("B")), empty()),
79+
alternation(label("A"), questionMarkQuantified(label("B"), true)));
80+
81+
assertFlattenedOptimized(
82+
alternation(alternation(empty(), label("A")), empty()),
83+
questionMarkQuantified(label("A"), false));
84+
85+
assertFlattenedOptimized(alternation(empty(), empty()), empty());
86+
87+
assertFlattenedOptimized(
88+
alternation(
89+
alternation(
90+
label("A"),
91+
alternation(
92+
alternation(empty(), alternation(alternation(label("B"), empty()), label("C"))),
93+
empty())),
94+
label("D")),
95+
alternation(questionMarkQuantified(label("A"), true), label("B"), label("C"), label("D")));
96+
}
97+
98+
@Test
99+
public void testFlattenConcatenation() {
100+
assertFlattened(
101+
concatenation(concatenation(label("A"), label("B")), label("C")),
102+
concatenation(label("A"), label("B"), label("C")));
103+
104+
assertFlattened(
105+
concatenation(concatenation(concatenation(label("A"), label("B")), empty()), label("C")),
106+
concatenation(label("A"), label("B"), label("C")));
107+
108+
assertFlattened(
109+
concatenation(concatenation(concatenation(empty(), label("A")), label("B")), label("C")),
110+
concatenation(label("A"), label("B"), label("C")));
111+
112+
assertFlattened(
113+
concatenation(
114+
concatenation(
115+
concatenation(
116+
concatenation(
117+
concatenation(concatenation(empty(), label("A")), empty()), label("B")),
118+
empty()),
119+
label("C")),
120+
empty()),
121+
concatenation(label("A"), label("B"), label("C")));
122+
123+
assertFlattened(concatenation(empty(), label("A")), label("A"));
124+
assertFlattened(concatenation(label("A"), empty()), label("A"));
125+
assertFlattened(concatenation(concatenation(empty(), empty()), empty()), empty());
126+
127+
assertFlattened(
128+
concatenation(label("A"), concatenation(label("B"), label("C"))),
129+
concatenation(label("A"), label("B"), label("C")));
130+
131+
assertFlattened(
132+
concatenation(
133+
concatenation(
134+
label("A"),
135+
concatenation(
136+
concatenation(concatenation(label("B"), label("C")), label("D")), label("E"))),
137+
concatenation(label("F"), label("G"))),
138+
concatenation(
139+
label("A"), label("B"), label("C"), label("D"), label("E"), label("F"), label("G")));
140+
}
141+
142+
@Test
143+
public void testFlattenPermutation() {
144+
assertFlattened(
145+
permutation(label("A"), label("B"), label("C")),
146+
permutation(label("A"), label("B"), label("C")));
147+
148+
assertFlattened(
149+
permutation(label("A"), label("B"), empty()), permutation(label("A"), label("B")));
150+
151+
assertFlattened(
152+
permutation(empty(), label("A"), empty(), label("B"), empty(), label("C"), empty()),
153+
permutation(label("A"), label("B"), label("C")));
154+
155+
assertFlattened(permutation(empty(), label("A")), label("A"));
156+
assertFlattened(permutation(label("A"), empty()), label("A"));
157+
assertFlattened(permutation(empty(), empty(), empty()), empty());
158+
}
159+
160+
@Test
161+
public void testFlattenAndOptimize() {
162+
assertFlattenedOptimized(
163+
alternation(
164+
concatenation(empty(), alternation(label("A"), label("B"))),
165+
alternation(
166+
concatenation(concatenation(empty(), empty()), empty()),
167+
alternation(label("C"), empty()))),
168+
alternation(label("A"), questionMarkQuantified(label("B"), true), label("C")));
169+
}
170+
171+
@Test
172+
public void testRemoveNestedExclusions() {
173+
assertFlattened(excluded(excluded(excluded(excluded(label("A"))))), excluded(label("A")));
174+
}
175+
176+
@Test
177+
public void testEmptyPattern() {
178+
assertFlattened(empty(), empty());
179+
assertOptimized(empty(), empty());
180+
}
181+
182+
@Test
183+
public void testFlattenQuantifiedEmptyPattern() {
184+
assertFlattened(starQuantified(empty(), true), empty());
185+
assertFlattened(plusQuantified(empty(), true), empty());
186+
assertFlattened(
187+
questionMarkQuantified(starQuantified(plusQuantified(empty(), true), true), true), empty());
188+
189+
assertFlattened(rangeQuantified(empty(), 1, Optional.of(2), true), empty());
190+
assertFlattened(rangeQuantified(empty(), 0, Optional.empty(), false), empty());
191+
}
192+
193+
private void assertFlattened(IrRowPattern pattern, IrRowPattern expected) {
194+
IrRowPattern flattened = IrRowPatternFlattener.optimize(pattern);
195+
Assert.assertEquals(expected, flattened);
196+
}
197+
198+
private void assertOptimized(IrRowPattern pattern, IrRowPattern expected) {
199+
IrRowPattern optimized = IrPatternAlternationOptimizer.optimize(pattern);
200+
Assert.assertEquals(expected, optimized);
201+
}
202+
203+
private void assertFlattenedOptimized(IrRowPattern pattern, IrRowPattern expected) {
204+
IrRowPattern flattened = IrRowPatternFlattener.optimize(pattern);
205+
IrRowPattern optimized = IrPatternAlternationOptimizer.optimize(flattened);
206+
Assert.assertEquals(expected, optimized);
207+
}
208+
}

0 commit comments

Comments
 (0)