Skip to content

Commit 974a7b2

Browse files
committed
Harden join projection map checks
1 parent 3a57abd commit 974a7b2

2 files changed

Lines changed: 50 additions & 6 deletions

File tree

src/delta/operators/delim_join.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,14 @@ static void AppendMultiplicityBindingsToJoinProjectionMaps(LogicalOperator &op,
110110
continue;
111111
}
112112
auto child_bindings = op.children[child_idx]->GetColumnBindings();
113-
proj_map.erase(
114-
std::remove_if(proj_map.begin(), proj_map.end(),
115-
[&](idx_t projected_idx) { return projected_idx >= child_bindings.size(); }),
116-
proj_map.end());
113+
for (auto projected_idx : proj_map) {
114+
if (projected_idx >= child_bindings.size()) {
115+
throw InternalException(
116+
"DeltaDelimJoin: projection map index %llu out of bounds for child %llu with %llu bindings",
117+
(unsigned long long)projected_idx, (unsigned long long)child_idx,
118+
(unsigned long long)child_bindings.size());
119+
}
120+
}
117121
for (idx_t binding_idx = 0; binding_idx < child_bindings.size(); binding_idx++) {
118122
if (!mul_set.count(BindingKey(child_bindings[binding_idx]))) {
119123
continue;
@@ -132,7 +136,8 @@ static void AppendMultiplicityBindingsToJoinProjectionMaps(LogicalOperator &op,
132136
}
133137
}
134138

135-
static void UpdateProjectionMapForLeaf(unique_ptr<LogicalOperator> &term, const BaseLeafInfo &leaf) {
139+
static void UpdateProjectionMapForLeaf(unique_ptr<LogicalOperator> &term, const BaseLeafInfo &leaf,
140+
const ColumnBinding &mul_binding) {
136141
if (leaf.path.empty()) {
137142
return;
138143
}
@@ -153,7 +158,33 @@ static void UpdateProjectionMapForLeaf(unique_ptr<LogicalOperator> &term, const
153158
return;
154159
}
155160
auto child_bindings = (*parent)->children[child_side]->GetColumnBindings();
161+
for (auto projected_idx : proj_map) {
162+
if (projected_idx >= child_bindings.size()) {
163+
throw InternalException(
164+
"DeltaDelimJoin: projection map index %llu out of bounds for child %llu with %llu bindings",
165+
(unsigned long long)projected_idx, (unsigned long long)child_side,
166+
(unsigned long long)child_bindings.size());
167+
}
168+
}
169+
// Wrapped DELIM_JOIN children can project an aggregate of the delta
170+
// multiplicity under a new binding. In that shape the extra column keeps the
171+
// original leaf-width ordinal, while simple children expose the raw delta
172+
// multiplicity binding directly.
156173
idx_t mul_idx = leaf.node->GetColumnBindings().size();
174+
if (mul_idx >= child_bindings.size()) {
175+
mul_idx = DConstants::INVALID_INDEX;
176+
for (idx_t binding_idx = 0; binding_idx < child_bindings.size(); binding_idx++) {
177+
if (child_bindings[binding_idx] == mul_binding) {
178+
mul_idx = binding_idx;
179+
break;
180+
}
181+
}
182+
}
183+
if (mul_idx == DConstants::INVALID_INDEX || mul_idx >= child_bindings.size()) {
184+
throw InternalException(
185+
"DeltaDelimJoin: multiplicity binding not available in projected child %llu with %llu bindings",
186+
(unsigned long long)child_side, (unsigned long long)child_bindings.size());
187+
}
157188
if (mul_idx < child_bindings.size() && std::find(proj_map.begin(), proj_map.end(), mul_idx) == proj_map.end()) {
158189
proj_map.push_back(mul_idx);
159190
}
@@ -542,7 +573,7 @@ DeltaPlanFragment CompileDelimJoinDelta(DeltaOperatorInput input) {
542573
AddLeafBindingReplacements(leaf_bindings, delta_bindings, output_replacements, delta_i.mul_binding);
543574
mul_bindings.push_back(delta_i.mul_binding);
544575
leaf_ref = std::move(delta_i.node);
545-
UpdateProjectionMapForLeaf(term, leaves[i]);
576+
UpdateProjectionMapForLeaf(term, leaves[i], delta_i.mul_binding);
546577
}
547578

548579
vector<ReplacementBinding> delim_replacements;

src/delta/operators/join.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,14 @@ void UpdateParentProjectionMap(unique_ptr<LogicalOperator> &term, const JoinLeaf
409409
auto &proj_map = (child_side == 0) ? join->left_projection_map : join->right_projection_map;
410410
if (!proj_map.empty()) {
411411
auto child_bindings = (*parent)->children[child_side]->GetColumnBindings();
412+
for (auto projected_idx : proj_map) {
413+
if (projected_idx >= child_bindings.size()) {
414+
throw InternalException(
415+
"DeltaJoin: projection map index %llu out of bounds for child %llu with %llu bindings",
416+
(unsigned long long)projected_idx, (unsigned long long)child_side,
417+
(unsigned long long)child_bindings.size());
418+
}
419+
}
412420
idx_t mul_idx = DConstants::INVALID_INDEX;
413421
for (idx_t binding_idx = 0; binding_idx < child_bindings.size(); binding_idx++) {
414422
if (DeltaJoinBindingKey(child_bindings[binding_idx]) == DeltaJoinBindingKey(mul_binding)) {
@@ -419,6 +427,11 @@ void UpdateParentProjectionMap(unique_ptr<LogicalOperator> &term, const JoinLeaf
419427
if (mul_idx == DConstants::INVALID_INDEX) {
420428
mul_idx = leaf.node->GetColumnBindings().size();
421429
}
430+
if (mul_idx >= child_bindings.size()) {
431+
throw InternalException("DeltaJoin: multiplicity binding not available in projected child %llu "
432+
"with %llu bindings",
433+
(unsigned long long)child_side, (unsigned long long)child_bindings.size());
434+
}
422435
if (mul_idx < child_bindings.size() &&
423436
std::find(proj_map.begin(), proj_map.end(), mul_idx) == proj_map.end()) {
424437
proj_map.push_back(mul_idx);

0 commit comments

Comments
 (0)