@@ -143,14 +143,16 @@ namespace
143
143
if (rse->rse_boolean && rse->rse_jointype == blr_inner &&
144
144
!rse->rse_first && !rse->rse_skip && !rse->rse_plan )
145
145
{
146
- StreamList streams ;
147
- rse->computeRseStreams (streams );
146
+ StreamList rseStreams ;
147
+ rse->computeRseStreams (rseStreams );
148
148
149
149
BoolExprNodeStack booleans;
150
- if (findDependentBooleans (csb, streams ,
150
+ if (findDependentBooleans (csb, rseStreams ,
151
151
rse->rse_boolean .getAddress (),
152
152
booleans))
153
153
{
154
+ // Compose the conjunct boolean
155
+
154
156
fb_assert (booleans.hasData ());
155
157
auto boolean = booleans.pop ();
156
158
while (booleans.hasData ())
@@ -162,11 +164,44 @@ namespace
162
164
boolean = andNode;
163
165
}
164
166
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;
170
205
}
171
206
}
172
207
}
0 commit comments