Skip to content

Commit 5fa4ae6

Browse files
committed
Fix bug #8252: Incorrect subquery unnesting with complex dependencies
1 parent 00c0049 commit 5fa4ae6

File tree

1 file changed

+43
-8
lines changed

1 file changed

+43
-8
lines changed

src/jrd/RecordSourceNodes.cpp

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,16 @@ namespace
143143
if (rse->rse_boolean && rse->rse_jointype == blr_inner &&
144144
!rse->rse_first && !rse->rse_skip && !rse->rse_plan)
145145
{
146-
StreamList streams;
147-
rse->computeRseStreams(streams);
146+
StreamList rseStreams;
147+
rse->computeRseStreams(rseStreams);
148148

149149
BoolExprNodeStack booleans;
150-
if (findDependentBooleans(csb, streams,
150+
if (findDependentBooleans(csb, rseStreams,
151151
rse->rse_boolean.getAddress(),
152152
booleans))
153153
{
154+
// Compose the conjunct boolean
155+
154156
fb_assert(booleans.hasData());
155157
auto boolean = booleans.pop();
156158
while (booleans.hasData())
@@ -162,11 +164,44 @@ namespace
162164
boolean = andNode;
163165
}
164166

165-
rse->flags |= RseNode::FLAG_SEMI_JOINED;
166-
rseStack.push(rse);
167-
booleanStack.push(boolean);
168-
*parentBoolean = nullptr;
169-
return true;
167+
// Ensure that no external references are left inside the subquery.
168+
// If so, mark the RSE as joined and add it to the stack.
169+
170+
SortedStreamList streams;
171+
rse->collectStreams(streams);
172+
173+
bool dependent = false;
174+
for (const auto stream : streams)
175+
{
176+
if (!rseStreams.exist(stream))
177+
{
178+
dependent = true;
179+
break;
180+
}
181+
}
182+
183+
if (!dependent)
184+
{
185+
rse->flags |= RseNode::FLAG_SEMI_JOINED;
186+
rseStack.push(rse);
187+
booleanStack.push(boolean);
188+
*parentBoolean = nullptr;
189+
return true;
190+
}
191+
192+
// Otherwise, restore the original sub-query by adding
193+
// the collected booleans back to the RSE.
194+
195+
if (rse->rse_boolean)
196+
{
197+
const auto andNode = FB_NEW_POOL(csb->csb_pool)
198+
BinaryBoolNode(csb->csb_pool, blr_and);
199+
andNode->arg1 = boolean;
200+
andNode->arg2 = rse->rse_boolean;
201+
boolean = andNode;
202+
}
203+
204+
rse->rse_boolean = boolean;
170205
}
171206
}
172207
}

0 commit comments

Comments
 (0)