Skip to content

Commit aae2ae3

Browse files
committed
Better (methinks) fix for #8252: Incorrect subquery unnesting with complex dependencies, it re-allows converting nested IN/EXISTS into multiple semi-joins
1 parent fe6ba50 commit aae2ae3

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

src/jrd/RecordSourceNodes.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static ValueExprNode* resolveUsingField(DsqlCompilerScratch* dsqlScratch, const
5555
namespace
5656
{
5757
// Search through the list of ANDed booleans to find comparisons
58-
// referring streams of other select expressions.
58+
// referring streams of the parent select expression.
5959
// Extract those booleans and return them to the caller.
6060

6161
bool findDependentBooleans(CompilerScratch* csb,
@@ -92,7 +92,7 @@ namespace
9292

9393
for (const auto stream : streams)
9494
{
95-
if (!rseStreams.exist(stream))
95+
if (rseStreams.exist(stream))
9696
{
9797
booleanStack.push(boolean);
9898
*parentBoolean = nullptr;
@@ -109,6 +109,7 @@ namespace
109109
// They are candidates to be converted into semi- or anti-joins.
110110

111111
bool findPossibleJoins(CompilerScratch* csb,
112+
const StreamList& rseStreams,
112113
BoolExprNode** parentBoolean,
113114
RecordSourceNodeStack& rseStack,
114115
BoolExprNodeStack& booleanStack)
@@ -118,10 +119,10 @@ namespace
118119
const auto binaryNode = nodeAs<BinaryBoolNode>(boolNode);
119120
if (binaryNode && binaryNode->blrOp == blr_and)
120121
{
121-
const bool found1 = findPossibleJoins(csb, binaryNode->arg1.getAddress(),
122-
rseStack, booleanStack);
123-
const bool found2 = findPossibleJoins(csb, binaryNode->arg2.getAddress(),
124-
rseStack, booleanStack);
122+
const bool found1 = findPossibleJoins(csb, rseStreams,
123+
binaryNode->arg1.getAddress(), rseStack, booleanStack);
124+
const bool found2 = findPossibleJoins(csb, rseStreams,
125+
binaryNode->arg2.getAddress(), rseStack, booleanStack);
125126

126127
if (!binaryNode->arg1 && !binaryNode->arg2)
127128
*parentBoolean = nullptr;
@@ -143,8 +144,7 @@ namespace
143144
if (rse->rse_boolean && rse->rse_jointype == blr_inner &&
144145
!rse->rse_first && !rse->rse_skip && !rse->rse_plan)
145146
{
146-
StreamList rseStreams;
147-
rse->computeRseStreams(rseStreams);
147+
// Find booleans convertable into semi-joins
148148

149149
BoolExprNodeStack booleans;
150150
if (findDependentBooleans(csb, rseStreams,
@@ -173,7 +173,7 @@ namespace
173173
bool dependent = false;
174174
for (const auto stream : streams)
175175
{
176-
if (!rseStreams.exist(stream))
176+
if (rseStreams.exist(stream))
177177
{
178178
dependent = true;
179179
break;
@@ -3264,7 +3264,10 @@ RseNode* RseNode::processPossibleJoins(thread_db* tdbb, CompilerScratch* csb)
32643264

32653265
// Find possibly joinable sub-queries
32663266

3267-
if (!findPossibleJoins(csb, rse_boolean.getAddress(), rseStack, booleanStack))
3267+
StreamList rseStreams;
3268+
computeRseStreams(rseStreams);
3269+
3270+
if (!findPossibleJoins(csb, rseStreams, rse_boolean.getAddress(), rseStack, booleanStack))
32683271
return nullptr;
32693272

32703273
fb_assert(rseStack.hasData() && booleanStack.hasData());

0 commit comments

Comments
 (0)