Skip to content

Commit bd813d8

Browse files
authored
implement intersect and except related optimization rule: MergeIntersect, MergeExcept, RemoveEmptyIntersectBranchs, EvaluateEmptyIntersect, PruneIntersectSourceColumns, PruneExceptSourceColmns (#16761)
1 parent 85281fa commit bd813d8

File tree

12 files changed

+950
-20
lines changed

12 files changed

+950
-20
lines changed
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.Assignments;
23+
import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Lookup;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
26+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.IntersectNode;
27+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
28+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
29+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
30+
31+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns.intersect;
32+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.QueryCardinalityUtil.isEmpty;
33+
34+
public class EvaluateEmptyIntersect implements Rule<IntersectNode> {
35+
36+
private static final Pattern<IntersectNode> PATTERN = intersect();
37+
38+
@Override
39+
public Pattern<IntersectNode> getPattern() {
40+
return PATTERN;
41+
}
42+
43+
/** if any child of the intersect node is empty set, then the result set is empty */
44+
@Override
45+
public Result apply(IntersectNode node, Captures captures, Context context) {
46+
47+
Lookup lookup = context.getLookup();
48+
for (int i = 0; i < node.getChildren().size(); i++) {
49+
if (isEmpty(node.getChildren().get(i), lookup)) {
50+
51+
// replace the intersect node with project node, append the empty node to the project node
52+
Assignments.Builder assignments = Assignments.builder();
53+
for (Symbol symbol : node.getOutputSymbols()) {
54+
assignments.put(symbol, node.getSymbolMapping().get(symbol).get(i).toSymbolReference());
55+
}
56+
return Result.ofPlanNode(
57+
new ProjectNode(node.getPlanNodeId(), node.getChildren().get(i), assignments.build()));
58+
}
59+
}
60+
61+
return Result.empty();
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.ExceptNode;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SetOperationNode;
26+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
27+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
28+
29+
import java.util.Optional;
30+
31+
public class MergeExcept implements Rule<ExceptNode> {
32+
33+
private final Pattern<ExceptNode> pattern = Patterns.except();
34+
35+
@Override
36+
public Pattern<ExceptNode> getPattern() {
37+
return pattern;
38+
}
39+
40+
@Override
41+
public Result apply(ExceptNode node, Captures captures, Context context) {
42+
43+
SetOperationMerge mergeOperation = new SetOperationMerge(node, context);
44+
Optional<SetOperationNode> result = mergeOperation.mergeFirstSource();
45+
return result.map(Result::ofPlanNode).orElseGet(Result::empty);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.IntersectNode;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SetOperationNode;
26+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
27+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
28+
29+
import java.util.Optional;
30+
31+
public class MergeIntersect implements Rule<IntersectNode> {
32+
33+
private final Pattern<IntersectNode> pattern = Patterns.intersect();
34+
35+
@Override
36+
public Pattern<IntersectNode> getPattern() {
37+
return pattern;
38+
}
39+
40+
@Override
41+
public Result apply(IntersectNode node, Captures captures, Context context) {
42+
43+
SetOperationMerge mergeOperation = new SetOperationMerge(node, context);
44+
Optional<SetOperationNode> result = mergeOperation.merge();
45+
return result.map(Result::ofPlanNode).orElseGet(Result::empty);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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.Symbol;
23+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.ExceptNode;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns;
26+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
27+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
28+
29+
import com.google.common.collect.ImmutableSet;
30+
31+
import java.util.Set;
32+
33+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.Util.restrictChildOutputs;
34+
35+
public class PruneExceptSourceColumns implements Rule<ExceptNode> {
36+
37+
@Override
38+
public Pattern<ExceptNode> getPattern() {
39+
return Patterns.except();
40+
}
41+
42+
@Override
43+
public Result apply(ExceptNode node, Captures captures, Context context) {
44+
45+
@SuppressWarnings("unchecked")
46+
Set<Symbol>[] referencedInputs = new Set[node.getChildren().size()];
47+
for (int i = 0; i < node.getChildren().size(); i++) {
48+
referencedInputs[i] = ImmutableSet.copyOf(node.sourceOutputLayout(i));
49+
}
50+
return restrictChildOutputs(context.getIdAllocator(), node, referencedInputs)
51+
.map(Rule.Result::ofPlanNode)
52+
.orElse(Rule.Result.empty());
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.Symbol;
23+
import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
24+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.IntersectNode;
25+
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns;
26+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
27+
import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
28+
29+
import com.google.common.collect.ImmutableSet;
30+
31+
import java.util.Set;
32+
33+
import static org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.Util.restrictChildOutputs;
34+
35+
public class PruneIntersectSourceColumns implements Rule<IntersectNode> {
36+
37+
@Override
38+
public Pattern<IntersectNode> getPattern() {
39+
return Patterns.intersect();
40+
}
41+
42+
@Override
43+
public Result apply(IntersectNode node, Captures captures, Context context) {
44+
45+
@SuppressWarnings("unchecked")
46+
Set<Symbol>[] referencedInputs = new Set[node.getChildren().size()];
47+
for (int i = 0; i < node.getChildren().size(); i++) {
48+
referencedInputs[i] = ImmutableSet.copyOf(node.sourceOutputLayout(i));
49+
}
50+
51+
return restrictChildOutputs(context.getIdAllocator(), node, referencedInputs)
52+
.map(Rule.Result::ofPlanNode)
53+
.orElse(Rule.Result.empty());
54+
}
55+
}

0 commit comments

Comments
 (0)