diff --git a/src/dsql/AggNodes.cpp b/src/dsql/AggNodes.cpp index eb947d0a29..6f25829eb7 100644 --- a/src/dsql/AggNodes.cpp +++ b/src/dsql/AggNodes.cpp @@ -245,7 +245,7 @@ bool AggNode::dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor) if (!visitor.insideHigherMap) { - NodeRefsHolder holder(visitor.getPool()); + NodeRefsHolder holder(visitor.dsqlScratch->getPool()); getChildren(holder, true); for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) @@ -254,7 +254,7 @@ bool AggNode::dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor) // an higher one then it's a invalid aggregate, because // aggregate-functions from the same context can't // be part of each other. - if (Aggregate2Finder::find(visitor.getPool(), visitor.context->ctx_scope_level, + if (Aggregate2Finder::find(visitor.dsqlScratch->getPool(), visitor.context->ctx_scope_level, FIELD_MATCH_TYPE_EQUAL, false, (*i)->getExpr())) { // Nested aggregate functions are not allowed @@ -296,9 +296,9 @@ ValueExprNode* AggNode::dsqlFieldRemapper(FieldRemapper& visitor) return this; } -bool AggNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool AggNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const AggNode* o = other->as(); diff --git a/src/dsql/BoolNodes.cpp b/src/dsql/BoolNodes.cpp index c6f5527a5e..1ce7e82ceb 100644 --- a/src/dsql/BoolNodes.cpp +++ b/src/dsql/BoolNodes.cpp @@ -137,9 +137,9 @@ void BinaryBoolNode::genBlr(DsqlCompilerScratch* dsqlScratch) GEN_expr(dsqlScratch, arg2); } -bool BinaryBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool BinaryBoolNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!BoolExprNode::dsqlMatch(other, ignoreMapCast)) + if (!BoolExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const BinaryBoolNode* o = other->as(); @@ -148,22 +148,22 @@ bool BinaryBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrOp == o->blrOp; } -bool BinaryBoolNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool BinaryBoolNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { const BinaryBoolNode* const otherNode = other->as(); if (!otherNode || blrOp != otherNode->blrOp) return false; - if (arg1->sameAs(otherNode->arg1, ignoreStreams) && - arg2->sameAs(otherNode->arg2, ignoreStreams)) + if (arg1->sameAs(csb, otherNode->arg1, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg2, ignoreStreams)) { return true; } // A AND B is equivalent to B AND A, ditto for A OR B and B OR A. - return arg1->sameAs(otherNode->arg2, ignoreStreams) && - arg2->sameAs(otherNode->arg1, ignoreStreams); + return arg1->sameAs(csb, otherNode->arg2, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg1, ignoreStreams); } BoolExprNode* BinaryBoolNode::copy(thread_db* tdbb, NodeCopier& copier) const @@ -485,9 +485,9 @@ void ComparativeBoolNode::genBlr(DsqlCompilerScratch* dsqlScratch) GEN_expr(dsqlScratch, arg3); } -bool ComparativeBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool ComparativeBoolNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!BoolExprNode::dsqlMatch(other, ignoreMapCast)) + if (!BoolExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const ComparativeBoolNode* o = other->as(); @@ -496,20 +496,20 @@ bool ComparativeBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) c return dsqlFlag == o->dsqlFlag && blrOp == o->blrOp; } -bool ComparativeBoolNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool ComparativeBoolNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { const ComparativeBoolNode* const otherNode = other->as(); if (!otherNode || blrOp != otherNode->blrOp) return false; - bool matching = arg1->sameAs(otherNode->arg1, ignoreStreams) && - arg2->sameAs(otherNode->arg2, ignoreStreams); + bool matching = arg1->sameAs(csb, otherNode->arg1, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg2, ignoreStreams); if (matching) { matching = (!arg3 == !otherNode->arg3) && - (!arg3 || arg3->sameAs(otherNode->arg3, ignoreStreams)); + (!arg3 || arg3->sameAs(csb, otherNode->arg3, ignoreStreams)); if (matching) return true; @@ -520,8 +520,8 @@ bool ComparativeBoolNode::sameAs(const ExprNode* other, bool ignoreStreams) cons if (blrOp == blr_eql || blrOp == blr_equiv || blrOp == blr_neq) { // A = B is equivalent to B = A, etc. - if (arg1->sameAs(otherNode->arg2, ignoreStreams) && - arg2->sameAs(otherNode->arg1, ignoreStreams)) + if (arg1->sameAs(csb, otherNode->arg2, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg1, ignoreStreams)) { return true; } @@ -1661,9 +1661,9 @@ void RseBoolNode::genBlr(DsqlCompilerScratch* dsqlScratch) GEN_rse(dsqlScratch, dsqlRse->as()); } -bool RseBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool RseBoolNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!BoolExprNode::dsqlMatch(other, ignoreMapCast)) + if (!BoolExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const RseBoolNode* o = other->as(); @@ -1672,9 +1672,9 @@ bool RseBoolNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrOp == o->blrOp; } -bool RseBoolNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool RseBoolNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!BoolExprNode::sameAs(other, ignoreStreams)) + if (!BoolExprNode::sameAs(csb, other, ignoreStreams)) return false; const RseBoolNode* const otherNode = other->as(); diff --git a/src/dsql/BoolNodes.h b/src/dsql/BoolNodes.h index 68da5f90c4..0bbd47c7c0 100644 --- a/src/dsql/BoolNodes.h +++ b/src/dsql/BoolNodes.h @@ -52,8 +52,8 @@ public: virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual bool execute(thread_db* tdbb, jrd_req* request) const; private: @@ -95,14 +95,14 @@ public: virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* opt) { - return blrOp == blr_equiv ? true : BoolExprNode::possiblyUnknown(); + return blrOp == blr_equiv ? true : BoolExprNode::possiblyUnknown(opt); } virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb); @@ -145,7 +145,7 @@ public: virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -178,7 +178,7 @@ public: virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -226,14 +226,14 @@ public: return true; } - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb); diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index e89f783e03..388d110c99 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -67,7 +67,7 @@ using namespace Jrd; namespace { - bool sameNodes(const ValueIfNode* node1, const CoalesceNode* node2, bool ignoreStreams) + bool sameNodes(CompilerScratch* csb, const ValueIfNode* node1, const CoalesceNode* node2, bool ignoreStreams) { // dimitr: COALESCE could be represented as ValueIfNode in older databases, // so compare them for actually being the same thing: @@ -76,10 +76,10 @@ namespace if (node1 && node2) { const MissingBoolNode* const missing = node1->condition->as(); - if (missing && missing->arg->sameAs(node1->falseValue, false) && + if (missing && missing->arg->sameAs(csb, node1->falseValue, false) && node2->args->items.getCount() == 2 && - node2->args->items[0]->sameAs(node1->falseValue, ignoreStreams) && - node2->args->items[1]->sameAs(node1->trueValue, ignoreStreams)) + node2->args->items[0]->sameAs(csb, node1->falseValue, ignoreStreams) && + node2->args->items[1]->sameAs(csb, node1->trueValue, ignoreStreams)) { return true; } @@ -269,17 +269,15 @@ string ExprNode::internalPrint(NodePrinter& printer) const } -bool ExprNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool ExprNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { if (other->type != type) return false; - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: - - NodeRefsHolder thisHolder(*tdbb->getDefaultPool()); + NodeRefsHolder thisHolder(dsqlScratch->getPool()); getChildren(thisHolder, true); - NodeRefsHolder otherHolder(*tdbb->getDefaultPool()); + NodeRefsHolder otherHolder(dsqlScratch->getPool()); other->getChildren(otherHolder, true); size_t count = thisHolder.refs.getCount(); @@ -290,24 +288,22 @@ bool ExprNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const for (const NodeRef* const* i = thisHolder.refs.begin(); i != thisHolder.refs.end(); ++i, ++j) { - if (!**i != !**j || !PASS1_node_match((*i)->getExpr(), (*j)->getExpr(), ignoreMapCast)) + if (!**i != !**j || !PASS1_node_match(dsqlScratch, (*i)->getExpr(), (*j)->getExpr(), ignoreMapCast)) return false; } return true; } -bool ExprNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool ExprNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { if (other->type != type) return false; - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: - - NodeRefsHolder thisHolder(*tdbb->getDefaultPool()); + NodeRefsHolder thisHolder(csb->csb_pool); getChildren(thisHolder, false); - NodeRefsHolder otherHolder(*tdbb->getDefaultPool()); + NodeRefsHolder otherHolder(csb->csb_pool); other->getChildren(otherHolder, false); size_t count = thisHolder.refs.getCount(); @@ -321,13 +317,53 @@ bool ExprNode::sameAs(const ExprNode* other, bool ignoreStreams) const if (!**i && !**j) continue; - if (!**i || !**j || !(*i)->getExpr()->sameAs((*j)->getExpr(), ignoreStreams)) + if (!**i || !**j || !(*i)->getExpr()->sameAs(csb, (*j)->getExpr(), ignoreStreams)) return false; } return true; } +bool ExprNode::possiblyUnknown(OptimizerBlk* opt) +{ + NodeRefsHolder holder(opt->getPool()); + getChildren(holder, false); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) + { + if (**i && (*i)->getExpr()->possiblyUnknown(opt)) + return true; + } + + return false; +} + +bool ExprNode::unmappable(CompilerScratch* csb, const MapNode* mapNode, StreamType shellStream) +{ + NodeRefsHolder holder(csb->csb_pool); + getChildren(holder, false); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) + { + if (**i && !(*i)->getExpr()->unmappable(csb, mapNode, shellStream)) + return false; + } + + return true; +} + +void ExprNode::collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const +{ + NodeRefsHolder holder(csb->csb_pool); + getChildren(holder, false); + + for (const NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) + { + if (**i) + (*i)->getExpr()->collectStreams(csb, streamList); + } +} + bool ExprNode::computable(CompilerScratch* csb, StreamType stream, bool allowOnlyCurrentStream, ValueExprNode* /*value*/) { @@ -1524,9 +1560,9 @@ ValueExprNode* ArithmeticNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool ArithmeticNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool ArithmeticNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const ArithmeticNode* o = other->as(); @@ -1535,15 +1571,15 @@ bool ArithmeticNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return dialect1 == o->dialect1 && blrOp == o->blrOp; } -bool ArithmeticNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool ArithmeticNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { const ArithmeticNode* const otherNode = other->as(); if (!otherNode || blrOp != otherNode->blrOp || dialect1 != otherNode->dialect1) return false; - if (arg1->sameAs(otherNode->arg1, ignoreStreams) && - arg2->sameAs(otherNode->arg2, ignoreStreams)) + if (arg1->sameAs(csb, otherNode->arg1, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg2, ignoreStreams)) { return true; } @@ -1553,8 +1589,8 @@ bool ArithmeticNode::sameAs(const ExprNode* other, bool ignoreStreams) const // A + B is equivalent to B + A, ditto for A * B and B * A. // Note: If one expression is A + B + C, but the other is B + C + A we won't // necessarily match them. - if (arg1->sameAs(otherNode->arg2, ignoreStreams) && - arg2->sameAs(otherNode->arg1, ignoreStreams)) + if (arg1->sameAs(csb, otherNode->arg2, ignoreStreams) && + arg2->sameAs(csb, otherNode->arg1, ignoreStreams)) { return true; } @@ -2793,9 +2829,9 @@ ValueExprNode* CastNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool CastNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool CastNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const CastNode* o = other->as(); @@ -2804,9 +2840,9 @@ bool CastNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return dsqlField == o->dsqlField; } -bool CastNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool CastNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const CastNode* const otherNode = other->as(); @@ -3010,12 +3046,12 @@ ValueExprNode* CoalesceNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool CoalesceNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool CoalesceNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (ExprNode::sameAs(other, ignoreStreams)) + if (ExprNode::sameAs(csb, other, ignoreStreams)) return true; - return sameNodes(other->as(), this, ignoreStreams); + return sameNodes(csb, other->as(), this, ignoreStreams); } ValueExprNode* CoalesceNode::pass2(thread_db* tdbb, CompilerScratch* csb) @@ -4190,9 +4226,9 @@ DmlNode* DerivedExprNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScrat return node; } -void DerivedExprNode::collectStreams(SortedStreamList& streamList) const +void DerivedExprNode::collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const { - arg->collectStreams(streamList); + arg->collectStreams(csb, streamList); for (const StreamType* i = internalStreamList.begin(); i != internalStreamList.end(); ++i) { @@ -4208,7 +4244,7 @@ bool DerivedExprNode::computable(CompilerScratch* csb, StreamType stream, return false; SortedStreamList argStreams; - arg->collectStreams(argStreams); + arg->collectStreams(csb, argStreams); for (StreamType* i = internalStreamList.begin(); i != internalStreamList.end(); ++i) { @@ -4572,9 +4608,9 @@ ValueExprNode* ExtractNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool ExtractNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool ExtractNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const ExtractNode* o = other->as(); @@ -4583,9 +4619,9 @@ bool ExtractNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrSubOp == o->blrSubOp; } -bool ExtractNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool ExtractNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const ExtractNode* const otherNode = other->as(); @@ -5524,9 +5560,9 @@ void FieldNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc) } } -bool FieldNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool FieldNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const FieldNode* o = other->as(); @@ -5536,14 +5572,14 @@ bool FieldNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return false; if (dsqlIndices || o->dsqlIndices) - return PASS1_node_match(dsqlIndices, o->dsqlIndices, ignoreMapCast); + return PASS1_node_match(dsqlScratch, dsqlIndices, o->dsqlIndices, ignoreMapCast); return true; } -bool FieldNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool FieldNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const FieldNode* const otherNode = other->as(); @@ -5818,7 +5854,7 @@ ValueExprNode* FieldNode::pass1(thread_db* tdbb, CompilerScratch* csb) // ASF: If the view field doesn't reference any of the view streams, // evaluate it based on the view dbkey - CORE-1245. SortedStreamList streams; - sub->collectStreams(streams); + sub->collectStreams(csb, streams); bool view_refs = false; for (FB_SIZE_T i = 0; i < streams.getCount(); i++) @@ -6097,9 +6133,9 @@ ValueExprNode* GenIdNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool GenIdNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool GenIdNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const GenIdNode* o = other->as(); @@ -6111,9 +6147,9 @@ bool GenIdNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const implicit == o->implicit; } -bool GenIdNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool GenIdNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const GenIdNode* const otherNode = other->as(); @@ -6797,9 +6833,9 @@ ValueExprNode* LiteralNode::copy(thread_db* tdbb, NodeCopier& /*copier*/) const return node; } -bool LiteralNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool LiteralNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const LiteralNode* o = other->as(); @@ -6813,9 +6849,9 @@ bool LiteralNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return memcmp(litDesc.dsc_address, o->litDesc.dsc_address, len) == 0; } -bool LiteralNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool LiteralNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const LiteralNode* const otherNode = other->as(); @@ -7056,10 +7092,10 @@ void DsqlMapNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc) desc->setNullable(true); } -bool DsqlMapNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool DsqlMapNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { const DsqlMapNode* o = other->as(); - return o && PASS1_node_match(map->map_node, o->map->map_node, ignoreMapCast); + return o && PASS1_node_match(dsqlScratch, map->map_node, o->map->map_node, ignoreMapCast); } @@ -7594,9 +7630,9 @@ OrderNode* OrderNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) return node; } -bool OrderNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool OrderNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const OrderNode* o = other->as(); @@ -8070,7 +8106,7 @@ void ParameterNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc) *desc = dsqlParameter->par_desc; } -bool ParameterNode::dsqlMatch(const ExprNode* other, bool /*ignoreMapCast*/) const +bool ParameterNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool /*ignoreMapCast*/) const { const ParameterNode* o = other->as(); @@ -8511,9 +8547,9 @@ ValueExprNode* RecordKeyNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool RecordKeyNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool RecordKeyNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const RecordKeyNode* o = other->as(); @@ -8522,9 +8558,9 @@ bool RecordKeyNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrOp == o->blrOp; } -bool RecordKeyNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool RecordKeyNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const RecordKeyNode* const otherNode = other->as(); @@ -9039,9 +9075,9 @@ ValueExprNode* StrCaseNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool StrCaseNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool StrCaseNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const StrCaseNode* o = other->as(); @@ -9050,9 +9086,9 @@ bool StrCaseNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrOp == o->blrOp; } -bool StrCaseNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool StrCaseNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const StrCaseNode* const otherNode = other->as(); @@ -9252,9 +9288,9 @@ ValueExprNode* StrLenNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool StrLenNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool StrLenNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const StrLenNode* o = other->as(); @@ -9263,9 +9299,9 @@ bool StrLenNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return blrSubOp == o->blrSubOp; } -bool StrLenNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool StrLenNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const StrLenNode* const otherNode = other->as(); @@ -9531,13 +9567,13 @@ ValueExprNode* SubQueryNode::dsqlFieldRemapper(FieldRemapper& visitor) return this; } -void SubQueryNode::collectStreams(SortedStreamList& streamList) const +void SubQueryNode::collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const { if (rse) - rse->collectStreams(streamList); + rse->collectStreams(csb, streamList); if (value1) - value1->collectStreams(streamList); + value1->collectStreams(csb, streamList); } bool SubQueryNode::computable(CompilerScratch* csb, StreamType stream, @@ -9653,7 +9689,7 @@ ValueExprNode* SubQueryNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool SubQueryNode::sameAs(const ExprNode* /*other*/, bool /*ignoreStreams*/) const +bool SubQueryNode::sameAs(CompilerScratch* /*csb*/, const ExprNode* /*other*/, bool /*ignoreStreams*/) const { return false; } @@ -10581,9 +10617,9 @@ ValueExprNode* SysFuncCallNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool SysFuncCallNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool SysFuncCallNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const SysFuncCallNode* otherNode = other->as(); @@ -10591,9 +10627,9 @@ bool SysFuncCallNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return name == otherNode->name; } -bool SysFuncCallNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool SysFuncCallNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const SysFuncCallNode* const otherNode = other->as(); @@ -10810,9 +10846,9 @@ ValueExprNode* TrimNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool TrimNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool TrimNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const TrimNode* o = other->as(); @@ -10821,9 +10857,9 @@ bool TrimNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return where == o->where; } -bool TrimNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool TrimNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const TrimNode* const otherNode = other->as(); @@ -11181,9 +11217,9 @@ ValueExprNode* UdfCallNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool UdfCallNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool UdfCallNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const UdfCallNode* otherNode = other->as(); @@ -11191,9 +11227,9 @@ bool UdfCallNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const return name == otherNode->name; } -bool UdfCallNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool UdfCallNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const UdfCallNode* const otherNode = other->as(); @@ -11762,12 +11798,12 @@ ValueExprNode* ValueIfNode::copy(thread_db* tdbb, NodeCopier& copier) const return node; } -bool ValueIfNode::sameAs(const ExprNode* other, bool ignoreStreams) const +bool ValueIfNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (ExprNode::sameAs(other, ignoreStreams)) + if (ExprNode::sameAs(csb, other, ignoreStreams)) return true; - return sameNodes(this, other->as(), ignoreStreams); + return sameNodes(csb, this, other->as(), ignoreStreams); } ValueExprNode* ValueIfNode::pass2(thread_db* tdbb, CompilerScratch* csb) @@ -11874,7 +11910,7 @@ void VariableNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc) *desc = dsqlVar->desc; } -bool VariableNode::dsqlMatch(const ExprNode* other, bool /*ignoreMapCast*/) const +bool VariableNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool /*ignoreMapCast*/) const { const VariableNode* o = other->as(); if (!o) diff --git a/src/dsql/ExprNodes.h b/src/dsql/ExprNodes.h index c10ca6bb36..3fe0e7e32d 100644 --- a/src/dsql/ExprNodes.h +++ b/src/dsql/ExprNodes.h @@ -87,8 +87,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -224,8 +224,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -267,11 +267,11 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -594,7 +594,7 @@ public: fb_assert(false); } - virtual void collectStreams(SortedStreamList& streamList) const; + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; virtual bool computable(CompilerScratch* csb, StreamType stream, bool allowOnlyCurrentStream, ValueExprNode* value); @@ -667,8 +667,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -701,21 +701,21 @@ public: virtual void setParameterName(dsql_par* parameter) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return false; } - virtual void collectStreams(SortedStreamList& streamList) const + virtual void collectStreams(CompilerScratch* /*csb*/, SortedStreamList& streamList) const { if (!streamList.exist(fieldStream)) streamList.add(fieldStream); } - virtual bool unmappable(const MapNode* /*mapNode*/, StreamType /*shellStream*/) + virtual bool unmappable(CompilerScratch* /*csb*/, const MapNode* /*mapNode*/, StreamType /*shellStream*/) { return true; } @@ -777,8 +777,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -849,8 +849,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -932,7 +932,7 @@ public: virtual void setParameterName(dsql_par* parameter) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void getDesc(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, dsc* /*desc*/) { @@ -1083,7 +1083,7 @@ public: virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual OrderNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void setParameterName(dsql_par* /*parameter*/) const { @@ -1199,7 +1199,7 @@ public: const dsc* desc, ValueExprNode* node, bool forceVarChar); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -1245,12 +1245,12 @@ public: virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return false; } - virtual void collectStreams(SortedStreamList& streamList) const + virtual void collectStreams(CompilerScratch* /*csb*/, SortedStreamList& streamList) const { if (!streamList.exist(recStream)) streamList.add(recStream); @@ -1264,8 +1264,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1435,8 +1435,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1467,8 +1467,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1501,17 +1501,17 @@ public: virtual bool dsqlFieldFinder(FieldFinder& visitor); virtual ValueExprNode* dsqlFieldRemapper(FieldRemapper& visitor); - virtual bool unmappable(const MapNode* /*mapNode*/, StreamType /*shellStream*/) + virtual bool unmappable(CompilerScratch* /*csb*/, const MapNode* /*mapNode*/, StreamType /*shellStream*/) { return false; } - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } - virtual void collectStreams(SortedStreamList& streamList) const; + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; virtual bool computable(CompilerScratch* csb, StreamType stream, bool allowOnlyCurrentStream, ValueExprNode* value); @@ -1521,7 +1521,7 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1637,8 +1637,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1676,8 +1676,8 @@ public: virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1715,15 +1715,15 @@ public: virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1764,14 +1764,14 @@ public: virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; @@ -1794,7 +1794,7 @@ public: virtual void setParameterName(dsql_par* parameter) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; diff --git a/src/dsql/Nodes.h b/src/dsql/Nodes.h index 557df1495e..c3d28517e1 100644 --- a/src/dsql/Nodes.h +++ b/src/dsql/Nodes.h @@ -583,7 +583,7 @@ public: { bool ret = false; - NodeRefsHolder holder(visitor.getPool()); + NodeRefsHolder holder(visitor.dsqlScratch->getPool()); getChildren(holder, true); for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) @@ -630,63 +630,23 @@ public: } // Check if expression could return NULL or expression can turn NULL into a true/false. - virtual bool possiblyUnknown() - { - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: - - NodeRefsHolder holder(*tdbb->getDefaultPool()); - getChildren(holder, false); - - for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) - { - if (**i && (*i)->getExpr()->possiblyUnknown()) - return true; - } - - return false; - } + virtual bool possiblyUnknown(OptimizerBlk* opt); // Verify if this node is allowed in an unmapped boolean. - virtual bool unmappable(const MapNode* mapNode, StreamType shellStream) - { - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: - - NodeRefsHolder holder(*tdbb->getDefaultPool()); - getChildren(holder, false); - - for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) - { - if (**i && !(*i)->getExpr()->unmappable(mapNode, shellStream)) - return false; - } - - return true; - } + virtual bool unmappable(CompilerScratch* csb, const MapNode* mapNode, StreamType shellStream); // Return all streams referenced by the expression. - virtual void collectStreams(SortedStreamList& streamList) const - { - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; - NodeRefsHolder holder(*tdbb->getDefaultPool()); - getChildren(holder, false); - - for (const NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) - { - if (**i) - (*i)->getExpr()->collectStreams(streamList); - } - } - - virtual bool findStream(StreamType stream) + virtual bool findStream(CompilerScratch* csb, StreamType stream) { SortedStreamList streams; - collectStreams(streams); + collectStreams(csb, streams); return streams.exist(stream); } - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual ExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { @@ -695,7 +655,7 @@ public: } // Determine if two expression trees are the same. - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; // See if node is presently computable. // A node is said to be computable, if all the streams involved @@ -975,7 +935,7 @@ public: virtual bool dsqlSubSelectFinder(SubSelectFinder& visitor); virtual ValueExprNode* dsqlFieldRemapper(FieldRemapper& visitor); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void setParameterName(dsql_par* parameter) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); @@ -987,19 +947,19 @@ public: virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } - virtual void collectStreams(SortedStreamList& /*streamList*/) const + virtual void collectStreams(CompilerScratch* /*csb*/, SortedStreamList& /*streamList*/) const { // ASF: Although in v2.5 the visitor happens normally for the node childs, nod_count has // been set to 0 in CMP_pass2, so that doesn't happens. return; } - virtual bool unmappable(const MapNode* /*mapNode*/, StreamType /*shellStream*/) + virtual bool unmappable(CompilerScratch* /*csb*/, const MapNode* /*mapNode*/, StreamType /*shellStream*/) { return false; } @@ -1125,23 +1085,23 @@ public: fb_assert(false); } - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } - virtual bool unmappable(const MapNode* /*mapNode*/, StreamType /*shellStream*/) + virtual bool unmappable(CompilerScratch* /*csb*/, const MapNode* /*mapNode*/, StreamType /*shellStream*/) { return false; } - virtual void collectStreams(SortedStreamList& streamList) const + virtual void collectStreams(CompilerScratch* /*csb*/, SortedStreamList& streamList) const { if (!streamList.exist(getStream())) streamList.add(getStream()); } - virtual bool sameAs(const ExprNode* /*other*/, bool /*ignoreStreams*/) const + virtual bool sameAs(CompilerScratch* /*csb*/, const ExprNode* /*other*/, bool /*ignoreStreams*/) const { return false; } diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index d264b895d4..bedab67f60 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -80,8 +80,8 @@ static RseNode* dsqlPassCursorReference(DsqlCompilerScratch*, const MetaName&, R static VariableNode* dsqlPassHiddenVariable(DsqlCompilerScratch* dsqlScratch, ValueExprNode* expr); static USHORT dsqlPassLabel(DsqlCompilerScratch* dsqlScratch, bool breakContinue, MetaName* label); static StmtNode* dsqlProcessReturning(DsqlCompilerScratch*, ReturningClause*, StmtNode*); -static void dsqlSetParameterName(ExprNode*, const ValueExprNode*, const dsql_rel*); -static void dsqlSetParametersName(CompoundStmtNode*, const RecordSourceNode*); +static void dsqlSetParameterName(DsqlCompilerScratch*, ExprNode*, const ValueExprNode*, const dsql_rel*); +static void dsqlSetParametersName(DsqlCompilerScratch*, CompoundStmtNode*, const RecordSourceNode*); static void cleanupRpb(thread_db* tdbb, record_param* rpb); static void makeValidation(thread_db* tdbb, CompilerScratch* csb, StreamType stream, @@ -5864,7 +5864,7 @@ StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool up // We do not allow cases like UPDATE T SET f1 = v1, f2 = v2, f1 = v3... dsqlFieldAppearsOnce(newValues, "UPDATE"); - dsqlSetParametersName(assignStatements, node->dsqlRelation); + dsqlSetParametersName(dsqlScratch, assignStatements, node->dsqlRelation); StmtNode* ret = node; if (!updateOrInsert) @@ -6656,7 +6656,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool upd dsqlScratch->context->pop(); } - dsqlSetParametersName(assignStatements, node->dsqlRelation); + dsqlSetParametersName(dsqlScratch, assignStatements, node->dsqlRelation); StmtNode* ret = node; if (!updateOrInsert) @@ -8926,7 +8926,7 @@ static StmtNode* dsqlProcessReturning(DsqlCompilerScratch* dsqlScratch, Returnin // the parameter is assigned the name of the field it is being inserted (or updated). The same goes // to the name of a relation. // The names are assigned to the parameter only if the field is of array data type. -static void dsqlSetParameterName(ExprNode* exprNode, const ValueExprNode* fld_node, +static void dsqlSetParameterName(DsqlCompilerScratch* dsqlScratch, ExprNode* exprNode, const ValueExprNode* fld_node, const dsql_rel* relation) { DEV_BLKCHK(fld_node, dsql_type_nod); @@ -8953,12 +8953,11 @@ static void dsqlSetParameterName(ExprNode* exprNode, const ValueExprNode* fld_no case ExprNode::TYPE_SUBSTRING_SIMILAR: case ExprNode::TYPE_TRIM: { - thread_db* tdbb = JRD_get_thread_data(); //// FIXME: - NodeRefsHolder holder(*tdbb->getDefaultPool()); + NodeRefsHolder holder(dsqlScratch->getPool()); exprNode->getChildren(holder, true); for (NodeRef** ref = holder.refs.begin(); ref != holder.refs.end(); ++ref) - dsqlSetParameterName((*ref)->getExpr(), fld_node, relation); + dsqlSetParameterName(dsqlScratch, (*ref)->getExpr(), fld_node, relation); break; } @@ -8975,7 +8974,8 @@ static void dsqlSetParameterName(ExprNode* exprNode, const ValueExprNode* fld_no } // Setup parameter parameters name. -static void dsqlSetParametersName(CompoundStmtNode* statements, const RecordSourceNode* relNode) +static void dsqlSetParametersName(DsqlCompilerScratch* dsqlScratch, CompoundStmtNode* statements, + const RecordSourceNode* relNode) { const dsql_ctx* context = relNode->dsqlContext; DEV_BLKCHK(context, dsql_type_ctx); @@ -8989,11 +8989,9 @@ static void dsqlSetParametersName(CompoundStmtNode* statements, const RecordSour AssignmentNode* assign = (*ptr)->as(); if (assign) - dsqlSetParameterName(assign->asgnFrom, assign->asgnTo, relation); + dsqlSetParameterName(dsqlScratch, assign->asgnFrom, assign->asgnTo, relation); else - { fb_assert(false); - } } } diff --git a/src/dsql/Visitors.h b/src/dsql/Visitors.h index ebd4cb51f9..161b2ba090 100644 --- a/src/dsql/Visitors.h +++ b/src/dsql/Visitors.h @@ -129,17 +129,18 @@ public: // thus a valid field reference. For the sake of argument, we'll match qualified to unqualified // reference, but qualified reference must match completely. // A list element containing a simple CAST for collation purposes is allowed. -class InvalidReferenceFinder : public Firebird::PermanentStorage +class InvalidReferenceFinder { public: - InvalidReferenceFinder(Firebird::MemoryPool& pool, const dsql_ctx* aContext, const ValueListNode* aList); + InvalidReferenceFinder(DsqlCompilerScratch* aDsqlScratch, const dsql_ctx* aContext, const ValueListNode* aList); - static bool find(Firebird::MemoryPool& pool, const dsql_ctx* context, + static bool find(DsqlCompilerScratch* dsqlScratch, const dsql_ctx* context, const ValueListNode* list, ExprNode* node); bool visit(ExprNode* node); public: + DsqlCompilerScratch* dsqlScratch; const dsql_ctx* const context; const ValueListNode* const list; bool insideOwnMap; diff --git a/src/dsql/pass1.cpp b/src/dsql/pass1.cpp index 24afc8b773..384208ee55 100644 --- a/src/dsql/pass1.cpp +++ b/src/dsql/pass1.cpp @@ -255,8 +255,9 @@ bool FieldFinder::visit(ExprNode* node) } -InvalidReferenceFinder::InvalidReferenceFinder(MemoryPool& pool, const dsql_ctx* aContext, const ValueListNode* aList) - : PermanentStorage(pool), +InvalidReferenceFinder::InvalidReferenceFinder(DsqlCompilerScratch* aDsqlScratch, + const dsql_ctx* aContext, const ValueListNode* aList) + : dsqlScratch(aDsqlScratch), context(aContext), list(aList), insideOwnMap(false), @@ -265,9 +266,10 @@ InvalidReferenceFinder::InvalidReferenceFinder(MemoryPool& pool, const dsql_ctx* DEV_BLKCHK(list, dsql_type_nod); } -bool InvalidReferenceFinder::find(MemoryPool& pool, const dsql_ctx* context, const ValueListNode* list, ExprNode* node) +bool InvalidReferenceFinder::find(DsqlCompilerScratch* dsqlScratch, const dsql_ctx* context, + const ValueListNode* list, ExprNode* node) { - InvalidReferenceFinder visitor(pool, context, list); + InvalidReferenceFinder visitor(dsqlScratch, context, list); return visitor.visit(node); } @@ -295,7 +297,7 @@ bool InvalidReferenceFinder::visit(ExprNode* node) const NestConst* ptr = list->items.begin(); for (const NestConst* const end = list->items.end(); ptr != end; ++ptr) { - if (PASS1_node_match(node, *ptr, true)) + if (PASS1_node_match(dsqlScratch, node, *ptr, true)) return false; } } @@ -787,7 +789,8 @@ void PASS1_field_unknown(const TEXT* qualifier_name, const TEXT* field_name, @param ignoreMapCast **/ -bool PASS1_node_match(const ExprNode* node1, const ExprNode* node2, bool ignoreMapCast) +bool PASS1_node_match(DsqlCompilerScratch* dsqlScratch, const ExprNode* node1, const ExprNode* node2, + bool ignoreMapCast) { thread_db* tdbb = JRD_get_thread_data(); @@ -816,10 +819,10 @@ bool PASS1_node_match(const ExprNode* node1, const ExprNode* node2, bool ignoreM castNode1->castDesc.dsc_length == castNode2->castDesc.dsc_length && castNode1->castDesc.dsc_sub_type == castNode2->castDesc.dsc_sub_type) { - return PASS1_node_match(castNode1->source, castNode2->source, ignoreMapCast); + return PASS1_node_match(dsqlScratch, castNode1->source, castNode2->source, ignoreMapCast); } - return PASS1_node_match(castNode1->source, node2, ignoreMapCast); + return PASS1_node_match(dsqlScratch, castNode1->source, node2, ignoreMapCast); } const DsqlMapNode* mapNode1 = node1->as(); @@ -833,10 +836,10 @@ bool PASS1_node_match(const ExprNode* node1, const ExprNode* node2, bool ignoreM if (mapNode1->context != mapNode2->context) return false; - return PASS1_node_match(mapNode1->map->map_node, mapNode2->map->map_node, ignoreMapCast); + return PASS1_node_match(dsqlScratch, mapNode1->map->map_node, mapNode2->map->map_node, ignoreMapCast); } - return PASS1_node_match(mapNode1->map->map_node, node2, ignoreMapCast); + return PASS1_node_match(dsqlScratch, mapNode1->map->map_node, node2, ignoreMapCast); } const DsqlAliasNode* aliasNode1 = node1->as(); @@ -846,13 +849,13 @@ bool PASS1_node_match(const ExprNode* node1, const ExprNode* node2, bool ignoreM if (aliasNode1 || aliasNode2) { if (aliasNode1 && aliasNode2) - return PASS1_node_match(aliasNode1->value, aliasNode2->value, ignoreMapCast); + return PASS1_node_match(dsqlScratch, aliasNode1->value, aliasNode2->value, ignoreMapCast); if (aliasNode1) - return PASS1_node_match(aliasNode1->value, node2, ignoreMapCast); + return PASS1_node_match(dsqlScratch, aliasNode1->value, node2, ignoreMapCast); if (aliasNode2) - return PASS1_node_match(node1, aliasNode2->value, ignoreMapCast); + return PASS1_node_match(dsqlScratch, node1, aliasNode2->value, ignoreMapCast); } // Handle derived fields. @@ -870,17 +873,17 @@ bool PASS1_node_match(const ExprNode* node1, const ExprNode* node2, bool ignoreM return false; } - return PASS1_node_match(derivedField1->value, derivedField2->value, ignoreMapCast); + return PASS1_node_match(dsqlScratch, derivedField1->value, derivedField2->value, ignoreMapCast); } if (derivedField1) - return PASS1_node_match(derivedField1->value, node2, ignoreMapCast); + return PASS1_node_match(dsqlScratch, derivedField1->value, node2, ignoreMapCast); if (derivedField2) - return PASS1_node_match(node1, derivedField2->value, ignoreMapCast); + return PASS1_node_match(dsqlScratch, node1, derivedField2->value, ignoreMapCast); } - return node1->type == node2->type && node1->dsqlMatch(node2, ignoreMapCast); + return node1->type == node2->type && node1->dsqlMatch(dsqlScratch, node2, ignoreMapCast); } @@ -2042,7 +2045,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod NestConst* ptr = valueList->items.begin(); for (const NestConst* const end = valueList->items.end(); ptr != end; ++ptr) { - if (InvalidReferenceFinder::find(dsqlScratch->getPool(), parent_context, aggregate->dsqlGroup, *ptr)) + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, *ptr)) { // Invalid expression in the select list // (not contained in either an aggregate or the GROUP BY clause) @@ -2064,7 +2067,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod NestConst* ptr = valueList->items.begin(); for (const NestConst* const end = valueList->items.end(); ptr != end; ++ptr) { - if (InvalidReferenceFinder::find(dsqlScratch->getPool(), parent_context, aggregate->dsqlGroup, *ptr)) + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, *ptr)) { // Invalid expression in the ORDER BY clause // (not contained in either an aggregate or the GROUP BY clause) @@ -2090,7 +2093,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod // AB: Check for invalid contructions inside the HAVING clause - if (InvalidReferenceFinder::find(dsqlScratch->getPool(), parent_context, aggregate->dsqlGroup, + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, parentRse->dsqlWhere)) { // Invalid expression in the HAVING clause @@ -2168,7 +2171,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod NestConst* ptr = valueList->items.begin(); for (const NestConst* const end = valueList->items.end(); ptr != end; ++ptr) { - if (InvalidReferenceFinder::find(dsqlScratch->getPool(), parent_context, aggregate->dsqlGroup, *ptr)) + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, *ptr)) { // Invalid expression in the select list // (not contained in either an aggregate or the GROUP BY clause) @@ -2192,7 +2195,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod NestConst* ptr = valueList->items.begin(); for (const NestConst* const end = valueList->items.end(); ptr != end; ++ptr) { - if (InvalidReferenceFinder::find(dsqlScratch->getPool(), parent_context, aggregate->dsqlGroup, *ptr)) + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, *ptr)) { // Invalid expression in the ORDER BY list // (not contained in either an aggregate or the GROUP BY clause) @@ -2844,7 +2847,7 @@ DsqlMapNode* PASS1_post_map(DsqlCompilerScratch* dsqlScratch, ValueExprNode* nod while (map) { - if (PASS1_node_match(node, map->map_node, false)) + if (PASS1_node_match(dsqlScratch, node, map->map_node, false)) break; ++count; @@ -2950,8 +2953,8 @@ PartitionMap* dsql_ctx::getPartitionMap(DsqlCompilerScratch* dsqlScratch, ValueL !partitionMap && i != ctx_win_maps.end(); ++i) { - if (PASS1_node_match((*i)->partition, partitionNode, false) && - PASS1_node_match((*i)->order, orderNode, false)) + if (PASS1_node_match(dsqlScratch, (*i)->partition, partitionNode, false) && + PASS1_node_match(dsqlScratch, (*i)->order, orderNode, false)) { partitionMap = *i; } diff --git a/src/dsql/pass1_proto.h b/src/dsql/pass1_proto.h index 472dbc476a..83986df9ac 100644 --- a/src/dsql/pass1_proto.h +++ b/src/dsql/pass1_proto.h @@ -49,7 +49,7 @@ void PASS1_limit(Jrd::DsqlCompilerScratch*, NestConst, Jrd::ValueExprNode* PASS1_lookup_alias(Jrd::DsqlCompilerScratch*, const Firebird::MetaName&, Jrd::ValueListNode*, bool); Jrd::dsql_ctx* PASS1_make_context(Jrd::DsqlCompilerScratch* statement, Jrd::RecordSourceNode* relationNode); -bool PASS1_node_match(const Jrd::ExprNode*, const Jrd::ExprNode*, bool); +bool PASS1_node_match(Jrd::DsqlCompilerScratch*, const Jrd::ExprNode*, const Jrd::ExprNode*, bool); Jrd::DsqlMapNode* PASS1_post_map(Jrd::DsqlCompilerScratch*, Jrd::ValueExprNode*, Jrd::dsql_ctx*, Jrd::ValueListNode*, Jrd::ValueListNode*); Jrd::RecordSourceNode* PASS1_relation(Jrd::DsqlCompilerScratch*, Jrd::RecordSourceNode*); diff --git a/src/jrd/Optimizer.cpp b/src/jrd/Optimizer.cpp index 83a465a526..faa6dec491 100644 --- a/src/jrd/Optimizer.cpp +++ b/src/jrd/Optimizer.cpp @@ -60,7 +60,7 @@ namespace Jrd { // Check the index for being an expression one and // matching both the given stream and the given expression tree -bool checkExpressionIndex(const index_desc* idx, ValueExprNode* node, StreamType stream) +bool checkExpressionIndex(CompilerScratch* csb, const index_desc* idx, ValueExprNode* node, StreamType stream) { fb_assert(idx); @@ -68,7 +68,7 @@ bool checkExpressionIndex(const index_desc* idx, ValueExprNode* node, StreamType { // The desired expression can be hidden inside a derived expression node, // so try to recover it (see CORE-4118). - while (!idx->idx_expression->sameAs(node, true)) + while (!idx->idx_expression->sameAs(csb, node, true)) { DerivedExprNode* const derivedExpr = node->as(); CastNode* const cast = node->as(); @@ -82,8 +82,8 @@ bool checkExpressionIndex(const index_desc* idx, ValueExprNode* node, StreamType } SortedStreamList exprStreams, nodeStreams; - idx->idx_expression->collectStreams(exprStreams); - node->collectStreams(nodeStreams); + idx->idx_expression->collectStreams(csb, exprStreams); + node->collectStreams(csb, nodeStreams); if (exprStreams.getCount() == 1 && exprStreams[0] == 0 && nodeStreams.getCount() == 1 && nodeStreams[0] == stream) @@ -720,10 +720,10 @@ void OptimizerRetrieval::analyzeNavigation(const InversionCandidateList& inversi ValueExprNode* const node1 = cmpNode->arg1; ValueExprNode* const node2 = cmpNode->arg2; - if (node1->sameAs(orgNode, false)) + if (node1->sameAs(csb, orgNode, false)) nodes.add(node2); - if (node2->sameAs(orgNode, false)) + if (node2->sameAs(csb, orgNode, false)) nodes.add(node1); } } @@ -736,7 +736,7 @@ void OptimizerRetrieval::analyzeNavigation(const InversionCandidateList& inversi if (idx->idx_flags & idx_expressn) { - if (!checkExpressionIndex(idx, node, stream)) + if (!checkExpressionIndex(csb, idx, node, stream)) continue; } else if (!(fieldNode = node->as()) || fieldNode->fieldStream != stream) @@ -1755,11 +1755,11 @@ bool OptimizerRetrieval::matchBoolean(IndexScratch* indexScratch, BoolExprNode* fb_assert(indexScratch->idx->idx_expression != NULL); - if (!checkExpressionIndex(indexScratch->idx, match, stream) || + if (!checkExpressionIndex(csb, indexScratch->idx, match, stream) || (value && !value->computable(csb, stream, false))) { if ((!cmpNode || cmpNode->blrOp != blr_starting) && value && - checkExpressionIndex(indexScratch->idx, value, stream) && + checkExpressionIndex(csb, indexScratch->idx, value, stream) && match->computable(csb, stream, false)) { ValueExprNode* temp = match; @@ -2490,13 +2490,13 @@ bool OptimizerRetrieval::validateStarts(IndexScratch* indexScratch, ComparativeB // we use starting with against it? Is that allowed? fb_assert(indexScratch->idx->idx_expression != NULL); - if (!(checkExpressionIndex(indexScratch->idx, field, stream) || + if (!(checkExpressionIndex(csb, indexScratch->idx, field, stream) || (value && !value->computable(csb, stream, false)))) { // AB: Can we swap de left and right sides by a starting with? // X STARTING WITH 'a' that is never the same as 'a' STARTING WITH X if (value && - checkExpressionIndex(indexScratch->idx, value, stream) && + checkExpressionIndex(csb, indexScratch->idx, value, stream) && field->computable(csb, stream, false)) { field = value; diff --git a/src/jrd/RecordSourceNodes.cpp b/src/jrd/RecordSourceNodes.cpp index bc01630b1c..24200891ce 100644 --- a/src/jrd/RecordSourceNodes.cpp +++ b/src/jrd/RecordSourceNodes.cpp @@ -49,7 +49,7 @@ static int strcmpSpace(const char* p, const char* q); static void processSource(thread_db* tdbb, CompilerScratch* csb, RseNode* rse, RecordSourceNode* source, BoolExprNode** boolean, RecordSourceNodeStack& stack); static void processMap(thread_db* tdbb, CompilerScratch* csb, MapNode* map, Format** inputFormat); -static void genDeliverUnmapped(thread_db* tdbb, BoolExprNodeStack* deliverStack, MapNode* map, +static void genDeliverUnmapped(CompilerScratch* csb, BoolExprNodeStack* deliverStack, MapNode* map, BoolExprNodeStack* parentStack, StreamType shellStream); static ValueExprNode* resolveUsingField(DsqlCompilerScratch* dsqlScratch, const MetaName& name, ValueListNode* list, const FieldNode* flawedNode, const TEXT* side, dsql_ctx*& ctx); @@ -559,7 +559,8 @@ RecordSourceNode* RelationSourceNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) return dsqlPassRelProc(dsqlScratch, this); } -bool RelationSourceNode::dsqlMatch(const ExprNode* other, bool /*ignoreMapCast*/) const +bool RelationSourceNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, + bool /*ignoreMapCast*/) const { const RelationSourceNode* o = other->as(); return o && dsqlContext == o->dsqlContext; @@ -1015,7 +1016,8 @@ RecordSourceNode* ProcedureSourceNode::dsqlFieldRemapper(FieldRemapper& visitor) return this; } -bool ProcedureSourceNode::dsqlMatch(const ExprNode* other, bool /*ignoreMapCast*/) const +bool ProcedureSourceNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, + bool /*ignoreMapCast*/) const { const ProcedureSourceNode* o = other->as(); return o && dsqlContext == o->dsqlContext; @@ -1241,15 +1243,15 @@ void ProcedureSourceNode::findDependentFromStreams(const OptimizerRetrieval* opt targetList->findDependentFromStreams(optRet, streamList); } -void ProcedureSourceNode::collectStreams(SortedStreamList& streamList) const +void ProcedureSourceNode::collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const { - RecordSourceNode::collectStreams(streamList); + RecordSourceNode::collectStreams(csb, streamList); if (sourceList) - sourceList->collectStreams(streamList); + sourceList->collectStreams(csb, streamList); if (targetList) - targetList->collectStreams(streamList); + targetList->collectStreams(csb, streamList); } @@ -1318,13 +1320,13 @@ RecordSourceNode* AggregateSourceNode::dsqlFieldRemapper(FieldRemapper& visitor) return this; } -bool AggregateSourceNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool AggregateSourceNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { const AggregateSourceNode* o = other->as(); return o && dsqlContext == o->dsqlContext && - PASS1_node_match(dsqlGroup, o->dsqlGroup, ignoreMapCast) && - PASS1_node_match(dsqlRse, o->dsqlRse, ignoreMapCast); + PASS1_node_match(dsqlScratch, dsqlGroup, o->dsqlGroup, ignoreMapCast) && + PASS1_node_match(dsqlScratch, dsqlRse, o->dsqlRse, ignoreMapCast); } void AggregateSourceNode::genBlr(DsqlCompilerScratch* dsqlScratch) @@ -1543,7 +1545,7 @@ RecordSource* AggregateSourceNode::generate(thread_db* tdbb, OptimizerBlk* opt, // Those fields are mappings. Mappings that hold a plain field may be used // to distribute. Handle the simple cases only. BoolExprNodeStack deliverStack; - genDeliverUnmapped(tdbb, &deliverStack, map, parentStack, shellStream); + genDeliverUnmapped(csb, &deliverStack, map, parentStack, shellStream); // try to optimize MAX and MIN to use an index; for now, optimize // only the simplest case, although it is probably possible @@ -1909,7 +1911,7 @@ RecordSource* UnionSourceNode::generate(thread_db* tdbb, OptimizerBlk* opt, cons // hvlad: don't do it for recursive unions else they will work wrong ! BoolExprNodeStack deliverStack; if (!recursive) - genDeliverUnmapped(tdbb, &deliverStack, map, parentStack, shellStream); + genDeliverUnmapped(csb, &deliverStack, map, parentStack, shellStream); rsbs.add(OPT_compile(tdbb, csb, rse, &deliverStack)); @@ -2160,7 +2162,7 @@ bool WindowSourceNode::containsStream(StreamType checkStream) const return false; } -void WindowSourceNode::collectStreams(SortedStreamList& streamList) const +void WindowSourceNode::collectStreams(CompilerScratch* /*csb*/, SortedStreamList& streamList) const { for (ObjectsArray::const_iterator partition = partitions.begin(); partition != partitions.end(); @@ -2290,7 +2292,7 @@ RseNode* RseNode::dsqlFieldRemapper(FieldRemapper& visitor) return this; } -bool RseNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool RseNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { const RseNode* o = other->as(); @@ -2300,7 +2302,7 @@ bool RseNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const // ASF: Commented-out code "Fixed assertion when subquery is used in group by" to make // CORE-4084 work again. return /***dsqlContext &&***/ dsqlContext == o->dsqlContext && - RecordSourceNode::dsqlMatch(other, ignoreMapCast); + RecordSourceNode::dsqlMatch(dsqlScratch, other, ignoreMapCast); } // Make up join node and mark relations as "possibly NULL" if they are in outer joins (inOuterJoin). @@ -3173,27 +3175,27 @@ void RseNode::findDependentFromStreams(const OptimizerRetrieval* optRet, (*ptr)->findDependentFromStreams(optRet, streamList); } -void RseNode::collectStreams(SortedStreamList& streamList) const +void RseNode::collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const { if (rse_first) - rse_first->collectStreams(streamList); + rse_first->collectStreams(csb, streamList); if (rse_skip) - rse_skip->collectStreams(streamList); + rse_skip->collectStreams(csb, streamList); if (rse_boolean) - rse_boolean->collectStreams(streamList); + rse_boolean->collectStreams(csb, streamList); // ASF: The legacy code used to visit rse_sorted and rse_projection, but the nod_sort was never // handled. - // rse_sorted->collectStreams(streamList); - // rse_projection->collectStreams(streamList); + // rse_sorted->collectStreams(csb, streamList); + // rse_projection->collectStreams(csb, streamList); const NestConst* ptr; const NestConst* end; for (ptr = rse_relations.begin(), end = rse_relations.end(); ptr != end; ++ptr) - (*ptr)->collectStreams(streamList); + (*ptr)->collectStreams(csb, streamList); } @@ -3455,12 +3457,10 @@ static void processMap(thread_db* tdbb, CompilerScratch* csb, MapNode* map, Form // Make new boolean nodes from nodes that contain a field from the given shellStream. // Those fields are references (mappings) to other nodes and are used by aggregates and union rse's. -static void genDeliverUnmapped(thread_db* tdbb, BoolExprNodeStack* deliverStack, MapNode* map, +static void genDeliverUnmapped(CompilerScratch* csb, BoolExprNodeStack* deliverStack, MapNode* map, BoolExprNodeStack* parentStack, StreamType shellStream) { - SET_TDBB(tdbb); - - MemoryPool& pool = *tdbb->getDefaultPool(); + MemoryPool& pool = csb->csb_pool; for (BoolExprNodeStack::iterator stack1(*parentStack); stack1.hasData(); ++stack1) { @@ -3476,7 +3476,7 @@ static void genDeliverUnmapped(thread_db* tdbb, BoolExprNodeStack* deliverStack, orgStack.push(binaryNode->arg1); orgStack.push(binaryNode->arg2); - genDeliverUnmapped(tdbb, &newStack, map, &orgStack, shellStream); + genDeliverUnmapped(csb, &newStack, map, &orgStack, shellStream); if (newStack.getCount() == 2) { @@ -3581,7 +3581,7 @@ static void genDeliverUnmapped(thread_db* tdbb, BoolExprNodeStack* deliverStack, // Check also the expression inside the map, because aggregate // functions aren't allowed to be delivered to the WHERE clause. ValueExprNode* value = map->sourceList[fieldId]; - okNode = value->unmappable(map, shellStream); + okNode = value->unmappable(csb, map, shellStream); if (okNode) *newChildren[indexArg] = map->sourceList[fieldId]; @@ -3589,7 +3589,7 @@ static void genDeliverUnmapped(thread_db* tdbb, BoolExprNodeStack* deliverStack, } else { - if ((okNode = children[indexArg]->unmappable(map, shellStream))) + if ((okNode = children[indexArg]->unmappable(csb, map, shellStream))) *newChildren[indexArg] = children[indexArg]; } } diff --git a/src/jrd/RecordSourceNodes.h b/src/jrd/RecordSourceNodes.h index 298682761b..3f906ca1a1 100644 --- a/src/jrd/RecordSourceNodes.h +++ b/src/jrd/RecordSourceNodes.h @@ -283,7 +283,7 @@ public: return false; } - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual RelationSourceNode* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -368,7 +368,7 @@ public: virtual bool dsqlFieldFinder(FieldFinder& visitor); virtual RecordSourceNode* dsqlFieldRemapper(FieldRemapper& visitor); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ProcedureSourceNode* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -397,7 +397,7 @@ public: virtual void findDependentFromStreams(const OptimizerRetrieval* optRet, SortedStreamList* streamList); - virtual void collectStreams(SortedStreamList& streamList) const; + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; virtual RecordSource* compile(thread_db* tdbb, OptimizerBlk* opt, bool innerSubStream); @@ -460,7 +460,7 @@ public: virtual bool dsqlFieldFinder(FieldFinder& visitor); virtual RecordSourceNode* dsqlFieldRemapper(FieldRemapper& visitor); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual AggregateSourceNode* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -610,7 +610,7 @@ public: virtual RecordSourceNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Rse(thread_db* tdbb, CompilerScratch* csb); virtual bool containsStream(StreamType checkStream) const; - virtual void collectStreams(SortedStreamList& streamList) const; + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; virtual void computeDbKeyStreams(StreamList& /*streamList*/) const { @@ -718,7 +718,7 @@ public: virtual bool dsqlFieldFinder(FieldFinder& visitor); virtual RseNode* dsqlFieldRemapper(FieldRemapper& visitor); - virtual bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const; + virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual RseNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual RseNode* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -741,7 +741,7 @@ public: virtual void findDependentFromStreams(const OptimizerRetrieval* optRet, SortedStreamList* streamList); - virtual void collectStreams(SortedStreamList& streamList) const; + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; virtual RecordSource* compile(thread_db* tdbb, OptimizerBlk* opt, bool innerSubStream); diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index 428eeb0aa5..70d060b1f0 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -162,10 +162,10 @@ namespace csb->csb_rpt[*iter].deactivate(); } - bool isReferenced(const ExprNode* node) const + bool isReferenced(CompilerScratch* csb, const ExprNode* node) const { SortedStreamList nodeStreams; - node->collectStreams(nodeStreams); + node->collectStreams(csb, nodeStreams); if (!nodeStreams.hasData()) return false; @@ -311,7 +311,7 @@ namespace static bool augment_stack(ValueExprNode*, ValueExprNodeStack&); static bool augment_stack(BoolExprNode*, BoolExprNodeStack&); static void check_indices(const CompilerScratch::csb_repeat*); -static void check_sorts(RseNode*); +static void check_sorts(CompilerScratch*, RseNode*); static void class_mask(USHORT, ValueExprNode**, ULONG*); static SLONG decompose(thread_db* tdbb, BoolExprNode* boolNode, BoolExprNodeStack& stack, CompilerScratch* csb); @@ -487,7 +487,7 @@ RecordSource* OPT_compile(thread_db* tdbb, CompilerScratch* csb, RseNode* rse, RiverList rivers; - check_sorts(rse); + check_sorts(csb, rse); SortNode* sort = rse->rse_sorted; SortNode* project = rse->rse_projection; SortNode* aggregate = rse->rse_aggregate; @@ -537,7 +537,7 @@ RecordSource* OPT_compile(thread_db* tdbb, CompilerScratch* csb, RseNode* rse, { BoolExprNode* const node = iter.object(); - if (rse->rse_jointype != blr_inner && node->possiblyUnknown()) + if (rse->rse_jointype != blr_inner && node->possiblyUnknown(opt)) { // parent missing conjunctions shouldn't be // distributed to FULL OUTER JOIN streams at all @@ -1021,7 +1021,7 @@ static void check_indices(const CompilerScratch::csb_repeat* csb_tail) } -static void check_sorts(RseNode* rse) +static void check_sorts(CompilerScratch* csb, RseNode* rse) { /************************************** * @@ -1208,7 +1208,7 @@ static void check_sorts(RseNode* rse) // This position doesn't use a simple field, thus we should // check the expression internals. SortedStreamList streams; - (*sort_ptr)->collectStreams(streams); + (*sort_ptr)->collectStreams(csb, streams); // We can use this sort only if there's a single stream // referenced by the expression. @@ -2370,7 +2370,7 @@ static RecordSource* gen_retrieval(thread_db* tdbb, // that are local to this stream. The remaining ones are left in piece // as possible candidates for a merge/hash join. - if ((inversion && node->findStream(stream)) || + if ((inversion && node->findStream(csb, stream)) || (!inversion && node->computable(csb, stream, true))) { compose(*tdbb->getDefaultPool(), &boolean, node); @@ -2823,9 +2823,9 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv { River* const river1 = *iter1; - if (!river1->isReferenced(node1)) + if (!river1->isReferenced(csb, node1)) { - if (!river1->isReferenced(node2)) + if (!river1->isReferenced(csb, node2)) continue; ValueExprNode* const temp = node1; @@ -2839,7 +2839,7 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv { River* const river2 = *iter2; - if (river2->isReferenced(node2)) + if (river2->isReferenced(csb, node2)) { for (eq_class = classes; eq_class < last_class; eq_class += cnt) { diff --git a/src/jrd/rse.h b/src/jrd/rse.h index 0c6b5a37ce..90f3b1c044 100644 --- a/src/jrd/rse.h +++ b/src/jrd/rse.h @@ -55,7 +55,8 @@ class OptimizerBlk : public pool_alloc { public: OptimizerBlk(MemoryPool* pool, RseNode* aRse) - : opt_conjuncts(*pool), + : opt_pool(pool), + opt_conjuncts(*pool), opt_streams(*pool), rse(aRse), outerStreams(*pool), @@ -66,6 +67,10 @@ public: keyStreams(*pool) {} +private: + Firebird::MemoryPool* opt_pool; + +public: CompilerScratch* opt_csb; // compiler scratch block double opt_best_cost; // cost of best join order StreamType opt_best_count; // longest length of indexable streams @@ -87,6 +92,11 @@ public: StreamType opt_stream_number; // stream in position of join order }; + Firebird::MemoryPool& getPool() + { + return *opt_pool; + } + Firebird::HalfStaticArray opt_conjuncts; Firebird::HalfStaticArray opt_streams;