Skip to content

Commit 681310b

Browse files
authored
merge yard-export-subquery: subquery plans in the exported tree
bench: yard_export emits predicate-owned subquery plans
2 parents 478938c + b63d0f9 commit 681310b

3 files changed

Lines changed: 174 additions & 87 deletions

File tree

‎benchmarks/yard_export.cpp‎

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,49 @@ std::string node_detail(const std::string& line) {
153153
return line.substr(bracket + 1, line.size() - bracket - 2);
154154
}
155155

156+
struct OwnedSubquery {
157+
std::string detail;
158+
const plan::LogicalPlan* plan{nullptr};
159+
};
160+
161+
void collect_scalar_subquery(const plan::BoundScalarExpr& expression,
162+
std::vector<OwnedSubquery>& subqueries) {
163+
if (const auto* subquery = std::get_if<plan::BoundScalarSubquery>(&expression.value);
164+
subquery != nullptr && subquery->plan != nullptr) {
165+
subqueries.push_back({"Subquery[" + subquery->name + "]", subquery->plan.get()});
166+
}
167+
}
168+
169+
void collect_predicate_subqueries(const plan::BoundPredicate& predicate,
170+
std::vector<OwnedSubquery>& subqueries) {
171+
if (predicate.kind == sql::PredicateKind::Comparison) {
172+
collect_scalar_subquery(predicate.comparison.left, subqueries);
173+
collect_scalar_subquery(predicate.comparison.right, subqueries);
174+
}
175+
if (predicate.subquery != nullptr) {
176+
subqueries.push_back({"Subquery[" + predicate.subquery_name + "]", predicate.subquery.get()});
177+
}
178+
if (predicate.left != nullptr) collect_predicate_subqueries(*predicate.left, subqueries);
179+
if (predicate.right != nullptr) collect_predicate_subqueries(*predicate.right, subqueries);
180+
}
181+
182+
std::string tree_json(const plan::LogicalPlan& node, const execution::Catalog& catalog, int indent);
183+
184+
std::string subquery_tree_json(const OwnedSubquery& subquery,
185+
const execution::Catalog& catalog,
186+
int indent) {
187+
const auto estimate = optimizer::estimate_cost(*subquery.plan, catalog);
188+
const std::string pad(static_cast<std::size_t>(indent), ' ');
189+
std::string out = "{\n" + pad + " \"op\": \"Subquery\"," +
190+
"\n" + pad + " \"detail\": " + quoted(subquery.detail) +
191+
",\n" + pad + " \"rows\": " + fixed(estimate.rows, 2) +
192+
",\n" + pad + " \"cost\": " + fixed(estimate.cost, 2) +
193+
",\n" + pad + " \"children\": [\n" + pad + " " +
194+
tree_json(*subquery.plan, catalog, indent + 4) +
195+
"\n" + pad + " ]\n" + pad + "}";
196+
return out;
197+
}
198+
156199
std::string tree_json(const plan::LogicalPlan& node, const execution::Catalog& catalog, int indent) {
157200
const auto estimate = optimizer::estimate_cost(node, catalog);
158201
const auto line = node_line(node);
@@ -166,10 +209,23 @@ std::string tree_json(const plan::LogicalPlan& node, const execution::Catalog& c
166209
if (node.input) children.push_back(node.input.get());
167210
if (node.left) children.push_back(node.left.get());
168211
if (node.right) children.push_back(node.right.get());
169-
for (std::size_t i = 0; i < children.size(); ++i) {
170-
out += (i == 0 ? "\n" : ",\n") + pad + " " + tree_json(*children[i], catalog, indent + 4);
212+
std::vector<OwnedSubquery> subqueries;
213+
for (const auto& predicate : node.predicates) {
214+
collect_predicate_subqueries(predicate, subqueries);
215+
}
216+
if (node.null_aware_predicate.has_value()) {
217+
collect_predicate_subqueries(*node.null_aware_predicate, subqueries);
218+
}
219+
std::size_t child_index = 0;
220+
for (const auto* child : children) {
221+
out += (child_index++ == 0 ? "\n" : ",\n") + pad + " " +
222+
tree_json(*child, catalog, indent + 4);
223+
}
224+
for (const auto& subquery : subqueries) {
225+
out += (child_index++ == 0 ? "\n" : ",\n") + pad + " " +
226+
subquery_tree_json(subquery, catalog, indent + 4);
171227
}
172-
out += children.empty() ? "]" : "\n" + pad + " ]";
228+
out += child_index == 0 ? "]" : "\n" + pad + " ]";
173229
out += "\n" + pad + "}";
174230
return out;
175231
}

0 commit comments

Comments
 (0)