MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / findPossibleJoins

Function findPossibleJoins

src/jrd/RecordSourceNodes.cpp:142–241  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

140 // They are candidates to be converted into semi- or anti-joins.
141
142 bool findPossibleJoins(CompilerScratch* csb,
143 const StreamList& rseStreams,
144 BoolExprNode** parentBoolean,
145 RecordSourceNodeStack& rseStack,
146 BoolExprNodeStack& booleanStack)
147 {
148 auto boolNode = *parentBoolean;
149
150 const auto binaryNode = nodeAs<BinaryBoolNode>(boolNode);
151 if (binaryNode && binaryNode->blrOp == blr_and)
152 {
153 const bool found1 = findPossibleJoins(csb, rseStreams,
154 binaryNode->arg1.getAddress(), rseStack, booleanStack);
155 const bool found2 = findPossibleJoins(csb, rseStreams,
156 binaryNode->arg2.getAddress(), rseStack, booleanStack);
157
158 if (!binaryNode->arg1 && !binaryNode->arg2)
159 *parentBoolean = nullptr;
160 else if (!binaryNode->arg1)
161 *parentBoolean = binaryNode->arg2;
162 else if (!binaryNode->arg2)
163 *parentBoolean = binaryNode->arg1;
164
165 return (found1 || found2);
166 }
167
168 const auto rseNode = nodeAs<RseBoolNode>(boolNode);
169 // Both EXISTS (blr_any) and IN (blr_ansi_any) sub-queries are handled
170 if (rseNode && (rseNode->blrOp == blr_any || rseNode->blrOp == blr_ansi_any))
171 {
172 auto rse = rseNode->rse;
173 fb_assert(rse && (rse->flags & RseNode::FLAG_SUB_QUERY));
174
175 if (rse->rse_boolean && rse->isInnerJoin() &&
176 !rse->rse_first && !rse->rse_skip && !rse->rse_plan)
177 {
178 // Find booleans convertable into semi-joins
179
180 BoolExprNodeStack booleans;
181 if (findDependentBooleans(csb, rseStreams,
182 rse->rse_boolean.getAddress(),
183 booleans))
184 {
185 // Compose the conjunct boolean
186
187 fb_assert(booleans.hasData());
188 auto boolean = booleans.pop();
189 while (booleans.hasData())
190 {
191 const auto andNode = FB_NEW_POOL(csb->csb_pool)
192 BinaryBoolNode(csb->csb_pool, blr_and);
193 andNode->arg1 = boolean;
194 andNode->arg2 = booleans.pop();
195 boolean = andNode;
196 }
197
198 // Ensure that no external references are left inside the subquery.
199 // If so, mark the RSE as joined and add it to the stack.

Callers 1

processPossibleJoinsMethod · 0.85

Calls 9

findDependentBooleansFunction · 0.85
getAddressMethod · 0.80
BinaryBoolNodeClass · 0.50
isInnerJoinMethod · 0.45
hasDataMethod · 0.45
popMethod · 0.45
collectStreamsMethod · 0.45
existMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected