8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 10:43:03 +01:00

Bigfix CORE-5236: IN/ANY/ALL predicates may cause sub-optimal (late filtering) execution of joins

This commit is contained in:
Dmitry Yemanov 2016-07-08 21:49:10 +03:00
parent 85ed405814
commit 1cdded614e
3 changed files with 6 additions and 14 deletions

View File

@ -91,15 +91,6 @@ namespace
//-------------------- //--------------------
bool BoolExprNode::computable(CompilerScratch* csb, StreamType stream,
bool allowOnlyCurrentStream, ValueExprNode* /*value*/)
{
if (nodFlags & (FLAG_DEOPTIMIZE | FLAG_RESIDUAL))
return false;
return ExprNode::computable(csb, stream, allowOnlyCurrentStream);
}
BoolExprNode* BoolExprNode::pass2(thread_db* tdbb, CompilerScratch* csb) BoolExprNode* BoolExprNode::pass2(thread_db* tdbb, CompilerScratch* csb)
{ {
pass2Boolean1(tdbb, csb); pass2Boolean1(tdbb, csb);

View File

@ -743,9 +743,6 @@ public:
return this; return this;
} }
virtual bool computable(CompilerScratch* csb, StreamType stream,
bool allowOnlyCurrentStream, ValueExprNode* value = NULL);
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb) virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb)
{ {
ExprNode::pass1(tdbb, csb); ExprNode::pass1(tdbb, csb);

View File

@ -212,6 +212,7 @@ namespace
BoolExprNode* const node = tail->opt_conjunct_node; BoolExprNode* const node = tail->opt_conjunct_node;
if (!(tail->opt_conjunct_flags & opt_conjunct_used) && if (!(tail->opt_conjunct_flags & opt_conjunct_used) &&
!(node->nodFlags & ExprNode::FLAG_RESIDUAL) &&
node->computable(csb, INVALID_STREAM, false)) node->computable(csb, INVALID_STREAM, false))
{ {
compose(csb->csb_pool, &boolean, node); compose(csb->csb_pool, &boolean, node);
@ -279,8 +280,9 @@ namespace
if (rsbs.getCount() < riverCount) if (rsbs.getCount() < riverCount)
{ {
// Ideally, we should never get here. Now it's possible only if some booleans // Ideally, we should never get here. But just in case it happened, handle it.
// were faked to be non-computable (FLAG_DEOPTIMIZE and FLAG_RESIDUAL).
fb_assert(false);
for (River** iter = rivers.begin(); iter < rivers.end(); iter++) for (River** iter = rivers.begin(); iter < rivers.end(); iter++)
{ {
@ -2378,6 +2380,7 @@ static RecordSource* gen_retrieval(thread_db* tdbb,
BoolExprNode* const node = tail->opt_conjunct_node; BoolExprNode* const node = tail->opt_conjunct_node;
if (!(tail->opt_conjunct_flags & opt_conjunct_used) && if (!(tail->opt_conjunct_flags & opt_conjunct_used) &&
!(node->nodFlags & ExprNode::FLAG_RESIDUAL) &&
node->computable(csb, INVALID_STREAM, false)) node->computable(csb, INVALID_STREAM, false))
{ {
// If inversion is available, utilize all conjuncts that refer to // If inversion is available, utilize all conjuncts that refer to
@ -3029,6 +3032,7 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
BoolExprNode* const node = tail->opt_conjunct_node; BoolExprNode* const node = tail->opt_conjunct_node;
if (!(tail->opt_conjunct_flags & opt_conjunct_used) && if (!(tail->opt_conjunct_flags & opt_conjunct_used) &&
!(node->nodFlags & ExprNode::FLAG_RESIDUAL) &&
node->computable(csb, INVALID_STREAM, false)) node->computable(csb, INVALID_STREAM, false))
{ {
compose(*tdbb->getDefaultPool(), &boolean, node); compose(*tdbb->getDefaultPool(), &boolean, node);