forked from heavyai/heavydb
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQueryPhysicalInputsCollector.cpp
More file actions
155 lines (136 loc) · 5.38 KB
/
QueryPhysicalInputsCollector.cpp
File metadata and controls
155 lines (136 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* Copyright 2017 MapD Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "QueryPhysicalInputsCollector.h"
#include "RelAlgAbstractInterpreter.h"
#include "RelAlgVisitor.h"
#include "RexVisitor.h"
namespace {
typedef std::unordered_set<PhysicalInput> PhysicalInputSet;
class RelAlgPhysicalInputsVisitor : public RelAlgVisitor<PhysicalInputSet> {
public:
PhysicalInputSet visitCompound(const RelCompound* compound) const override;
PhysicalInputSet visitFilter(const RelFilter* filter) const override;
PhysicalInputSet visitJoin(const RelJoin* join) const override;
PhysicalInputSet visitProject(const RelProject* project) const override;
protected:
PhysicalInputSet aggregateResult(const PhysicalInputSet& aggregate,
const PhysicalInputSet& next_result) const override;
};
class RexPhysicalInputsVisitor : public RexVisitor<PhysicalInputSet> {
public:
PhysicalInputSet visitInput(const RexInput* input) const override {
const auto source_ra = input->getSourceNode();
const auto scan_ra = dynamic_cast<const RelScan*>(source_ra);
if (!scan_ra) {
const auto join_ra = dynamic_cast<const RelJoin*>(source_ra);
if (join_ra) {
const auto node_inputs = get_node_output(join_ra);
CHECK_LT(input->getIndex(), node_inputs.size());
return visitInput(&node_inputs[input->getIndex()]);
}
return PhysicalInputSet{};
}
const auto scan_td = scan_ra->getTableDescriptor();
CHECK(scan_td);
const int col_id = input->getIndex() + 1;
const int table_id = scan_td->tableId;
CHECK_GT(table_id, 0);
return {{col_id, table_id}};
}
PhysicalInputSet visitSubQuery(const RexSubQuery* subquery) const override {
const auto ra = subquery->getRelAlg();
CHECK(ra);
RelAlgPhysicalInputsVisitor visitor;
return visitor.visit(ra);
}
protected:
PhysicalInputSet aggregateResult(const PhysicalInputSet& aggregate,
const PhysicalInputSet& next_result) const override {
auto result = aggregate;
result.insert(next_result.begin(), next_result.end());
return result;
}
};
PhysicalInputSet RelAlgPhysicalInputsVisitor::visitCompound(const RelCompound* compound) const {
PhysicalInputSet result;
for (size_t i = 0; i < compound->getScalarSourcesSize(); ++i) {
const auto rex = compound->getScalarSource(i);
CHECK(rex);
RexPhysicalInputsVisitor visitor;
const auto rex_phys_inputs = visitor.visit(rex);
result.insert(rex_phys_inputs.begin(), rex_phys_inputs.end());
}
const auto filter = compound->getFilterExpr();
if (filter) {
RexPhysicalInputsVisitor visitor;
const auto filter_phys_inputs = visitor.visit(filter);
result.insert(filter_phys_inputs.begin(), filter_phys_inputs.end());
}
return result;
}
PhysicalInputSet RelAlgPhysicalInputsVisitor::visitFilter(const RelFilter* filter) const {
const auto condition = filter->getCondition();
CHECK(condition);
RexPhysicalInputsVisitor visitor;
return visitor.visit(condition);
}
PhysicalInputSet RelAlgPhysicalInputsVisitor::visitJoin(const RelJoin* join) const {
const auto condition = join->getCondition();
if (!condition) {
return PhysicalInputSet{};
}
RexPhysicalInputsVisitor visitor;
return visitor.visit(condition);
}
PhysicalInputSet RelAlgPhysicalInputsVisitor::visitProject(const RelProject* project) const {
PhysicalInputSet result;
for (size_t i = 0; i < project->size(); ++i) {
const auto rex = project->getProjectAt(i);
CHECK(rex);
RexPhysicalInputsVisitor visitor;
const auto rex_phys_inputs = visitor.visit(rex);
result.insert(rex_phys_inputs.begin(), rex_phys_inputs.end());
}
return result;
}
PhysicalInputSet RelAlgPhysicalInputsVisitor::aggregateResult(const PhysicalInputSet& aggregate,
const PhysicalInputSet& next_result) const {
auto result = aggregate;
result.insert(next_result.begin(), next_result.end());
return result;
}
class RelAlgPhysicalTableInputsVisitor : public RelAlgVisitor<std::unordered_set<int>> {
public:
std::unordered_set<int> visitScan(const RelScan* scan) const override {
return {scan->getTableDescriptor()->tableId};
}
protected:
std::unordered_set<int> aggregateResult(const std::unordered_set<int>& aggregate,
const std::unordered_set<int>& next_result) const override {
auto result = aggregate;
result.insert(next_result.begin(), next_result.end());
return result;
}
};
} // namespace
std::unordered_set<PhysicalInput> get_physical_inputs(const RelAlgNode* ra) {
RelAlgPhysicalInputsVisitor phys_inputs_visitor;
return phys_inputs_visitor.visit(ra);
}
std::unordered_set<int> get_physical_table_inputs(const RelAlgNode* ra) {
RelAlgPhysicalTableInputsVisitor phys_table_inputs_visitor;
return phys_table_inputs_visitor.visit(ra);
}