diff --git a/src/dsql/AggNodes.cpp b/src/dsql/AggNodes.cpp index c095a0bc2b..5c329df0a2 100644 --- a/src/dsql/AggNodes.cpp +++ b/src/dsql/AggNodes.cpp @@ -56,13 +56,12 @@ AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool ValueExprNode* aArg) : TypedNode(pool), aggInfo(aAggInfo), - distinct(aDistinct), - dialect1(aDialect1), arg(aArg), asb(NULL), + distinct(aDistinct), + dialect1(aDialect1), indexed(false) { - addChildNode(arg, arg); } DmlNode* AggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -86,7 +85,10 @@ DmlNode* AggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR count = csb->csb_blr_reader.getByte(); - if (count != node->jrdChildNodes.getCount()) + NodeRefsHolder holder(pool); + node->getChildren(holder, false); + + if (count != holder.refs.getCount()) PAR_error(csb, Arg::Gds(isc_funmismat) << name); node->parseArgs(tdbb, csb, count); @@ -146,7 +148,10 @@ bool AggNode::dsqlAggregateFinder(AggregateFinder& visitor) AutoSetRestore autoDeepestLevel(&visitor.deepestLevel, 0); AutoSetRestore autoIgnoreSubSelects(&visitor.ignoreSubSelects, true); - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) visitor.visit((*i)->getExpr()); localDeepestLevel = visitor.deepestLevel; @@ -175,7 +180,10 @@ bool AggNode::dsqlAggregateFinder(AggregateFinder& visitor) AutoSetRestore autoDeepestLevel(&visitor.deepestLevel, localDeepestLevel); - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) aggregate |= visitor.visit((*i)->getExpr()); } @@ -188,9 +196,12 @@ bool AggNode::dsqlAggregate2Finder(Aggregate2Finder& visitor) return false; bool found = false; - FieldFinder fieldFinder(visitor.checkScopeLevel, visitor.matchType); + FieldFinder fieldFinder(visitor.getPool(), visitor.checkScopeLevel, visitor.matchType); - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) found |= fieldFinder.visit((*i)->getExpr()); if (!fieldFinder.getField()) @@ -234,13 +245,16 @@ bool AggNode::dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor) if (!visitor.insideHigherMap) { - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.dsqlScratch->getPool()); + getChildren(holder, true); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) { // If there's another aggregate with the same scope_level or // 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.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 @@ -260,7 +274,7 @@ bool AggNode::dsqlSubSelectFinder(SubSelectFinder& /*visitor*/) ValueExprNode* AggNode::dsqlFieldRemapper(FieldRemapper& visitor) { - AggregateFinder aggFinder(visitor.dsqlScratch, false); + AggregateFinder aggFinder(visitor.getPool(), visitor.dsqlScratch, false); aggFinder.deepestLevel = visitor.dsqlScratch->scopeLevel; aggFinder.currentLevel = visitor.currentLevel; @@ -270,15 +284,18 @@ ValueExprNode* AggNode::dsqlFieldRemapper(FieldRemapper& visitor) return PASS1_post_map(visitor.dsqlScratch, this, visitor.context, visitor.windowNode); } - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) (*i)->remap(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 = nodeAs(other); @@ -297,6 +314,9 @@ void AggNode::setParameterName(dsql_par* parameter) const void AggNode::genBlr(DsqlCompilerScratch* dsqlScratch) { + NodeRefsHolder holder(dsqlScratch->getPool()); + getChildren(holder, true); + if (aggInfo.blr) // Is this a standard aggregate function? dsqlScratch->appendUChar((distinct ? aggInfo.distinctBlr : aggInfo.blr)); else // This is a new window function. @@ -306,7 +326,7 @@ void AggNode::genBlr(DsqlCompilerScratch* dsqlScratch) unsigned count = 0; - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) { if (**i) ++count; @@ -315,7 +335,7 @@ void AggNode::genBlr(DsqlCompilerScratch* dsqlScratch) dsqlScratch->appendUChar(UCHAR(count)); } - for (NodeRef** i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + for (NodeRef** i = holder.refs.begin(); i != holder.refs.end(); ++i) { if (**i) GEN_expr(dsqlScratch, (*i)->getExpr()); @@ -474,7 +494,6 @@ AvgAggNode::AvgAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueEx : AggNode(pool, avgAggInfo, aDistinct, aDialect1, aArg), tempImpure(0) { - dsqlCompatDialectVerb = "avg"; } DmlNode* AvgAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -703,7 +722,7 @@ dsc* AvgAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const AggNode* AvgAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) AvgAggNode(getPool(), distinct, dialect1, + return FB_NEW_POOL(dsqlScratch->getPool()) AvgAggNode(dsqlScratch->getPool(), distinct, dialect1, doDsqlPass(dsqlScratch, arg)); } @@ -718,7 +737,6 @@ ListAggNode::ListAggNode(MemoryPool& pool, bool aDistinct, ValueExprNode* aArg, : AggNode(pool, listAggInfo, aDistinct, false, aArg), delimiter(aDelimiter) { - addChildNode(delimiter, delimiter); } DmlNode* ListAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -841,7 +859,7 @@ AggNode* ListAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { thread_db* tdbb = JRD_get_thread_data(); - AggNode* node = FB_NEW_POOL(getPool()) ListAggNode(getPool(), distinct, + AggNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ListAggNode(dsqlScratch->getPool(), distinct, doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, delimiter)); dsc argDesc; @@ -951,7 +969,7 @@ dsc* CountAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const AggNode* CountAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) CountAggNode(getPool(), distinct, dialect1, + return FB_NEW_POOL(dsqlScratch->getPool()) CountAggNode(dsqlScratch->getPool(), distinct, dialect1, doDsqlPass(dsqlScratch, arg)); } @@ -964,7 +982,6 @@ static AggNode::Register sumAggInfo("SUM", blr_agg_total, blr_agg_to SumAggNode::SumAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg) : AggNode(pool, sumAggInfo, aDistinct, aDialect1, aArg) { - dsqlCompatDialectVerb = "sum"; } DmlNode* SumAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -1203,7 +1220,7 @@ dsc* SumAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const AggNode* SumAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) SumAggNode(getPool(), distinct, dialect1, + return FB_NEW_POOL(dsqlScratch->getPool()) SumAggNode(dsqlScratch->getPool(), distinct, dialect1, doDsqlPass(dsqlScratch, arg)); } @@ -1294,7 +1311,8 @@ dsc* MaxMinAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const AggNode* MaxMinAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) MaxMinAggNode(getPool(), type, doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) MaxMinAggNode(dsqlScratch->getPool(), + type, doDsqlPass(dsqlScratch, arg)); } @@ -1503,7 +1521,8 @@ dsc* StdDevAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const AggNode* StdDevAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) StdDevAggNode(getPool(), type, doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) StdDevAggNode(dsqlScratch->getPool(), + type, doDsqlPass(dsqlScratch, arg)); } @@ -1527,7 +1546,6 @@ CorrAggNode::CorrAggNode(MemoryPool& pool, CorrType aType, ValueExprNode* aArg, arg2(aArg2), impure2Offset(0) { - addChildNode(arg2, arg2); } void CorrAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/) @@ -1765,7 +1783,7 @@ dsc* CorrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const AggNode* CorrAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) CorrAggNode(getPool(), type, + return FB_NEW_POOL(dsqlScratch->getPool()) CorrAggNode(dsqlScratch->getPool(), type, doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, arg2)); } @@ -1805,7 +1823,6 @@ RegrAggNode::RegrAggNode(MemoryPool& pool, RegrType aType, ValueExprNode* aArg, arg2(aArg2), impure2Offset(0) { - addChildNode(arg2, arg2); } void RegrAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/) @@ -2092,7 +2109,7 @@ dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const AggNode* RegrAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) RegrAggNode(getPool(), type, + return FB_NEW_POOL(dsqlScratch->getPool()) RegrAggNode(dsqlScratch->getPool(), type, doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, arg2)); } @@ -2106,7 +2123,6 @@ RegrCountAggNode::RegrCountAggNode(MemoryPool& pool, ValueExprNode* aArg, ValueE : AggNode(pool, regrCountAggInfo, false, false, aArg), arg2(aArg2) { - addChildNode(arg2, arg2); } void RegrCountAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/) @@ -2185,7 +2201,7 @@ dsc* RegrCountAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const AggNode* RegrCountAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) RegrCountAggNode(getPool(), + return FB_NEW_POOL(dsqlScratch->getPool()) RegrCountAggNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, arg2)); } diff --git a/src/dsql/AggNodes.h b/src/dsql/AggNodes.h index 8dceaad48c..281c3a24d2 100644 --- a/src/dsql/AggNodes.h +++ b/src/dsql/AggNodes.h @@ -37,6 +37,11 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual const char* getCompatDialectVerb() + { + return "avg"; + } + virtual unsigned getCapabilities() const { return CAP_RESPECTS_WINDOW_FRAME | CAP_WANTS_AGG_CALLS; @@ -72,6 +77,12 @@ public: return CAP_WANTS_AGG_CALLS; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + AggNode::getChildren(holder, dsql); + holder.add(delimiter); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual bool setParameterType(DsqlCompilerScratch* dsqlScratch, @@ -123,6 +134,11 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual const char* getCompatDialectVerb() + { + return "sum"; + } + virtual unsigned getCapabilities() const { return CAP_RESPECTS_WINDOW_FRAME | CAP_WANTS_AGG_CALLS; @@ -259,6 +275,12 @@ public: virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + AggNode::getChildren(holder, dsql); + holder.add(arg2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -318,6 +340,12 @@ public: virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + AggNode::getChildren(holder, dsql); + holder.add(arg2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -353,6 +381,12 @@ public: virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + AggNode::getChildren(holder, dsql); + holder.add(arg2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); diff --git a/src/dsql/BoolNodes.cpp b/src/dsql/BoolNodes.cpp index 0070c3067f..8d17ae6bd2 100644 --- a/src/dsql/BoolNodes.cpp +++ b/src/dsql/BoolNodes.cpp @@ -103,8 +103,6 @@ BinaryBoolNode::BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aAr arg1(aArg1), arg2(aArg2) { - addChildNode(arg1, arg1); - addChildNode(arg2, arg2); } DmlNode* BinaryBoolNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -128,7 +126,7 @@ string BinaryBoolNode::internalPrint(NodePrinter& printer) const BoolExprNode* BinaryBoolNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) BinaryBoolNode(getPool(), blrOp, + return FB_NEW_POOL(dsqlScratch->getPool()) BinaryBoolNode(dsqlScratch->getPool(), blrOp, doDsqlPass(dsqlScratch, arg1), doDsqlPass(dsqlScratch, arg2)); } @@ -139,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 = nodeAs(other); @@ -150,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 = nodeAs(other); 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 @@ -316,9 +314,6 @@ ComparativeBoolNode::ComparativeBoolNode(MemoryPool& pool, UCHAR aBlrOp, arg3(aArg3), dsqlSpecialArg(NULL) { - addChildNode(arg1, arg1); - addChildNode(arg2, arg2); - addChildNode(arg3, arg3); } DmlNode* ComparativeBoolNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -384,8 +379,8 @@ BoolExprNode* ComparativeBoolNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_dsql_too_many_values) << Arg::Num(MAX_MEMBER_LIST)); } - ComparativeBoolNode* temp = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), - blrOp, procArg1, *ptr); + ComparativeBoolNode* temp = FB_NEW_POOL(dsqlScratch->getPool()) ComparativeBoolNode( + dsqlScratch->getPool(), blrOp, procArg1, *ptr); resultNode = PASS1_compose(resultNode, temp, blr_or); } @@ -411,7 +406,7 @@ BoolExprNode* ComparativeBoolNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) procArg2 = doDsqlPass(dsqlScratch, procArg2); - ComparativeBoolNode* node = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), blrOp, + ComparativeBoolNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ComparativeBoolNode(dsqlScratch->getPool(), blrOp, doDsqlPass(dsqlScratch, procArg1), procArg2, doDsqlPass(dsqlScratch, procArg3)); @@ -490,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 = nodeAs(other); @@ -501,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 = nodeAs(other); 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; @@ -525,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; } @@ -1263,17 +1258,19 @@ bool ComparativeBoolNode::sleuth(thread_db* tdbb, jrd_req* request, const dsc* d BoolExprNode* ComparativeBoolNode::createRseNode(DsqlCompilerScratch* dsqlScratch, UCHAR rseBlrOp) { + MemoryPool& pool = dsqlScratch->getPool(); + // Create a derived table representing our subquery. - SelectExprNode* dt = FB_NEW_POOL(getPool()) SelectExprNode(getPool()); + SelectExprNode* dt = FB_NEW_POOL(pool) SelectExprNode(pool); // Ignore validation for column names that must exist for "user" derived tables. dt->dsqlFlags = RecordSourceNode::DFLAG_DT_IGNORE_COLUMN_CHECK | RecordSourceNode::DFLAG_DERIVED; dt->querySpec = static_cast(dsqlSpecialArg.getObject()); - RseNode* querySpec = FB_NEW_POOL(getPool()) RseNode(getPool()); - querySpec->dsqlFrom = FB_NEW_POOL(getPool()) RecSourceListNode(getPool(), 1); + RseNode* querySpec = FB_NEW_POOL(pool) RseNode(pool); + querySpec->dsqlFrom = FB_NEW_POOL(pool) RecSourceListNode(pool, 1); querySpec->dsqlFrom->items[0] = dt; - SelectExprNode* select_expr = FB_NEW_POOL(getPool()) SelectExprNode(getPool()); + SelectExprNode* select_expr = FB_NEW_POOL(pool) SelectExprNode(pool); select_expr->querySpec = querySpec; const DsqlContextStack::iterator base(*dsqlScratch->context); @@ -1285,7 +1282,7 @@ BoolExprNode* ComparativeBoolNode::createRseNode(DsqlCompilerScratch* dsqlScratc // Create a conjunct to be injected. - ComparativeBoolNode* cmpNode = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), blrOp, + ComparativeBoolNode* cmpNode = FB_NEW_POOL(pool) ComparativeBoolNode(pool, blrOp, doDsqlPass(dsqlScratch, arg1, false), rse->dsqlSelectList->items[0]); PASS1_set_parameter_type(dsqlScratch, cmpNode->arg1, cmpNode->arg2, false); @@ -1293,7 +1290,7 @@ BoolExprNode* ComparativeBoolNode::createRseNode(DsqlCompilerScratch* dsqlScratc rse->dsqlWhere = cmpNode; // Create output node. - RseBoolNode* rseBoolNode = FB_NEW_POOL(getPool()) RseBoolNode(getPool(), rseBlrOp, rse); + RseBoolNode* rseBoolNode = FB_NEW_POOL(pool) RseBoolNode(pool, rseBlrOp, rse); // Finish off by cleaning up contexts dsqlScratch->unionContext.clear(baseUnion); @@ -1314,7 +1311,6 @@ MissingBoolNode::MissingBoolNode(MemoryPool& pool, ValueExprNode* aArg, bool aDs dsqlUnknown(aDsqlUnknown), arg(aArg) { - addChildNode(arg, arg); } DmlNode* MissingBoolNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -1336,7 +1332,7 @@ string MissingBoolNode::internalPrint(NodePrinter& printer) const BoolExprNode* MissingBoolNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - MissingBoolNode* node = FB_NEW_POOL(getPool()) MissingBoolNode(getPool(), + MissingBoolNode* node = FB_NEW_POOL(dsqlScratch->getPool()) MissingBoolNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); PASS1_set_parameter_type(dsqlScratch, node->arg, (dsc*) NULL, false); @@ -1408,7 +1404,6 @@ NotBoolNode::NotBoolNode(MemoryPool& pool, BoolExprNode* aArg) : TypedNode(pool), arg(aArg) { - addChildNode(arg, arg); } DmlNode* NotBoolNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -1475,6 +1470,7 @@ bool NotBoolNode::execute(thread_db* tdbb, jrd_req* request) const // Get rid of redundant nested NOT predicates. BoolExprNode* NotBoolNode::process(DsqlCompilerScratch* dsqlScratch, bool invert) { + MemoryPool& pool = dsqlScratch->getPool(); NotBoolNode* notArg = nodeAs(arg); if (notArg) @@ -1530,8 +1526,8 @@ BoolExprNode* NotBoolNode::process(DsqlCompilerScratch* dsqlScratch, bool invert return NULL; } - ComparativeBoolNode* node = FB_NEW_POOL(getPool()) ComparativeBoolNode( - getPool(), newBlrOp, cmpArg->arg1, cmpArg->arg2); + ComparativeBoolNode* node = FB_NEW_POOL(pool) ComparativeBoolNode( + pool, newBlrOp, cmpArg->arg1, cmpArg->arg2); node->dsqlSpecialArg = cmpArg->dsqlSpecialArg; node->dsqlCheckBoolean = cmpArg->dsqlCheckBoolean; @@ -1545,13 +1541,13 @@ BoolExprNode* NotBoolNode::process(DsqlCompilerScratch* dsqlScratch, bool invert case blr_between: { - ComparativeBoolNode* cmpNode1 = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), + ComparativeBoolNode* cmpNode1 = FB_NEW_POOL(pool) ComparativeBoolNode(pool, blr_lss, cmpArg->arg1, cmpArg->arg2); - ComparativeBoolNode* cmpNode2 = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), + ComparativeBoolNode* cmpNode2 = FB_NEW_POOL(pool) ComparativeBoolNode(pool, blr_gtr, cmpArg->arg1, cmpArg->arg3); - BinaryBoolNode* node = FB_NEW_POOL(getPool()) BinaryBoolNode(getPool(), blr_or, + BinaryBoolNode* node = FB_NEW_POOL(pool) BinaryBoolNode(pool, blr_or, cmpNode1, cmpNode2); return node->dsqlPass(dsqlScratch); @@ -1567,10 +1563,10 @@ BoolExprNode* NotBoolNode::process(DsqlCompilerScratch* dsqlScratch, bool invert { UCHAR newBlrOp = binArg->blrOp == blr_and ? blr_or : blr_and; - NotBoolNode* notNode1 = FB_NEW_POOL(getPool()) NotBoolNode(getPool(), binArg->arg1); - NotBoolNode* notNode2 = FB_NEW_POOL(getPool()) NotBoolNode(getPool(), binArg->arg2); + NotBoolNode* notNode1 = FB_NEW_POOL(pool) NotBoolNode(pool, binArg->arg1); + NotBoolNode* notNode2 = FB_NEW_POOL(pool) NotBoolNode(pool, binArg->arg2); - BinaryBoolNode* node = FB_NEW_POOL(getPool()) BinaryBoolNode(getPool(), newBlrOp, + BinaryBoolNode* node = FB_NEW_POOL(pool) BinaryBoolNode(pool, newBlrOp, notNode1, notNode2); return node->dsqlPass(dsqlScratch); @@ -1581,7 +1577,7 @@ BoolExprNode* NotBoolNode::process(DsqlCompilerScratch* dsqlScratch, bool invert // No inversion is possible, so just recreate the input node // and return immediately to avoid infinite recursion later. - return FB_NEW_POOL(getPool()) NotBoolNode(getPool(), doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(pool) NotBoolNode(pool, doDsqlPass(dsqlScratch, arg)); } @@ -1602,7 +1598,6 @@ RseBoolNode::RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsql rse(NULL), subQuery(NULL) { - addChildNode(dsqlRse, rse); } DmlNode* RseBoolNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -1645,7 +1640,7 @@ BoolExprNode* RseBoolNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) const DsqlContextStack::iterator base(*dsqlScratch->context); - RseBoolNode* node = FB_NEW_POOL(getPool()) RseBoolNode(getPool(), blrOp, + RseBoolNode* node = FB_NEW_POOL(dsqlScratch->getPool()) RseBoolNode(dsqlScratch->getPool(), blrOp, PASS1_rse(dsqlScratch, nodeAs(dsqlRse), false)); // Finish off by cleaning up contexts @@ -1660,9 +1655,9 @@ void RseBoolNode::genBlr(DsqlCompilerScratch* dsqlScratch) GEN_rse(dsqlScratch, nodeAs(dsqlRse)); } -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 = nodeAs(other); @@ -1671,9 +1666,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 = nodeAs(other); @@ -1890,7 +1885,7 @@ BoolExprNode* RseBoolNode::convertNeqAllToNotAny(thread_db* tdbb, CompilerScratc andNode->arg2 = rseBoolNode; - RseNode* newInnerRse = innerRse->clone(); + RseNode* newInnerRse = innerRse->clone(csb->csb_pool); newInnerRse->ignoreDbKey(tdbb, csb); rseBoolNode = FB_NEW_POOL(csb->csb_pool) RseBoolNode(csb->csb_pool, blr_any); @@ -1921,7 +1916,7 @@ BoolExprNode* RseBoolNode::convertNeqAllToNotAny(thread_db* tdbb, CompilerScratc newInnerRse->rse_boolean = boolean; - SubExprNodeCopier copier(csb); + SubExprNodeCopier copier(csb->csb_pool, csb); return copier.copy(tdbb, static_cast(newNode)); } diff --git a/src/dsql/BoolNodes.h b/src/dsql/BoolNodes.h index 8c3a01b434..0bbd47c7c0 100644 --- a/src/dsql/BoolNodes.h +++ b/src/dsql/BoolNodes.h @@ -39,13 +39,21 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + BoolExprNode::getChildren(holder, dsql); + + holder.add(arg1); + holder.add(arg2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); 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: @@ -74,18 +82,27 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + BoolExprNode::getChildren(holder, dsql); + + holder.add(arg1); + holder.add(arg2); + holder.add(arg3); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; 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); @@ -118,11 +135,17 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + BoolExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -145,11 +168,17 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + BoolExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -173,6 +202,16 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + BoolExprNode::getChildren(holder, dsql); + + if (dsql) + holder.add(dsqlRse); + else + holder.add(rse); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); @@ -187,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/DdlNodes.epp b/src/dsql/DdlNodes.epp index 83cc536d9a..718b1d0a35 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -3586,8 +3586,8 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d if (relationName.hasData()) { - RelationSourceNode* relationNode = FB_NEW_POOL(getPool()) RelationSourceNode(getPool(), - relationName); + RelationSourceNode* relationNode = FB_NEW_POOL(dsqlScratch->getPool()) RelationSourceNode( + dsqlScratch->getPool(), relationName); const string temp = relationNode->alias; // always empty? @@ -4873,7 +4873,7 @@ void AlterDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, status_exception::raise(Arg::PrivateDyn(160)); } - dsql_fld localField(dsqlScratch->getStatement()->getPool()); + dsql_fld localField(dsqlScratch->getPool()); // Get the attributes of the domain, and set any occurrences of // keyword VALUE to the correct type, length, scale, etc. @@ -6416,7 +6416,7 @@ void RelationNode::makeConstraint(thread_db* /*tdbb*/, DsqlCompilerScratch* dsql jrd_tra* transaction, AddConstraintClause* clause, ObjectsArray& constraints, bool* notNull) { - MemoryPool& pool = constraints.getPool(); + MemoryPool& pool = dsqlScratch->getPool(); switch (clause->constraintType) { @@ -12005,7 +12005,7 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc if (!DBB.RDB$CHARACTER_SET_NAME.NULL && setDefaultCollation.hasData()) { - AlterCharSetNode alterCharSetNode(getPool(), setDefaultCharSet, setDefaultCollation); + AlterCharSetNode alterCharSetNode(dsqlScratch->getPool(), setDefaultCharSet, setDefaultCollation); alterCharSetNode.execute(tdbb, dsqlScratch, transaction); } diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index 6725b5ee8a..c23f5fa0c3 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -1162,7 +1162,7 @@ public: bool descending; }; - struct Constraint : public PermanentStorage + struct Constraint { enum Type { TYPE_CHECK, TYPE_NOT_NULL, TYPE_PK, TYPE_UNIQUE, TYPE_FK }; @@ -1194,8 +1194,7 @@ public: }; explicit Constraint(MemoryPool& p) - : PermanentStorage(p), - type(TYPE_CHECK), // Just something to initialize. Do not assume it. + : type(TYPE_CHECK), // Just something to initialize. Do not assume it. columns(p), index(NULL), refRelation(p), @@ -1218,11 +1217,10 @@ public: Firebird::ObjectsArray blrWritersHolder; }; - struct CreateDropConstraint : public PermanentStorage + struct CreateDropConstraint { explicit CreateDropConstraint(MemoryPool& p) - : PermanentStorage(p), - name(p) + : name(p) { } @@ -1230,7 +1228,7 @@ public: Firebird::AutoPtr create; }; - struct Clause : public PermanentStorage + struct Clause { enum Type { @@ -1246,8 +1244,7 @@ public: }; explicit Clause(MemoryPool& p, Type aType) - : PermanentStorage(p), - type(aType) + : type(aType) { } @@ -2109,12 +2106,11 @@ protected: } public: - class Property : public PermanentStorage + class Property { public: explicit Property(MemoryPool& p) - : PermanentStorage(p), - value(p) + : value(p) { } Firebird::MetaName property; diff --git a/src/dsql/DsqlCompilerScratch.cpp b/src/dsql/DsqlCompilerScratch.cpp index c91e8d1cbd..18de5ae044 100644 --- a/src/dsql/DsqlCompilerScratch.cpp +++ b/src/dsql/DsqlCompilerScratch.cpp @@ -896,7 +896,7 @@ RseNode* DsqlCompilerScratch::pass1RseIsRecursive(RseNode* input) { fb_assert(rseNode->dsqlExplicitJoin); - RseNode* dstRse = rseNode->clone(); + RseNode* dstRse = rseNode->clone(getPool()); *pDstTable = dstRse; diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 66afd14c6e..1ebe69a9f6 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -249,20 +249,26 @@ 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; - size_t count = dsqlChildNodes.getCount(); - if (other->dsqlChildNodes.getCount() != count) + NodeRefsHolder thisHolder(dsqlScratch->getPool()); + getChildren(thisHolder, true); + + NodeRefsHolder otherHolder(dsqlScratch->getPool()); + other->getChildren(otherHolder, true); + + size_t count = thisHolder.refs.getCount(); + if (otherHolder.refs.getCount() != count) return false; - const auto* j = other->dsqlChildNodes.begin(); + const auto* j = otherHolder.refs.begin(); - for (const auto& i : dsqlChildNodes) + for (const auto& i : thisHolder.refs) { - 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; ++j; @@ -271,23 +277,29 @@ bool ExprNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const 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; - size_t count = jrdChildNodes.getCount(); - if (other->jrdChildNodes.getCount() != count) + NodeRefsHolder thisHolder(csb->csb_pool); + getChildren(thisHolder, false); + + NodeRefsHolder otherHolder(csb->csb_pool); + other->getChildren(otherHolder, false); + + size_t count = thisHolder.refs.getCount(); + if (otherHolder.refs.getCount() != count) return false; - const auto* j = other->jrdChildNodes.begin(); + const auto* j = otherHolder.refs.begin(); - for (const auto& i : jrdChildNodes) + for (const auto& i : thisHolder.refs) { 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; ++j; @@ -296,10 +308,53 @@ bool ExprNode::sameAs(const ExprNode* other, bool ignoreStreams) const 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*/) { - for (auto& i : jrdChildNodes) + NodeRefsHolder holder(csb->csb_pool); + getChildren(holder, false); + + for (auto& i : holder.refs) { if (*i && !i->getExpr()->computable(csb, stream, allowOnlyCurrentStream)) return false; @@ -310,7 +365,10 @@ bool ExprNode::computable(CompilerScratch* csb, StreamType stream, void ExprNode::findDependentFromStreams(const OptimizerRetrieval* optRet, SortedStreamList* streamList) { - for (auto& i : jrdChildNodes) + NodeRefsHolder holder(optRet->getPool()); + getChildren(holder, false); + + for (auto& i : holder.refs) { if (*i) i->getExpr()->findDependentFromStreams(optRet, streamList); @@ -319,7 +377,10 @@ void ExprNode::findDependentFromStreams(const OptimizerRetrieval* optRet, Sorted ExprNode* ExprNode::pass1(thread_db* tdbb, CompilerScratch* csb) { - for (auto& i : jrdChildNodes) + NodeRefsHolder holder(csb->csb_pool); + getChildren(holder, false); + + for (auto& i : holder.refs) { if (*i) i->pass1(tdbb, csb); @@ -330,7 +391,10 @@ ExprNode* ExprNode::pass1(thread_db* tdbb, CompilerScratch* csb) ExprNode* ExprNode::pass2(thread_db* tdbb, CompilerScratch* csb) { - for (auto& i : jrdChildNodes) + NodeRefsHolder holder(csb->csb_pool); + getChildren(holder, false); + + for (auto& i : holder.refs) { if (*i) i->pass2(tdbb, csb); @@ -397,33 +461,8 @@ ArithmeticNode::ArithmeticNode(MemoryPool& pool, UCHAR aBlrOp, bool aDialect1, arg1(aArg1), arg2(aArg2) { - switch (blrOp) - { - case blr_add: - dsqlCompatDialectVerb = "add"; - break; - - case blr_subtract: - dsqlCompatDialectVerb = "subtract"; - break; - - case blr_multiply: - dsqlCompatDialectVerb = "multiply"; - break; - - case blr_divide: - dsqlCompatDialectVerb = "divide"; - break; - - default: - fb_assert(false); - } - - label = dsqlCompatDialectVerb; + label = getCompatDialectVerb(); label.upper(); - - addChildNode(arg1, arg1); - addChildNode(arg2, arg2); } DmlNode* ArithmeticNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -1662,9 +1701,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 = nodeAs(other); @@ -1673,15 +1712,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 = nodeAs(other); 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; } @@ -1691,8 +1730,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; } @@ -2845,8 +2884,8 @@ dsc* ArithmeticNode::addTimeStamp(const dsc* desc, impure_value* value) const ValueExprNode* ArithmeticNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) ArithmeticNode(getPool(), blrOp, dialect1, - doDsqlPass(dsqlScratch, arg1), doDsqlPass(dsqlScratch, arg2)); + return FB_NEW_POOL(dsqlScratch->getPool()) ArithmeticNode(dsqlScratch->getPool(), + blrOp, dialect1, doDsqlPass(dsqlScratch, arg1), doDsqlPass(dsqlScratch, arg2)); } @@ -2889,7 +2928,6 @@ BoolAsValueNode::BoolAsValueNode(MemoryPool& pool, BoolExprNode* aBoolean) : TypedNode(pool), boolean(aBoolean) { - addChildNode(boolean, boolean); } DmlNode* BoolAsValueNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -2910,8 +2948,8 @@ string BoolAsValueNode::internalPrint(NodePrinter& printer) const ValueExprNode* BoolAsValueNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - BoolAsValueNode* node = FB_NEW_POOL(getPool()) BoolAsValueNode(getPool(), - doDsqlPass(dsqlScratch, boolean)); + BoolAsValueNode* node = FB_NEW_POOL(dsqlScratch->getPool()) BoolAsValueNode( + dsqlScratch->getPool(), doDsqlPass(dsqlScratch, boolean)); return node; } @@ -2983,7 +3021,6 @@ CastNode::CastNode(MemoryPool& pool, ValueExprNode* aSource, dsql_fld* aDsqlFiel artificial(false) { castDesc.clear(); - addChildNode(source, source); } // Parse a datatype cast. @@ -3024,7 +3061,7 @@ string CastNode::internalPrint(NodePrinter& printer) const ValueExprNode* CastNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - CastNode* node = FB_NEW_POOL(getPool()) CastNode(getPool()); + CastNode* node = FB_NEW_POOL(dsqlScratch->getPool()) CastNode(dsqlScratch->getPool()); node->dsqlAlias = dsqlAlias; node->source = doDsqlPass(dsqlScratch, source); node->dsqlField = dsqlField; @@ -3114,7 +3151,7 @@ void CastNode::getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc) ValueExprNode* CastNode::copy(thread_db* tdbb, NodeCopier& copier) const { - CastNode* node = FB_NEW_POOL(getPool()) CastNode(getPool()); + CastNode* node = FB_NEW_POOL(*tdbb->getDefaultPool()) CastNode(*tdbb->getDefaultPool()); node->source = copier.copy(tdbb, source); node->castDesc = castDesc; @@ -3123,9 +3160,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 = nodeAs(other); @@ -3134,9 +3171,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 = nodeAs(other); @@ -3271,8 +3308,8 @@ string CoalesceNode::internalPrint(NodePrinter& printer) const ValueExprNode* CoalesceNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - CoalesceNode* node = FB_NEW_POOL(getPool()) CoalesceNode(getPool(), - doDsqlPass(dsqlScratch, args)); + CoalesceNode* node = FB_NEW_POOL(dsqlScratch->getPool()) CoalesceNode( + dsqlScratch->getPool(), doDsqlPass(dsqlScratch, args)); node->make(dsqlScratch, &node->nodDesc); // Set descriptor for output node. node->setParameterType(dsqlScratch, &node->nodDesc, false); return node; @@ -3372,7 +3409,6 @@ CollateNode::CollateNode(MemoryPool& pool, ValueExprNode* aArg, const Firebird:: arg(aArg), collation(pool, aCollation) { - addDsqlChildNode(arg); } string CollateNode::internalPrint(NodePrinter& printer) const @@ -3460,8 +3496,6 @@ ConcatenateNode::ConcatenateNode(MemoryPool& pool, ValueExprNode* aArg1, ValueEx arg1(aArg1), arg2(aArg2) { - addChildNode(arg1, arg1); - addChildNode(arg2, arg2); } DmlNode* ConcatenateNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -3718,7 +3752,7 @@ dsc* ConcatenateNode::execute(thread_db* tdbb, jrd_req* request) const ValueExprNode* ConcatenateNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) ConcatenateNode(getPool(), + return FB_NEW_POOL(dsqlScratch->getPool()) ConcatenateNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg1), doDsqlPass(dsqlScratch, arg2)); } @@ -4118,9 +4152,9 @@ dsc* CurrentRoleNode::execute(thread_db* tdbb, jrd_req* request) const return &impure->vlu_desc; } -ValueExprNode* CurrentRoleNode::dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/) +ValueExprNode* CurrentRoleNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) CurrentRoleNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) CurrentRoleNode(dsqlScratch->getPool()); } @@ -4211,9 +4245,9 @@ dsc* CurrentUserNode::execute(thread_db* tdbb, jrd_req* request) const return &impure->vlu_desc; } -ValueExprNode* CurrentUserNode::dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/) +ValueExprNode* CurrentUserNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) CurrentUserNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) CurrentUserNode(dsqlScratch->getPool()); } @@ -4245,8 +4279,8 @@ string DecodeNode::internalPrint(NodePrinter& printer) const ValueExprNode* DecodeNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - DecodeNode* node = FB_NEW_POOL(getPool()) DecodeNode(getPool(), doDsqlPass(dsqlScratch, test), - doDsqlPass(dsqlScratch, conditions), doDsqlPass(dsqlScratch, values)); + DecodeNode* node = FB_NEW_POOL(dsqlScratch->getPool()) DecodeNode(dsqlScratch->getPool(), + doDsqlPass(dsqlScratch, test), doDsqlPass(dsqlScratch, conditions), doDsqlPass(dsqlScratch, values)); node->label = label; node->make(dsqlScratch, &node->nodDesc); // Set descriptor for output node. node->setParameterType(dsqlScratch, &node->nodDesc, false); @@ -4284,10 +4318,11 @@ ValueExprNode* DecodeNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) } else { - DecodeNode* newNode = FB_NEW_POOL(getPool()) DecodeNode(getPool(), + DecodeNode* newNode = FB_NEW_POOL(dsqlScratch->getPool()) DecodeNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, test), - FB_NEW_POOL(getPool()) ValueListNode(getPool(), conditionsCount), - FB_NEW_POOL(getPool()) ValueListNode(getPool(), valuesCount + (last ? 0 : 1))); + FB_NEW_POOL(dsqlScratch->getPool()) ValueListNode(dsqlScratch->getPool(), conditionsCount), + FB_NEW_POOL(dsqlScratch->getPool()) ValueListNode(dsqlScratch->getPool(), + valuesCount + (last ? 0 : 1))); newNode->conditions->items.assign(conditions.begin() + index, conditionsCount); newNode->values->items.assign(values.begin() + index, valuesCount); @@ -4332,7 +4367,7 @@ bool DecodeNode::setParameterType(DsqlCompilerScratch* dsqlScratch, if (setParameters) { // Build list to make describe information for the test and conditions expressions. - AutoPtr node1(FB_NEW_POOL(getPool()) ValueListNode(getPool(), + AutoPtr node1(FB_NEW_POOL(dsqlScratch->getPool()) ValueListNode(dsqlScratch->getPool(), conditions->items.getCount() + 1)); dsc node1Desc; @@ -4549,7 +4584,7 @@ ValueExprNode* DefaultNode::createFromField(thread_db* tdbb, CompilerScratch* cs if (!map) map = localMap.getBuffer(STREAM_MAP_LENGTH); - return NodeCopier(csb, map).copy(tdbb, fld->fld_default_value); + return NodeCopier(csb->csb_pool, csb, map).copy(tdbb, fld->fld_default_value); } else return FB_NEW_POOL(csb->csb_pool) NullNode(csb->csb_pool); @@ -4567,7 +4602,7 @@ string DefaultNode::internalPrint(NodePrinter& printer) const ValueExprNode* DefaultNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - DefaultNode* node = FB_NEW_POOL(getPool()) DefaultNode(getPool(), + DefaultNode* node = FB_NEW_POOL(dsqlScratch->getPool()) DefaultNode(dsqlScratch->getPool(), relationName, fieldName); return node; } @@ -4593,9 +4628,9 @@ void DefaultNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* /*desc*/) { } -bool DefaultNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const +bool DefaultNode::dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const DefaultNode* o = nodeAs(other); @@ -4635,9 +4670,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 auto i : internalStreamList) { @@ -4653,7 +4688,7 @@ bool DerivedExprNode::computable(CompilerScratch* csb, StreamType stream, return false; SortedStreamList argStreams; - arg->collectStreams(argStreams); + arg->collectStreams(csb, argStreams); for (const auto n : internalStreamList) { @@ -4814,7 +4849,7 @@ ValueExprNode* DomainValidationNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_dsql_domain_err)); } - DomainValidationNode* node = FB_NEW_POOL(getPool()) DomainValidationNode(getPool()); + DomainValidationNode* node = FB_NEW_POOL(dsqlScratch->getPool()) DomainValidationNode(dsqlScratch->getPool()); node->domDesc = dsqlScratch->domainValue; return node; @@ -4878,7 +4913,6 @@ ExtractNode::ExtractNode(MemoryPool& pool, UCHAR aBlrSubOp, ValueExprNode* aArg) blrSubOp(aBlrSubOp), arg(aArg) { - addChildNode(arg, arg); } DmlNode* ExtractNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -4943,7 +4977,7 @@ ValueExprNode* ExtractNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) break; } - return FB_NEW_POOL(getPool()) ExtractNode(getPool(), blrSubOp, sub1); + return FB_NEW_POOL(dsqlScratch->getPool()) ExtractNode(dsqlScratch->getPool(), blrSubOp, sub1); } void ExtractNode::setParameterName(dsql_par* parameter) const @@ -5014,9 +5048,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 = nodeAs(other); @@ -5025,9 +5059,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 = nodeAs(other); @@ -5447,7 +5481,7 @@ ValueExprNode* FieldNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (dsqlScratch->isPsql() && !dsqlQualifier.hasData()) { - VariableNode* node = FB_NEW_POOL(getPool()) VariableNode(getPool()); + VariableNode* node = FB_NEW_POOL(dsqlScratch->getPool()) VariableNode(dsqlScratch->getPool()); node->line = line; node->column = column; node->dsqlName = dsqlName; @@ -5957,9 +5991,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 = nodeAs(other); @@ -5969,14 +6003,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 = nodeAs(other); @@ -6248,7 +6282,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++) @@ -6394,7 +6428,6 @@ GenIdNode::GenIdNode(MemoryPool& pool, bool aDialect1, implicit(aImplicit), identity(aIdentity) { - addChildNode(arg, arg); } DmlNode* GenIdNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -6446,9 +6479,8 @@ string GenIdNode::internalPrint(NodePrinter& printer) const ValueExprNode* GenIdNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - GenIdNode* const node = FB_NEW_POOL(getPool()) - GenIdNode(getPool(), dialect1, generator.name, - doDsqlPass(dsqlScratch, arg), implicit, identity); + GenIdNode* const node = FB_NEW_POOL(dsqlScratch->getPool()) GenIdNode(dsqlScratch->getPool(), + dialect1, generator.name, doDsqlPass(dsqlScratch, arg), implicit, identity); node->generator = generator; node->step = step; node->sysGen = sysGen; @@ -6516,9 +6548,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 = nodeAs(other); @@ -6530,9 +6562,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 = nodeAs(other); @@ -6626,7 +6658,6 @@ InternalInfoNode::InternalInfoNode(MemoryPool& pool, ValueExprNode* aArg) : TypedNode(pool), arg(aArg) { - addChildNode(arg, arg); } DmlNode* InternalInfoNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -6874,7 +6905,7 @@ ValueExprNode* InternalInfoNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_random) << attr.alias); } - return FB_NEW_POOL(getPool()) InternalInfoNode(getPool(), doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) InternalInfoNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); } @@ -7147,7 +7178,7 @@ ValueExprNode* LiteralNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (litDesc.dsc_dtype > dtype_any_text) return this; - LiteralNode* constant = FB_NEW_POOL(getPool()) LiteralNode(getPool()); + LiteralNode* constant = FB_NEW_POOL(dsqlScratch->getPool()) LiteralNode(dsqlScratch->getPool()); constant->dsqlStr = dsqlStr; constant->litDesc = litDesc; @@ -7285,9 +7316,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 = nodeAs(other); @@ -7301,9 +7332,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 = nodeAs(other); @@ -7329,7 +7360,7 @@ dsc* LiteralNode::execute(thread_db* /*tdbb*/, jrd_req* /*request*/) const return const_cast(&litDesc); } -void LiteralNode::fixMinSInt64() +void LiteralNode::fixMinSInt64(MemoryPool& pool) { // MIN_SINT64 should be stored as BIGINT, not DECFLOAT @@ -7358,7 +7389,7 @@ void LiteralNode::fixMinSInt64() if (*minSInt64) return; - SINT64* valuePtr = FB_NEW_POOL(getPool()) SINT64(QUADCONST(0x8000000000000000)); + SINT64* valuePtr = FB_NEW_POOL(pool) SINT64(QUADCONST(0x8000000000000000)); litDesc.dsc_dtype = dtype_int64; litDesc.dsc_length = sizeof(SINT64); litDesc.dsc_scale = scale; @@ -7383,7 +7414,7 @@ string DsqlAliasNode::internalPrint(NodePrinter& printer) const ValueExprNode* DsqlAliasNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - DsqlAliasNode* node = FB_NEW_POOL(getPool()) DsqlAliasNode(getPool(), name, + DsqlAliasNode* node = FB_NEW_POOL(dsqlScratch->getPool()) DsqlAliasNode(dsqlScratch->getPool(), name, doDsqlPass(dsqlScratch, value)); MAKE_desc(dsqlScratch, &node->value->nodDesc, node->value); return node; @@ -7426,9 +7457,9 @@ string DsqlMapNode::internalPrint(NodePrinter& printer) const return "DsqlMapNode"; } -ValueExprNode* DsqlMapNode::dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/) +ValueExprNode* DsqlMapNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) DsqlMapNode(getPool(), context, map); + return FB_NEW_POOL(dsqlScratch->getPool()) DsqlMapNode(dsqlScratch->getPool(), context, map); } bool DsqlMapNode::dsqlAggregateFinder(AggregateFinder& visitor) @@ -7570,10 +7601,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 = nodeAs(other); - 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); } @@ -7588,7 +7619,6 @@ DerivedFieldNode::DerivedFieldNode(MemoryPool& pool, const MetaName& aName, USHO value(aValue), context(NULL) { - addDsqlChildNode(value); } string DerivedFieldNode::internalPrint(NodePrinter& printer) const @@ -7792,11 +7822,9 @@ NegateNode::NegateNode(MemoryPool& pool, ValueExprNode* aArg) : TypedNode(pool), arg(aArg) { - addChildNode(arg, arg); - LiteralNode* literal = nodeAs(arg); if (literal && literal->litDesc.dsc_dtype == dtype_dec128) - literal->fixMinSInt64(); + literal->fixMinSInt64(pool); } DmlNode* NegateNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -7998,7 +8026,7 @@ dsc* NegateNode::execute(thread_db* tdbb, jrd_req* request) const ValueExprNode* NegateNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) NegateNode(getPool(), doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) NegateNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); } @@ -8086,7 +8114,6 @@ OrderNode::OrderNode(MemoryPool& pool, ValueExprNode* aValue) descending(false), nullsPlacement(NULLS_DEFAULT) { - addDsqlChildNode(value); } string OrderNode::internalPrint(NodePrinter& printer) const @@ -8102,15 +8129,16 @@ string OrderNode::internalPrint(NodePrinter& printer) const OrderNode* OrderNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - OrderNode* node = FB_NEW_POOL(getPool()) OrderNode(getPool(), doDsqlPass(dsqlScratch, value)); + OrderNode* node = FB_NEW_POOL(dsqlScratch->getPool()) OrderNode(dsqlScratch->getPool(), + doDsqlPass(dsqlScratch, value)); node->descending = descending; node->nullsPlacement = nullsPlacement; 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 = nodeAs(other); @@ -8122,9 +8150,9 @@ bool OrderNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const //-------------------- -bool WindowClause::Frame::sameAs(const ExprNode* other, bool ignoreStreams) const +bool WindowClause::Frame::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const Frame* const otherNode = nodeAs(other); @@ -8154,9 +8182,9 @@ WindowClause::Frame* WindowClause::Frame::copy(thread_db* tdbb, NodeCopier& copi //-------------------- -bool WindowClause::FrameExtent::sameAs(const ExprNode* other, bool ignoreStreams) const +bool WindowClause::FrameExtent::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const { - if (!ExprNode::sameAs(other, ignoreStreams)) + if (!ExprNode::sameAs(csb, other, ignoreStreams)) return false; const FrameExtent* const otherNode = nodeAs(other); @@ -8183,7 +8211,7 @@ WindowClause::FrameExtent* WindowClause::FrameExtent::dsqlPass(DsqlCompilerScrat } } - return FB_NEW_POOL(getPool()) FrameExtent(getPool(), unit, + return FB_NEW_POOL(dsqlScratch->getPool()) FrameExtent(dsqlScratch->getPool(), unit, doDsqlPass(dsqlScratch, frame1), doDsqlPass(dsqlScratch, frame2)); } @@ -8251,7 +8279,7 @@ WindowClause* WindowClause::dsqlPass(DsqlCompilerScratch* dsqlScratch) else window = this; - WindowClause* node = FB_NEW_POOL(getPool()) WindowClause(getPool(), + WindowClause* node = FB_NEW_POOL(dsqlScratch->getPool()) WindowClause(dsqlScratch->getPool(), window->name, doDsqlPass(dsqlScratch, window->partition), doDsqlPass(dsqlScratch, window->order), @@ -8315,8 +8343,6 @@ OverNode::OverNode(MemoryPool& pool, AggNode* aAggExpr, const MetaName* aWindowN windowName(aWindowName), window(NULL) { - addDsqlChildNode(aggExpr); - addDsqlChildNode(window); } OverNode::OverNode(MemoryPool& pool, AggNode* aAggExpr, WindowClause* aWindow) @@ -8325,8 +8351,6 @@ OverNode::OverNode(MemoryPool& pool, AggNode* aAggExpr, WindowClause* aWindow) windowName(NULL), window(aWindow) { - addDsqlChildNode(aggExpr); - addDsqlChildNode(window); } string OverNode::internalPrint(NodePrinter& printer) const @@ -8347,7 +8371,10 @@ bool OverNode::dsqlAggregateFinder(AggregateFinder& visitor) if (!wereWindow) { - for (auto& child : aggExpr->dsqlChildNodes) + NodeRefsHolder holder(visitor.getPool()); + aggExpr->getChildren(holder, true); + + for (auto& child : holder.refs) aggregate |= visitor.visit(child->getExpr()); } else @@ -8395,7 +8422,7 @@ ValueExprNode* OverNode::dsqlFieldRemapper(FieldRemapper& visitor) // Save the values to restore them in the end. AutoSetRestore autoWindowNode(&visitor.windowNode, visitor.windowNode); - if (Aggregate2Finder::find(visitor.context->ctx_scope_level, FIELD_MATCH_TYPE_EQUAL, + if (Aggregate2Finder::find(visitor.getPool(), visitor.context->ctx_scope_level, FIELD_MATCH_TYPE_EQUAL, true, window)) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << @@ -8407,9 +8434,12 @@ ValueExprNode* OverNode::dsqlFieldRemapper(FieldRemapper& visitor) // Before remap, aggExpr must always be an AggNode; AggNode* aggNode = static_cast(aggExpr.getObject()); - for (auto& child : aggNode->dsqlChildNodes) + NodeRefsHolder holder(visitor.getPool()); + aggNode->getChildren(holder, true); + + for (auto& child : holder.refs) { - if (Aggregate2Finder::find(visitor.context->ctx_scope_level, FIELD_MATCH_TYPE_EQUAL, + if (Aggregate2Finder::find(visitor.getPool(), visitor.context->ctx_scope_level, FIELD_MATCH_TYPE_EQUAL, true, child->getExpr())) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << @@ -8417,7 +8447,7 @@ ValueExprNode* OverNode::dsqlFieldRemapper(FieldRemapper& visitor) } } - AggregateFinder aggFinder(visitor.dsqlScratch, false); + AggregateFinder aggFinder(visitor.getPool(), visitor.dsqlScratch, false); aggFinder.deepestLevel = visitor.dsqlScratch->scopeLevel; aggFinder.currentLevel = visitor.currentLevel; @@ -8427,7 +8457,10 @@ ValueExprNode* OverNode::dsqlFieldRemapper(FieldRemapper& visitor) { AutoSetRestore autoWindowNode2(&visitor.windowNode, NULL); - for (auto& child : aggNode->dsqlChildNodes) + NodeRefsHolder holder(visitor.getPool()); + aggNode->getChildren(holder, true); + + for (auto& child : holder.refs) child->remap(visitor); doDsqlFieldRemapper(visitor, window); @@ -8494,7 +8527,7 @@ ValueExprNode* OverNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) else refWindow = window; - OverNode* node = FB_NEW_POOL(getPool()) OverNode(getPool(), + OverNode* node = FB_NEW_POOL(dsqlScratch->getPool()) OverNode(dsqlScratch->getPool(), static_cast(doDsqlPass(dsqlScratch, aggExpr)), doDsqlPass(dsqlScratch, refWindow)); const AggNode* aggNode = nodeAs(node->aggExpr); @@ -8505,7 +8538,7 @@ ValueExprNode* OverNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) (aggNode->getCapabilities() & AggNode::CAP_RESPECTS_WINDOW_FRAME) != AggNode::CAP_RESPECTS_WINDOW_FRAME) { - node->window->extent = WindowClause::FrameExtent::createDefault(getPool()); + node->window->extent = WindowClause::FrameExtent::createDefault(dsqlScratch->getPool()); node->window->exclusion = WindowClause::Exclusion::NO_OTHERS; } @@ -8530,8 +8563,6 @@ ParameterNode::ParameterNode(MemoryPool& pool) argIndicator(NULL), argInfo(NULL) { - addChildNode(argFlag); - addChildNode(argIndicator); } DmlNode* ParameterNode::parse(thread_db* /*tdbb*/, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -8605,7 +8636,7 @@ ValueExprNode* ParameterNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) dsql_msg* tempMsg = dsqlParameter ? dsqlParameter->par_message : dsqlScratch->getStatement()->getSendMsg(); - ParameterNode* node = FB_NEW_POOL(getPool()) ParameterNode(getPool()); + ParameterNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ParameterNode(dsqlScratch->getPool()); node->dsqlParameter = MAKE_parameter(tempMsg, true, true, dsqlParameterIndex, NULL); node->dsqlParameterIndex = dsqlParameterIndex; @@ -8755,7 +8786,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 = nodeAs(other); @@ -8924,7 +8955,6 @@ RecordKeyNode::RecordKeyNode(MemoryPool& pool, UCHAR aBlrOp, const MetaName& aDs aggregate(false) { fb_assert(blrOp == blr_dbkey || blrOp == blr_record_version || blrOp == blr_record_version2); - addDsqlChildNode(dsqlRelation); } DmlNode* RecordKeyNode::parse(thread_db* /*tdbb*/, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -8988,10 +9018,11 @@ ValueExprNode* RecordKeyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) PASS1_ambiguity_check(dsqlScratch, getAlias(true), contexts); - RelationSourceNode* relNode = FB_NEW_POOL(getPool()) RelationSourceNode(getPool()); + RelationSourceNode* relNode = FB_NEW_POOL(dsqlScratch->getPool()) RelationSourceNode( + dsqlScratch->getPool()); relNode->dsqlContext = context; - RecordKeyNode* node = FB_NEW_POOL(getPool()) RecordKeyNode(getPool(), blrOp); + RecordKeyNode* node = FB_NEW_POOL(dsqlScratch->getPool()) RecordKeyNode(dsqlScratch->getPool(), blrOp); node->dsqlRelation = relNode; return node; @@ -9023,10 +9054,11 @@ ValueExprNode* RecordKeyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (context->ctx_flags & CTX_null) return FB_NEW_POOL(*tdbb->getDefaultPool()) NullNode(*tdbb->getDefaultPool()); - RelationSourceNode* relNode = FB_NEW_POOL(getPool()) RelationSourceNode(getPool()); + RelationSourceNode* relNode = FB_NEW_POOL(dsqlScratch->getPool()) RelationSourceNode( + dsqlScratch->getPool()); relNode->dsqlContext = context; - RecordKeyNode* node = FB_NEW_POOL(getPool()) RecordKeyNode(getPool(), blrOp); + RecordKeyNode* node = FB_NEW_POOL(dsqlScratch->getPool()) RecordKeyNode(dsqlScratch->getPool(), blrOp); node->dsqlRelation = relNode; return node; @@ -9194,9 +9226,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 = nodeAs(other); @@ -9205,9 +9237,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 = nodeAs(other); @@ -9645,7 +9677,6 @@ StrCaseNode::StrCaseNode(MemoryPool& pool, UCHAR aBlrOp, ValueExprNode* aArg) blrOp(aBlrOp), arg(aArg) { - addChildNode(arg, arg); } DmlNode* StrCaseNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -9667,7 +9698,7 @@ string StrCaseNode::internalPrint(NodePrinter& printer) const ValueExprNode* StrCaseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) StrCaseNode(getPool(), blrOp, doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) StrCaseNode(dsqlScratch->getPool(), blrOp, doDsqlPass(dsqlScratch, arg)); } void StrCaseNode::setParameterName(dsql_par* parameter) const @@ -9722,9 +9753,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 = nodeAs(other); @@ -9733,9 +9764,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 = nodeAs(other); @@ -9839,7 +9870,6 @@ StrLenNode::StrLenNode(MemoryPool& pool, UCHAR aBlrSubOp, ValueExprNode* aArg) blrSubOp(aBlrSubOp), arg(aArg) { - addChildNode(arg, arg); } DmlNode* StrLenNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -9863,7 +9893,8 @@ string StrLenNode::internalPrint(NodePrinter& printer) const ValueExprNode* StrLenNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return FB_NEW_POOL(getPool()) StrLenNode(getPool(), blrSubOp, doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) StrLenNode(dsqlScratch->getPool(), + blrSubOp, doDsqlPass(dsqlScratch, arg)); } void StrLenNode::setParameterName(dsql_par* parameter) const @@ -9937,9 +9968,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 = nodeAs(other); @@ -9948,9 +9979,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 = nodeAs(other); @@ -10091,9 +10122,6 @@ SubQueryNode::SubQueryNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDs value2(aValue2), subQuery(NULL) { - addChildNode(dsqlRse, rse); - addChildNode(value1, value1); - addChildNode(value2, value2); } DmlNode* SubQueryNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp) @@ -10120,6 +10148,19 @@ DmlNode* SubQueryNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* return node; } +void SubQueryNode::getChildren(NodeRefsHolder& holder, bool dsql) const +{ + ValueExprNode::getChildren(holder, dsql); + + if (dsql) + holder.add(dsqlRse); + else + holder.add(rse); + + holder.add(value1); + holder.add(value2); +} + string SubQueryNode::internalPrint(NodePrinter& printer) const { ValueExprNode::internalPrint(printer); @@ -10147,8 +10188,8 @@ ValueExprNode* SubQueryNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) RseNode* rse = PASS1_rse(dsqlScratch, nodeAs(dsqlRse), false); - SubQueryNode* node = FB_NEW_POOL(getPool()) SubQueryNode(getPool(), blrOp, rse, - rse->dsqlSelectList->items[0], FB_NEW_POOL(getPool()) NullNode(getPool())); + SubQueryNode* node = FB_NEW_POOL(dsqlScratch->getPool()) SubQueryNode(dsqlScratch->getPool(), blrOp, rse, + rse->dsqlSelectList->items[0], FB_NEW_POOL(dsqlScratch->getPool()) NullNode(dsqlScratch->getPool())); // Finish off by cleaning up contexts. dsqlScratch->context->clear(base); @@ -10206,13 +10247,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, @@ -10350,7 +10391,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; } @@ -10596,9 +10637,6 @@ SubstringNode::SubstringNode(MemoryPool& pool, ValueExprNode* aExpr, ValueExprNo start(aStart), length(aLength) { - addChildNode(expr, expr); - addChildNode(start, start); - addChildNode(length, length); } DmlNode* SubstringNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, @@ -10624,7 +10662,7 @@ string SubstringNode::internalPrint(NodePrinter& printer) const ValueExprNode* SubstringNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - SubstringNode* node = FB_NEW_POOL(getPool()) SubstringNode(getPool(), + SubstringNode* node = FB_NEW_POOL(dsqlScratch->getPool()) SubstringNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, expr), doDsqlPass(dsqlScratch, start), doDsqlPass(dsqlScratch, length)); @@ -10933,9 +10971,6 @@ SubstringSimilarNode::SubstringSimilarNode(MemoryPool& pool, ValueExprNode* aExp pattern(aPattern), escape(aEscape) { - addChildNode(expr, expr); - addChildNode(pattern, pattern); - addChildNode(escape, escape); } DmlNode* SubstringSimilarNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, @@ -11138,7 +11173,7 @@ dsc* SubstringSimilarNode::execute(thread_db* tdbb, jrd_req* request) const ValueExprNode* SubstringSimilarNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - SubstringSimilarNode* node = FB_NEW_POOL(getPool()) SubstringSimilarNode(getPool(), + SubstringSimilarNode* node = FB_NEW_POOL(dsqlScratch->getPool()) SubstringSimilarNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, expr), doDsqlPass(dsqlScratch, pattern), doDsqlPass(dsqlScratch, escape)); @@ -11168,7 +11203,6 @@ SysFuncCallNode::SysFuncCallNode(MemoryPool& pool, const MetaName& aName, ValueL args(aArgs), function(NULL) { - addChildNode(args, args); } DmlNode* SysFuncCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, @@ -11273,9 +11307,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 = nodeAs(other); @@ -11283,9 +11317,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 = nodeAs(other); @@ -11319,11 +11353,11 @@ ValueExprNode* SysFuncCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (!dsqlSpecialSyntax && METD_get_function(dsqlScratch->getTransaction(), dsqlScratch, qualifName)) { - UdfCallNode* node = FB_NEW_POOL(getPool()) UdfCallNode(getPool(), qualifName, args); + UdfCallNode* node = FB_NEW_POOL(dsqlScratch->getPool()) UdfCallNode(dsqlScratch->getPool(), qualifName, args); return node->dsqlPass(dsqlScratch); } - SysFuncCallNode* node = FB_NEW_POOL(getPool()) SysFuncCallNode(getPool(), name, + SysFuncCallNode* node = FB_NEW_POOL(dsqlScratch->getPool()) SysFuncCallNode(dsqlScratch->getPool(), name, doDsqlPass(dsqlScratch, args)); node->dsqlSpecialSyntax = dsqlSpecialSyntax; @@ -11367,8 +11401,6 @@ TrimNode::TrimNode(MemoryPool& pool, UCHAR aWhere, ValueExprNode* aValue, ValueE value(aValue), trimChars(aTrimChars) { - addChildNode(value, value); - addChildNode(trimChars, trimChars); } DmlNode* TrimNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -11399,7 +11431,7 @@ string TrimNode::internalPrint(NodePrinter& printer) const ValueExprNode* TrimNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - TrimNode* node = FB_NEW_POOL(getPool()) TrimNode(getPool(), where, + TrimNode* node = FB_NEW_POOL(dsqlScratch->getPool()) TrimNode(dsqlScratch->getPool(), where, doDsqlPass(dsqlScratch, value), doDsqlPass(dsqlScratch, trimChars)); // Try to force trimChars to be same type as value: TRIM(? FROM FIELD) @@ -11504,9 +11536,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 = nodeAs(other); @@ -11515,9 +11547,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 = nodeAs(other); @@ -11711,7 +11743,6 @@ UdfCallNode::UdfCallNode(MemoryPool& pool, const QualifiedName& aName, ValueList dsqlFunction(NULL), isSubRoutine(false) { - addChildNode(args, args); } DmlNode* UdfCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, @@ -11874,9 +11905,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 = nodeAs(other); @@ -11884,9 +11915,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 = nodeAs(other); @@ -12174,7 +12205,7 @@ dsc* UdfCallNode::execute(thread_db* tdbb, jrd_req* request) const ValueExprNode* UdfCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - UdfCallNode* node = FB_NEW_POOL(getPool()) UdfCallNode(getPool(), name, + UdfCallNode* node = FB_NEW_POOL(dsqlScratch->getPool()) UdfCallNode(dsqlScratch->getPool(), name, doDsqlPass(dsqlScratch, args)); if (name.package.isEmpty()) @@ -12229,9 +12260,6 @@ ValueIfNode::ValueIfNode(MemoryPool& pool, BoolExprNode* aCondition, ValueExprNo trueValue(aTrueValue), falseValue(aFalseValue) { - addChildNode(condition, condition); - addChildNode(trueValue, trueValue); - addChildNode(falseValue, falseValue); } DmlNode* ValueIfNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/) @@ -12357,7 +12385,7 @@ string ValueIfNode::internalPrint(NodePrinter& printer) const ValueExprNode* ValueIfNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - ValueIfNode* node = FB_NEW_POOL(getPool()) ValueIfNode(getPool(), + ValueIfNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ValueIfNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, condition), doDsqlPass(dsqlScratch, trueValue), doDsqlPass(dsqlScratch, falseValue)); @@ -12482,7 +12510,7 @@ string VariableNode::internalPrint(NodePrinter& printer) const ValueExprNode* VariableNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - VariableNode* node = FB_NEW_POOL(getPool()) VariableNode(getPool()); + VariableNode* node = FB_NEW_POOL(dsqlScratch->getPool()) VariableNode(dsqlScratch->getPool()); node->dsqlName = dsqlName; node->dsqlVar = dsqlVar ? dsqlVar.getObject() : dsqlScratch->resolveVariable(dsqlName); @@ -12525,7 +12553,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 = nodeAs(other); if (!o) diff --git a/src/dsql/ExprNodes.h b/src/dsql/ExprNodes.h index b490a9c0b5..3aa8707fd5 100644 --- a/src/dsql/ExprNodes.h +++ b/src/dsql/ExprNodes.h @@ -47,6 +47,36 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(arg1); + holder.add(arg2); + } + + virtual const char* getCompatDialectVerb() + { + switch (blrOp) + { + case blr_add: + return "add"; + + case blr_subtract: + return "subtract"; + + case blr_multiply: + return "multiply"; + + case blr_divide: + return "divide"; + + default: + fb_assert(false); + return NULL; + } + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -57,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; @@ -145,6 +175,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(boolean); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -172,6 +208,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(source); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -182,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; @@ -205,11 +247,16 @@ public: : TypedNode(pool), args(aArgs) { - addChildNode(args, args); } static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(args); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -223,7 +270,7 @@ public: 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; } @@ -238,6 +285,14 @@ class CollateNode : public TypedNode public: CollateNode(MemoryPool& pool, ValueExprNode* aArg, const Firebird::MetaName& aCollation); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + if (dsql) + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -294,6 +349,13 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg1); + holder.add(arg2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -446,15 +508,20 @@ public: conditions(aConditions), values(aValues) { - addChildNode(test, test); - addChildNode(conditions, conditions); - addChildNode(values, values); - label = "DECODE"; } static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(test); + holder.add(conditions); + holder.add(values); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -493,7 +560,7 @@ public: 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 ValueExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); @@ -514,13 +581,18 @@ public: arg(NULL), internalStreamList(pool) { - addChildNode(arg); } static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); // This is a non-DSQL node. + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { ValueExprNode::internalPrint(printer); @@ -547,7 +619,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); @@ -604,6 +676,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -614,8 +692,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; @@ -648,21 +726,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; } @@ -708,6 +786,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -718,8 +802,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; @@ -752,6 +836,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -786,8 +876,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; @@ -797,7 +887,7 @@ public: return *reinterpret_cast(litDesc.dsc_address); } - void fixMinSInt64(); + void fixMinSInt64(MemoryPool& pool); public: const IntlString* dsqlStr; @@ -814,7 +904,12 @@ public: value(aValue), implicitJoin(NULL) { - addDsqlChildNode(value); + } + + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(value); } virtual Firebird::string internalPrint(NodePrinter& printer) const; @@ -866,7 +961,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*/) { @@ -897,6 +992,14 @@ public: DerivedFieldNode(MemoryPool& pool, const Firebird::MetaName& aName, USHORT aScope, ValueExprNode* aValue); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + if (dsql) + holder.add(value); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -943,6 +1046,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -995,9 +1104,15 @@ public: OrderNode(MemoryPool& pool, ValueExprNode* aValue); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + DsqlNode::getChildren(holder, dsql); + holder.add(value); + } + 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; public: NestConst value; @@ -1023,15 +1138,20 @@ public: }; public: - explicit Frame(MemoryPool& p, Bound aBound, ValueExprNode* aValue = NULL) - : TypedNode(p), + explicit Frame(MemoryPool& pool, Bound aBound, ValueExprNode* aValue = NULL) + : TypedNode(pool), bound(aBound), value(aValue) { - addChildNode(value, value); } public: + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ListExprNode::getChildren(holder, dsql); + holder.add(value); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { NODE_PRINT_ENUM(printer, bound); @@ -1042,7 +1162,7 @@ public: virtual Frame* dsqlPass(DsqlCompilerScratch* dsqlScratch) { - Frame* node = FB_NEW_POOL(getPool()) Frame(getPool(), bound, + Frame* node = FB_NEW_POOL(dsqlScratch->getPool()) Frame(dsqlScratch->getPool(), bound, doDsqlPass(dsqlScratch, value)); if (node->value) @@ -1056,9 +1176,9 @@ public: return node; } - bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const + bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ListExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ListExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const Frame* o = nodeAs(other); @@ -1073,7 +1193,7 @@ public: return this; } - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual Frame* pass1(thread_db* tdbb, CompilerScratch* csb); virtual Frame* pass2(thread_db* tdbb, CompilerScratch* csb); virtual Frame* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -1095,14 +1215,12 @@ public: }; public: - explicit FrameExtent(MemoryPool& p, Unit aUnit, Frame* aFrame1 = NULL, Frame* aFrame2 = NULL) - : TypedNode(p), + explicit FrameExtent(MemoryPool& pool, Unit aUnit, Frame* aFrame1 = NULL, Frame* aFrame2 = NULL) + : TypedNode(pool), unit(aUnit), frame1(aFrame1), frame2(aFrame2) { - addChildNode(frame1, frame1); - addChildNode(frame2, frame2); } static FrameExtent* createDefault(MemoryPool& p) @@ -1114,6 +1232,13 @@ public: } public: + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ListExprNode::getChildren(holder, dsql); + holder.add(frame1); + holder.add(frame2); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { NODE_PRINT_ENUM(printer, unit); @@ -1125,9 +1250,9 @@ public: virtual FrameExtent* dsqlPass(DsqlCompilerScratch* dsqlScratch); - bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const + bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!ListExprNode::dsqlMatch(other, ignoreMapCast)) + if (!ListExprNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const FrameExtent* o = nodeAs(other); @@ -1142,7 +1267,7 @@ public: return this; } - virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; + virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const; virtual FrameExtent* pass1(thread_db* tdbb, CompilerScratch* csb); virtual FrameExtent* pass2(thread_db* tdbb, CompilerScratch* csb); virtual FrameExtent* copy(thread_db* tdbb, NodeCopier& copier) const; @@ -1163,25 +1288,31 @@ public: }; public: - explicit WindowClause(MemoryPool& p, + explicit WindowClause(MemoryPool& pool, const Firebird::MetaName* aName = NULL, ValueListNode* aPartition = NULL, ValueListNode* aOrder = NULL, FrameExtent* aFrameExtent = NULL, Exclusion aExclusion = Exclusion::NO_OTHERS) - : DsqlNode(p), + : DsqlNode(pool), name(aName), partition(aPartition), order(aOrder), extent(aFrameExtent), exclusion(aExclusion) { - addDsqlChildNode(partition); - addDsqlChildNode(order); - addDsqlChildNode(extent); } public: + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(partition); + holder.add(order); + holder.add(extent); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { NODE_PRINT(printer, partition); @@ -1194,9 +1325,9 @@ public: virtual WindowClause* dsqlPass(DsqlCompilerScratch* dsqlScratch); - bool dsqlMatch(const ExprNode* other, bool ignoreMapCast) const + bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const { - if (!DsqlNode::dsqlMatch(other, ignoreMapCast)) + if (!DsqlNode::dsqlMatch(dsqlScratch, other, ignoreMapCast)) return false; const WindowClause* o = nodeAs(other); @@ -1239,6 +1370,17 @@ public: explicit OverNode(MemoryPool& pool, AggNode* aAggExpr, const Firebird::MetaName* aWindowName); explicit OverNode(MemoryPool& pool, AggNode* aAggExpr, WindowClause* aWindow); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + if (dsql) + { + holder.add(aggExpr); + holder.add(window); + } + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -1275,6 +1417,17 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + if (!dsql) + { + holder.add(argFlag); + holder.add(argIndicator); + } + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -1286,7 +1439,7 @@ public: const dsc* desc, 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; @@ -1311,6 +1464,14 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + if (dsql) + holder.add(dsqlRelation); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -1324,12 +1485,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); @@ -1343,8 +1504,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; @@ -1382,14 +1543,20 @@ public: field(NULL), subscripts(NULL) { - addChildNode(field); - addChildNode(subscripts); } static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); // This is a non-DSQL node. + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(field); + holder.add(subscripts); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { ValueExprNode::internalPrint(printer); @@ -1434,14 +1601,20 @@ public: stmt(NULL), expr(NULL) { - // Do not add the statement. We'll manually handle it in pass1 and pass2. - addChildNode(expr); } static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); // This is a non-DSQL node. + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + // Do not add the statement. We'll manually handle it in pass1 and pass2. + holder.add(expr); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const { ValueExprNode::internalPrint(printer); @@ -1486,6 +1659,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1496,8 +1675,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; @@ -1514,6 +1693,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1524,8 +1709,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; @@ -1544,6 +1729,8 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const; + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1556,17 +1743,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); @@ -1576,7 +1763,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; @@ -1600,6 +1787,15 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(expr); + holder.add(start); + holder.add(length); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1631,6 +1827,15 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(expr); + holder.add(pattern); + holder.add(escape); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1660,6 +1865,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(args); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1668,8 +1879,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; @@ -1689,6 +1900,14 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(value); + holder.add(trimChars); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1699,8 +1918,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; @@ -1726,21 +1945,27 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(args); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; 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,6 +1989,15 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + + holder.add(condition); + holder.add(trueValue); + holder.add(falseValue); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void setParameterName(dsql_par* parameter) const; @@ -1772,7 +2006,7 @@ public: virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); - virtual bool possiblyUnknown() + virtual bool possiblyUnknown(OptimizerBlk* /*opt*/) { return true; } @@ -1801,7 +2035,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 0ac8082988..6a1fc18666 100644 --- a/src/dsql/Nodes.h +++ b/src/dsql/Nodes.h @@ -38,6 +38,7 @@ class Cursor; class Node; class NodePrinter; class ExprNode; +class NodeRefsHolder; class OptimizerBlk; class OptimizerRetrieval; class RecordSource; @@ -101,12 +102,11 @@ public: }; -class Node : public Firebird::PermanentStorage, public Printable +class Node : public Printable { public: explicit Node(MemoryPool& pool) - : PermanentStorage(pool), - line(0), + : line(0), column(0) { } @@ -153,6 +153,10 @@ public: virtual Firebird::string internalPrint(NodePrinter& printer) const = 0; + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + } + virtual Node* dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/) { return this; @@ -316,9 +320,8 @@ public: KIND_LIST }; - explicit DmlNode(MemoryPool& pool, Kind aKind) - : Node(pool), - kind(aKind) + explicit DmlNode(MemoryPool& pool) + : Node(pool) { } @@ -332,13 +335,11 @@ public: } public: + virtual Kind getKind() = 0; virtual void genBlr(DsqlCompilerScratch* dsqlScratch) = 0; virtual DmlNode* pass1(thread_db* tdbb, CompilerScratch* csb) = 0; virtual DmlNode* pass2(thread_db* tdbb, CompilerScratch* csb) = 0; virtual DmlNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0; - -public: - const Kind kind; }; @@ -438,6 +439,28 @@ private: T** ptr; }; +class NodeRefsHolder : public Firebird::PermanentStorage +{ +public: + NodeRefsHolder(MemoryPool& pool) + : PermanentStorage(pool), + refs(pool) + { + } + + ~NodeRefsHolder() + { + for (auto& ref : refs) + delete ref; + } + +public: + template void add(const NestConst& node); + +public: + Firebird::HalfStaticArray refs; +}; + class ExprNode : public DmlNode { @@ -528,17 +551,19 @@ public: static const unsigned FLAG_VALUE = 0x80; // Full value area required in impure space. static const unsigned FLAG_DECFIXED = 0x100; - explicit ExprNode(Type aType, MemoryPool& pool, Kind aKind) - : DmlNode(pool, aKind), + explicit ExprNode(Type aType, MemoryPool& pool) + : DmlNode(pool), type(aType), nodFlags(0), - impureOffset(0), - dsqlCompatDialectVerb(NULL), - dsqlChildNodes(pool), - jrdChildNodes(pool) + impureOffset(0) { } + virtual const char* getCompatDialectVerb() + { + return NULL; + } + // Allocate and assign impure space for various nodes. template static void doPass2(thread_db* tdbb, CompilerScratch* csb, T** node) { @@ -554,7 +579,10 @@ public: { bool ret = false; - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) ret |= visitor.visit((*i)->getExpr()); return ret; @@ -564,7 +592,10 @@ public: { bool ret = false; - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) ret |= visitor.visit((*i)->getExpr()); return ret; @@ -574,7 +605,10 @@ public: { bool ret = false; - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) ret |= visitor.visit((*i)->getExpr()); return ret; @@ -584,7 +618,10 @@ public: { bool ret = false; - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.dsqlScratch->getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) ret |= visitor.visit((*i)->getExpr()); return ret; @@ -594,7 +631,10 @@ public: { bool ret = false; - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) ret |= visitor.visit((*i)->getExpr()); return ret; @@ -602,7 +642,10 @@ public: virtual ExprNode* dsqlFieldRemapper(FieldRemapper& visitor) { - for (NodeRef* const* i = dsqlChildNodes.begin(); i != dsqlChildNodes.end(); ++i) + NodeRefsHolder holder(visitor.getPool()); + getChildren(holder, true); + + for (NodeRef* const* i = holder.refs.begin(); i != holder.refs.end(); ++i) (*i)->remap(visitor); return this; @@ -622,48 +665,23 @@ public: } // Check if expression could return NULL or expression can turn NULL into a true/false. - virtual bool possiblyUnknown() - { - for (NodeRef** i = jrdChildNodes.begin(); i != jrdChildNodes.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) - { - for (NodeRef** i = jrdChildNodes.begin(); i != jrdChildNodes.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 - { - for (const NodeRef* const* i = jrdChildNodes.begin(); i != jrdChildNodes.end(); ++i) - { - if (**i) - (*i)->getExpr()->collectStreams(streamList); - } - } + virtual void collectStreams(CompilerScratch* csb, SortedStreamList& streamList) const; - 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) { @@ -672,7 +690,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 @@ -687,33 +705,10 @@ public: virtual ExprNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual ExprNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0; -protected: - template - void addChildNode(NestConst& dsqlNode, NestConst& jrdNode) - { - addDsqlChildNode(dsqlNode); - addChildNode(jrdNode); - } - - template - void addDsqlChildNode(NestConst& dsqlNode) - { - dsqlChildNodes.add(FB_NEW_POOL(getPool()) NodeRefImpl(dsqlNode.getAddress())); - } - - template - void addChildNode(NestConst& jrdNode) - { - jrdChildNodes.add(FB_NEW_POOL(getPool()) NodeRefImpl(jrdNode.getAddress())); - } - public: const Type type; unsigned nodFlags; ULONG impureOffset; - const char* dsqlCompatDialectVerb; - Firebird::Array dsqlChildNodes; - Firebird::Array jrdChildNodes; }; @@ -749,14 +744,26 @@ inline void NodeRefImpl::internalPass2(thread_db* tdbb, CompilerScratch* csb) } +template +inline void NodeRefsHolder::add(const NestConst& node) +{ + refs.add(FB_NEW_POOL(getPool()) NodeRefImpl(const_cast(node.getAddress()))); +} + + class BoolExprNode : public ExprNode { public: BoolExprNode(Type aType, MemoryPool& pool) - : ExprNode(aType, pool, KIND_BOOLEAN) + : ExprNode(aType, pool) { } + virtual Kind getKind() + { + return KIND_BOOLEAN; + } + virtual BoolExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { ExprNode::dsqlPass(dsqlScratch); @@ -793,7 +800,7 @@ class ValueExprNode : public ExprNode { public: ValueExprNode(Type aType, MemoryPool& pool) - : ExprNode(aType, pool, KIND_VALUE), + : ExprNode(aType, pool), nodScale(0) { nodDesc.clear(); @@ -802,6 +809,11 @@ public: public: virtual Firebird::string internalPrint(NodePrinter& printer) const = 0; + virtual Kind getKind() + { + return KIND_VALUE; + } + virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { ExprNode::dsqlPass(dsqlScratch); @@ -1011,6 +1023,12 @@ public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp); + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ValueExprNode::getChildren(holder, dsql); + holder.add(arg); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const = 0; virtual bool dsqlAggregateFinder(AggregateFinder& visitor); @@ -1019,7 +1037,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); @@ -1031,19 +1049,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; } @@ -1074,10 +1092,10 @@ protected: public: const AggInfo& aggInfo; - bool distinct; - bool dialect1; NestConst arg; const AggregateSort* asb; + bool distinct; + bool dialect1; bool indexed; private: @@ -1115,13 +1133,18 @@ public: static const unsigned DFLAG_CURSOR = 0x40; RecordSourceNode(Type aType, MemoryPool& pool) - : ExprNode(aType, pool, KIND_REC_SOURCE), + : ExprNode(aType, pool), dsqlFlags(0), dsqlContext(NULL), stream(INVALID_STREAM) { } + virtual Kind getKind() + { + return KIND_REC_SOURCE; + } + virtual StreamType getStream() const { return stream; @@ -1159,23 +1182,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; } @@ -1204,10 +1227,15 @@ class ListExprNode : public ExprNode { public: ListExprNode(Type aType, MemoryPool& pool) - : ExprNode(aType, pool, KIND_LIST) + : ExprNode(aType, pool) { } + virtual Kind getKind() + { + return KIND_LIST; + } + virtual void genBlr(DsqlCompilerScratch* /*dsqlScratch*/) { fb_assert(false); @@ -1220,57 +1248,52 @@ class ValueListNode : public TypedNode public: ValueListNode(MemoryPool& pool, unsigned count) : TypedNode(pool), - items(pool, INITIAL_CAPACITY), - itemsBegin(items.begin()) + items(pool, INITIAL_CAPACITY) { items.resize(count); for (unsigned i = 0; i < count; ++i) - { items[i] = NULL; - addChildNode(items[i], items[i]); - } } ValueListNode(MemoryPool& pool, ValueExprNode* arg1) : TypedNode(pool), - items(pool, INITIAL_CAPACITY), - itemsBegin(items.begin()) + items(pool, INITIAL_CAPACITY) { - items.resize(1); - addDsqlChildNode((items[0] = arg1)); + items.push(arg1); + } + + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ListExprNode::getChildren(holder, dsql); + + for (auto& item : items) + holder.add(item); } ValueListNode* add(ValueExprNode* argn) { - FB_SIZE_T pos = items.add(argn); - - if (invalidated()) - resetChildNodes(); - else - addChildNode(items[pos], items[pos]); - + items.add(argn); return this; } ValueListNode* addFront(ValueExprNode* argn) { items.insert(0, argn); - resetChildNodes(); return this; } void clear() { items.clear(); - resetChildNodes(); } virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual ValueListNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { - ValueListNode* node = FB_NEW_POOL(getPool()) ValueListNode(getPool(), items.getCount()); + ValueListNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ValueListNode(dsqlScratch->getPool(), + items.getCount()); NestConst* dst = node->items.begin(); @@ -1311,28 +1334,8 @@ public: return node; } -private: - bool invalidated() - { - bool ret = items.begin() != itemsBegin; - itemsBegin = items.begin(); - return ret; - } - - void resetChildNodes() - { - dsqlChildNodes.clear(); - jrdChildNodes.clear(); - - for (FB_SIZE_T i = 0; i < items.getCount(); ++i) - addChildNode(items[i], items[i]); - - itemsBegin = items.begin(); - } - public: NestValueArray items; - NestConst* itemsBegin; private: static const unsigned INITIAL_CAPACITY = 4; @@ -1348,10 +1351,17 @@ public: RecSourceListNode* add(RecordSourceNode* argn) { items.add(argn); - resetChildNodes(); return this; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + ListExprNode::getChildren(holder, dsql); + + for (auto& item : items) + holder.add(item); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual RecSourceListNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); @@ -1380,15 +1390,6 @@ public: return NULL; } -private: - void resetChildNodes() - { - dsqlChildNodes.clear(); - - for (FB_SIZE_T i = 0; i < items.getCount(); ++i) - addDsqlChildNode(items[i]); - } - public: Firebird::Array > items; }; @@ -1493,7 +1494,7 @@ public: public: explicit StmtNode(Type aType, MemoryPool& pool) - : DmlNode(pool, KIND_STATEMENT), + : DmlNode(pool), type(aType), parentStmt(NULL), impureOffset(0), @@ -1544,6 +1545,11 @@ public: *node = (*node)->pass2(tdbb, csb); } + virtual Kind getKind() + { + return KIND_STATEMENT; + } + virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { DmlNode::dsqlPass(dsqlScratch); @@ -1640,12 +1646,11 @@ struct ScaledNumber }; -class RowsClause : public Firebird::PermanentStorage, public Printable +class RowsClause : public Printable { public: explicit RowsClause(MemoryPool& pool) - : PermanentStorage(pool), - length(NULL), + : length(NULL), skip(NULL) { } @@ -1689,8 +1694,8 @@ typedef Firebird::Array StreamMap; class SubExprNodeCopier : private StreamMap, public NodeCopier { public: - SubExprNodeCopier(CompilerScratch* aCsb) - : NodeCopier(aCsb, getBuffer(STREAM_MAP_LENGTH)) + SubExprNodeCopier(Firebird::MemoryPool& pool, CompilerScratch* aCsb) + : NodeCopier(pool, aCsb, getBuffer(STREAM_MAP_LENGTH)) { // Initialize the map so all streams initially resolve to the original number. // As soon as copy creates new streams, the map is being overwritten. diff --git a/src/dsql/PackageNodes.epp b/src/dsql/PackageNodes.epp index a00c92f036..95752ff78e 100644 --- a/src/dsql/PackageNodes.epp +++ b/src/dsql/PackageNodes.epp @@ -214,15 +214,17 @@ string CreateAlterPackageNode::internalPrint(NodePrinter& printer) const DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { + MemoryPool& pool = dsqlScratch->getPool(); + source.ltrim("\n\r\t "); // items for (unsigned i = 0; i < items->getCount(); ++i) { - DsqlCompiledStatement* itemStatement = FB_NEW_POOL(getPool()) DsqlCompiledStatement(getPool()); + DsqlCompiledStatement* itemStatement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool); DsqlCompilerScratch* itemScratch = (*items)[i].dsqlScratch = - FB_NEW_POOL(getPool()) DsqlCompilerScratch(getPool(), dsqlScratch->getAttachment(), + FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), itemStatement); itemScratch->clientDialect = dsqlScratch->clientDialect; @@ -372,6 +374,7 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { + MemoryPool& pool = dsqlScratch->getPool(); Attachment* attachment = transaction->getAttachment(); AutoCacheRequest requestHandle(tdbb, drq_m_pkg, DYN_REQUESTS); bool modified = false; @@ -385,8 +388,8 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_PACKAGE, name, NULL); - SortedObjectsArray existingFuncs(getPool()); - SortedObjectsArray existingProcs(getPool()); + SortedObjectsArray existingFuncs(pool); + SortedObjectsArray existingProcs(pool); collectPackagedItems(tdbb, transaction, name, existingFuncs, existingProcs, false); for (SortedObjectsArray::iterator i = existingFuncs.begin(); @@ -394,7 +397,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* { if (!functionNames.exist(i->name)) { - DropFunctionNode dropNode(getPool(), i->name); + DropFunctionNode dropNode(pool, i->name); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); @@ -406,7 +409,7 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* { if (!procedureNames.exist(i->name)) { - DropProcedureNode dropNode(getPool(), i->name); + DropProcedureNode dropNode(pool, i->name); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); @@ -496,6 +499,8 @@ bool DropPackageNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { + MemoryPool& pool = dsqlScratch->getPool(); + // run all statements under savepoint control AutoSavePoint savePoint(tdbb, transaction); @@ -530,14 +535,14 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name)); } - SortedObjectsArray existingFuncs(getPool()); - SortedObjectsArray existingProcs(getPool()); + SortedObjectsArray existingFuncs(pool); + SortedObjectsArray existingProcs(pool); collectPackagedItems(tdbb, transaction, name, existingFuncs, existingProcs, false); for (SortedObjectsArray::iterator i = existingFuncs.begin(); i != existingFuncs.end(); ++i) { - DropFunctionNode dropNode(getPool(), i->name); + DropFunctionNode dropNode(pool, i->name); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); @@ -546,7 +551,7 @@ void DropPackageNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, for (SortedObjectsArray::iterator i = existingProcs.begin(); i != existingProcs.end(); ++i) { - DropProcedureNode dropNode(getPool(), i->name); + DropProcedureNode dropNode(pool, i->name); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); @@ -593,6 +598,8 @@ string CreatePackageBodyNode::internalPrint(NodePrinter& printer) const DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { + MemoryPool& pool = dsqlScratch->getPool(); + source.ltrim("\n\r\t "); // process declaredItems and items @@ -607,10 +614,10 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) for (unsigned j = 0; j < arrays[i]->getCount(); ++j) { - DsqlCompiledStatement* itemStatement = FB_NEW_POOL(getPool()) DsqlCompiledStatement(getPool()); + DsqlCompiledStatement* itemStatement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool); DsqlCompilerScratch* itemScratch = (*arrays[i])[j].dsqlScratch = - FB_NEW_POOL(getPool()) DsqlCompilerScratch(getPool(), dsqlScratch->getAttachment(), + FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), itemStatement); itemScratch->clientDialect = dsqlScratch->clientDialect; @@ -686,6 +693,7 @@ bool CreatePackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transactio void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { + MemoryPool& pool = dsqlScratch->getPool(); Attachment* attachment = transaction->getAttachment(); // run all statements under savepoint control @@ -729,12 +737,12 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc Arg::Gds(isc_dyn_package_not_found) << Arg::Str(name)); } - SortedObjectsArray headerFuncs(getPool()); - SortedObjectsArray headerProcs(getPool()); + SortedObjectsArray headerFuncs(pool); + SortedObjectsArray headerProcs(pool); collectPackagedItems(tdbb, transaction, name, headerFuncs, headerProcs, false); - SortedObjectsArray existingFuncs(getPool()); - SortedObjectsArray existingProcs(getPool()); + SortedObjectsArray existingFuncs(pool); + SortedObjectsArray existingProcs(pool); // process declaredItems and items Array* arrays[] = {declaredItems, items}; @@ -803,15 +811,15 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc } } - SortedObjectsArray newFuncs(getPool()); - SortedObjectsArray newProcs(getPool()); + SortedObjectsArray newFuncs(pool); + SortedObjectsArray newProcs(pool); collectPackagedItems(tdbb, transaction, name, newFuncs, newProcs, true); for (SortedObjectsArray::iterator i = existingFuncs.begin(); i != existingFuncs.end(); ++i) { FB_SIZE_T pos; - bool found = newFuncs.find(Signature(getPool(), i->name), pos); + bool found = newFuncs.find(Signature(pool, i->name), pos); if (!found || !newFuncs[pos].defined) { @@ -829,7 +837,7 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc i != existingProcs.end(); ++i) { FB_SIZE_T pos; - bool found = newProcs.find(Signature(getPool(), i->name), pos); + bool found = newProcs.find(Signature(pool, i->name), pos); if (!found || !newProcs[pos].defined) { @@ -876,6 +884,8 @@ bool DropPackageBodyNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { + MemoryPool& pool = dsqlScratch->getPool(); + // run all statements under savepoint control AutoSavePoint savePoint(tdbb, transaction); @@ -918,7 +928,7 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra { if (!FUN.RDB$PRIVATE_FLAG.NULL && FUN.RDB$PRIVATE_FLAG != 0) { - DropFunctionNode dropNode(getPool(), FUN.RDB$FUNCTION_NAME); + DropFunctionNode dropNode(pool, FUN.RDB$FUNCTION_NAME); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); @@ -945,7 +955,7 @@ void DropPackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra { if (!PRC.RDB$PRIVATE_FLAG.NULL && PRC.RDB$PRIVATE_FLAG != 0) { - DropProcedureNode dropNode(getPool(), PRC.RDB$PROCEDURE_NAME); + DropProcedureNode dropNode(pool, PRC.RDB$PROCEDURE_NAME); dropNode.package = name; dropNode.dsqlPass(dsqlScratch); dropNode.executeDdl(tdbb, dsqlScratch, transaction); diff --git a/src/dsql/Parser.h b/src/dsql/Parser.h index 447c8ecd02..cd73ce1980 100644 --- a/src/dsql/Parser.h +++ b/src/dsql/Parser.h @@ -231,6 +231,11 @@ private: return cmpNode; } + MemoryPool& getStatementPool() + { + return scratch->getStatement()->getPool(); + } + void yyReducePosn(YYPOSN& ret, YYPOSN* termPosns, YYSTYPE* termVals, int termNo, int stkPos, int yychar, YYPOSN& yyposn, void*); diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index 6bc840ddac..eea880be6a 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -78,8 +78,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, @@ -108,7 +108,7 @@ namespace { public: RemapFieldNodeCopier(CompilerScratch* aCsb, StreamType* aRemap, USHORT aFldId) - : NodeCopier(aCsb, aRemap), + : NodeCopier(aCsb->csb_pool, aCsb, aRemap), fldId(aFldId) { } @@ -328,7 +328,7 @@ void AssignmentNode::dsqlValidateTarget(const ValueExprNode* target) AssignmentNode* AssignmentNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - AssignmentNode* node = FB_NEW_POOL(getPool()) AssignmentNode(getPool()); + AssignmentNode* node = FB_NEW_POOL(dsqlScratch->getPool()) AssignmentNode(dsqlScratch->getPool()); node->asgnFrom = doDsqlPass(dsqlScratch, asgnFrom); node->asgnTo = doDsqlPass(dsqlScratch, asgnTo); @@ -460,12 +460,12 @@ StmtNode* BlockNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { if (!handlers && !dsqlScratch->errorHandlers) { - CompoundStmtNode* node = FB_NEW_POOL(getPool()) CompoundStmtNode(getPool()); + CompoundStmtNode* node = FB_NEW_POOL(dsqlScratch->getPool()) CompoundStmtNode(dsqlScratch->getPool()); node->statements.add(action->dsqlPass(dsqlScratch)); return node; } - BlockNode* node = FB_NEW_POOL(getPool()) BlockNode(getPool()); + BlockNode* node = FB_NEW_POOL(dsqlScratch->getPool()) BlockNode(dsqlScratch->getPool()); if (handlers) ++dsqlScratch->errorHandlers; @@ -800,7 +800,7 @@ CompoundStmtNode* CompoundStmtNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_dsql_max_nesting) << Arg::Num(DsqlCompilerScratch::MAX_NESTING)); } - CompoundStmtNode* node = FB_NEW_POOL(getPool()) CompoundStmtNode(getPool()); + CompoundStmtNode* node = FB_NEW_POOL(dsqlScratch->getPool()) CompoundStmtNode(dsqlScratch->getPool()); for (NestConst* i = statements.begin(); i != statements.end(); ++i) { @@ -1261,7 +1261,7 @@ DeclareCursorNode* DeclareCursorNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) // Make sure the cursor doesn't exist. PASS1_cursor_name(dsqlScratch, dsqlName, CUR_TYPE_ALL, false); - SelectExprNode* dt = FB_NEW_POOL(getPool()) SelectExprNode(getPool()); + SelectExprNode* dt = FB_NEW_POOL(dsqlScratch->getPool()) SelectExprNode(dsqlScratch->getPool()); dt->dsqlFlags = RecordSourceNode::DFLAG_DERIVED | RecordSourceNode::DFLAG_CURSOR; dt->querySpec = dsqlSelect->dsqlExpr; dt->alias = dsqlName.c_str(); @@ -1516,7 +1516,7 @@ string DeclareSubFuncNode::internalPrint(NodePrinter& printer) const DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - MemoryPool& pool = getPool(); + MemoryPool& pool = dsqlScratch->getPool(); if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE) ERR_post(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) << "nested sub function"); @@ -1856,7 +1856,7 @@ string DeclareSubProcNode::internalPrint(NodePrinter& printer) const DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - MemoryPool& pool = getPool(); + MemoryPool& pool = dsqlScratch->getPool(); if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE) ERR_post(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) << "nested sub procedure"); @@ -2183,7 +2183,7 @@ StmtNode* EraseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) NestConst relation = dsqlRelation; - EraseNode* node = FB_NEW_POOL(getPool()) EraseNode(getPool()); + EraseNode* node = FB_NEW_POOL(dsqlScratch->getPool()) EraseNode(dsqlScratch->getPool()); if (dsqlCursorName.hasData() && dsqlScratch->isPsql()) { @@ -2198,7 +2198,7 @@ StmtNode* EraseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) --dsqlScratch->scopeLevel; dsqlScratch->context->pop(); - return SavepointEncloseNode::make(getPool(), dsqlScratch, node); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, node); } dsqlScratch->getStatement()->setType(dsqlCursorName.hasData() ? @@ -2212,9 +2212,9 @@ StmtNode* EraseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) rse = dsqlPassCursorReference(dsqlScratch, dsqlCursorName, relation); else { - rse = FB_NEW_POOL(getPool()) RseNode(getPool()); + rse = FB_NEW_POOL(dsqlScratch->getPool()) RseNode(dsqlScratch->getPool()); - rse->dsqlStreams = FB_NEW_POOL(getPool()) RecSourceListNode(getPool(), 1); + rse->dsqlStreams = FB_NEW_POOL(dsqlScratch->getPool()) RecSourceListNode(dsqlScratch->getPool(), 1); doDsqlPass(dsqlScratch, rse->dsqlStreams->items[0], relation, false); if (dsqlBoolean) @@ -2242,7 +2242,7 @@ StmtNode* EraseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) dsqlScratch->context->pop(); - return SavepointEncloseNode::make(getPool(), dsqlScratch, ret); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, ret); } string EraseNode::internalPrint(NodePrinter& printer) const @@ -2630,7 +2630,7 @@ DmlNode* ErrorHandlerNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScra ErrorHandlerNode* ErrorHandlerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - ErrorHandlerNode* node = FB_NEW_POOL(getPool()) ErrorHandlerNode(getPool()); + ErrorHandlerNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ErrorHandlerNode(dsqlScratch->getPool()); node->conditions = conditions; node->action = action->dsqlPass(dsqlScratch); return node; @@ -2811,7 +2811,7 @@ ExecProcedureNode* ExecProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (!dsqlScratch->isPsql()) dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_EXEC_PROCEDURE); - ExecProcedureNode* node = FB_NEW_POOL(getPool()) ExecProcedureNode(getPool(), dsqlName); + ExecProcedureNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ExecProcedureNode(dsqlScratch->getPool(), dsqlName); node->dsqlProcedure = procedure; if (node->dsqlName.package.isEmpty() && procedure->prc_name.package.hasData()) @@ -2887,14 +2887,14 @@ ValueListNode* ExecProcedureNode::explodeOutputs(DsqlCompilerScratch* dsqlScratc DEV_BLKCHK(procedure, dsql_type_prc); const USHORT count = procedure->prc_out_count; - ValueListNode* output = FB_NEW_POOL(getPool()) ValueListNode(getPool(), count); + ValueListNode* output = FB_NEW_POOL(dsqlScratch->getPool()) ValueListNode(dsqlScratch->getPool(), count); NestConst* ptr = output->items.begin(); for (const dsql_fld* field = procedure->prc_outputs; field; field = field->fld_next, ++ptr) { DEV_BLKCHK(field, dsql_type_fld); - ParameterNode* paramNode = FB_NEW_POOL(getPool()) ParameterNode(getPool()); + ParameterNode* paramNode = FB_NEW_POOL(dsqlScratch->getPool()) ParameterNode(dsqlScratch->getPool()); *ptr = paramNode; dsql_par* parameter = paramNode->dsqlParameter = MAKE_parameter( @@ -3293,7 +3293,7 @@ DmlNode* ExecStatementNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr StmtNode* ExecStatementNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - ExecStatementNode* node = FB_NEW_POOL(getPool()) ExecStatementNode(getPool()); + ExecStatementNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ExecStatementNode(dsqlScratch->getPool()); node->sql = doDsqlPass(dsqlScratch, sql); node->inputs = doDsqlPass(dsqlScratch, inputs); @@ -3351,7 +3351,7 @@ StmtNode* ExecStatementNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) node->traScope = traScope; node->useCallerPrivs = useCallerPrivs; - return SavepointEncloseNode::make(getPool(), dsqlScratch, node); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, node); } string ExecStatementNode::internalPrint(NodePrinter& printer) const @@ -3662,7 +3662,7 @@ DmlNode* IfNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, IfNode* IfNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - IfNode* node = FB_NEW_POOL(getPool()) IfNode(getPool()); + IfNode* node = FB_NEW_POOL(dsqlScratch->getPool()) IfNode(dsqlScratch->getPool()); node->condition = doDsqlPass(dsqlScratch, condition); node->trueAction = trueAction->dsqlPass(dsqlScratch); if (falseAction) @@ -3755,7 +3755,8 @@ InAutonomousTransactionNode* InAutonomousTransactionNode::dsqlPass(DsqlCompilerS const bool autoTrans = dsqlScratch->flags & DsqlCompilerScratch::FLAG_IN_AUTO_TRANS_BLOCK; dsqlScratch->flags |= DsqlCompilerScratch::FLAG_IN_AUTO_TRANS_BLOCK; - InAutonomousTransactionNode* node = FB_NEW_POOL(getPool()) InAutonomousTransactionNode(getPool()); + InAutonomousTransactionNode* node = FB_NEW_POOL(dsqlScratch->getPool()) InAutonomousTransactionNode( + dsqlScratch->getPool()); node->action = action->dsqlPass(dsqlScratch); if (!autoTrans) @@ -4047,7 +4048,7 @@ ExecBlockNode* ExecBlockNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) dsqlScratch->flags |= DsqlCompilerScratch::FLAG_BLOCK; - ExecBlockNode* node = FB_NEW_POOL(getPool()) ExecBlockNode(getPool()); + ExecBlockNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ExecBlockNode(dsqlScratch->getPool()); for (NestConst* param = parameters.begin(); param != parameters.end(); ++param) { @@ -4369,13 +4370,13 @@ StmtNode* ExceptionNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Num(MsgFormat::SAFEARG_MAX_ARG)); } - ExceptionNode* node = FB_NEW_POOL(getPool()) ExceptionNode(getPool()); + ExceptionNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ExceptionNode(dsqlScratch->getPool()); if (exception) - node->exception = FB_NEW_POOL(getPool()) ExceptionItem(getPool(), *exception); + node->exception = FB_NEW_POOL(dsqlScratch->getPool()) ExceptionItem(dsqlScratch->getPool(), *exception); node->messageExpr = doDsqlPass(dsqlScratch, messageExpr); node->parameters = doDsqlPass(dsqlScratch, parameters); - return SavepointEncloseNode::make(getPool(), dsqlScratch, node); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, node); } string ExceptionNode::internalPrint(NodePrinter& printer) const @@ -4654,7 +4655,7 @@ DmlNode* ForNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, ForNode* ForNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - ForNode* node = FB_NEW_POOL(getPool()) ForNode(getPool()); + ForNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ForNode(dsqlScratch->getPool()); node->dsqlCursor = dsqlCursor; @@ -4665,7 +4666,7 @@ ForNode* ForNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) fb_assert(dsqlCursor->dsqlCursorType != DeclareCursorNode::CUR_TYPE_NONE); PASS1_cursor_name(dsqlScratch, dsqlCursor->dsqlName, DeclareCursorNode::CUR_TYPE_ALL, false); - SelectExprNode* dt = FB_NEW_POOL(getPool()) SelectExprNode(getPool()); + SelectExprNode* dt = FB_NEW_POOL(dsqlScratch->getPool()) SelectExprNode(dsqlScratch->getPool()); dt->dsqlFlags = RecordSourceNode::DFLAG_DERIVED | RecordSourceNode::DFLAG_CURSOR; dt->querySpec = dsqlSelect->dsqlExpr; dt->alias = dsqlCursor->dsqlName.c_str(); @@ -5052,7 +5053,7 @@ DmlNode* LoopNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb LoopNode* LoopNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - LoopNode* node = FB_NEW_POOL(getPool()) LoopNode(getPool()); + LoopNode* node = FB_NEW_POOL(dsqlScratch->getPool()) LoopNode(dsqlScratch->getPool()); node->dsqlExpr = doDsqlPass(dsqlScratch, dsqlExpr); @@ -5261,7 +5262,7 @@ StmtNode* MergeNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) } } - SelectExprNode* select_expr = FB_NEW_POOL(getPool()) SelectExprNode(getPool()); + SelectExprNode* select_expr = FB_NEW_POOL(dsqlScratch->getPool()) SelectExprNode(dsqlScratch->getPool()); select_expr->querySpec = querySpec; // build a FOR SELECT node @@ -5560,7 +5561,7 @@ StmtNode* MergeNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) StmtNode* sendNode = (FB_NEW_POOL(pool) MergeSendNode(pool, mergeStmt))->dsqlPass(dsqlScratch); - return SavepointEncloseNode::make(getPool(), dsqlScratch, sendNode); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, sendNode); } string MergeNode::internalPrint(NodePrinter& printer) const @@ -5768,7 +5769,7 @@ DmlNode* ModifyNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* c StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool updateOrInsert) { thread_db* tdbb = JRD_get_thread_data(); // necessary? - MemoryPool& pool = getPool(); + MemoryPool& pool = dsqlScratch->getPool(); // Separate old and new context references. @@ -5933,7 +5934,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) @@ -5944,7 +5945,7 @@ StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool up StmtNode* ModifyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - return SavepointEncloseNode::make(getPool(), dsqlScratch, internalDsqlPass(dsqlScratch, false)); + return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, internalDsqlPass(dsqlScratch, false)); } string ModifyNode::internalPrint(NodePrinter& printer) const @@ -6104,7 +6105,7 @@ void ModifyNode::pass1Modify(thread_db* tdbb, CompilerScratch* csb, ModifyNode* // Copy the view source. map = CMP_alloc_map(tdbb, csb, node->newStream); - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); source = source->copy(tdbb, copier); if (trigger) @@ -6395,7 +6396,7 @@ DmlNode* PostEventNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch PostEventNode* PostEventNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - PostEventNode* node = FB_NEW_POOL(getPool()) PostEventNode(getPool()); + PostEventNode* node = FB_NEW_POOL(dsqlScratch->getPool()) PostEventNode(dsqlScratch->getPool()); node->event = doDsqlPass(dsqlScratch, event); node->argument = doDsqlPass(dsqlScratch, argument); @@ -6610,7 +6611,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_INSERT); - StoreNode* node = FB_NEW_POOL(getPool()) StoreNode(getPool()); + StoreNode* node = FB_NEW_POOL(dsqlScratch->getPool()) StoreNode(dsqlScratch->getPool()); node->overrideClause = overrideClause; // Process SELECT expression, if present @@ -6633,7 +6634,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, else { values = doDsqlPass(dsqlScratch, dsqlValues, false); - needSavePoint = SubSelectFinder::find(values); + needSavePoint = SubSelectFinder::find(dsqlScratch->getPool(), values); } // Process relation @@ -6704,7 +6705,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, // Match field fields and values - CompoundStmtNode* assignStatements = FB_NEW_POOL(getPool()) CompoundStmtNode(getPool()); + CompoundStmtNode* assignStatements = FB_NEW_POOL(dsqlScratch->getPool()) CompoundStmtNode(dsqlScratch->getPool()); node->statement = assignStatements; if (values) @@ -6728,7 +6729,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, if (field && field->dsqlField) { - *ptr2 = FB_NEW_POOL(getPool()) DefaultNode(getPool(), + *ptr2 = FB_NEW_POOL(dsqlScratch->getPool()) DefaultNode(dsqlScratch->getPool(), relation->rel_name, field->dsqlField->fld_name); *ptr2 = doDsqlPass(dsqlScratch, *ptr2, false); } @@ -6736,7 +6737,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, if (*ptr2) { - AssignmentNode* temp = FB_NEW_POOL(getPool()) AssignmentNode(getPool()); + AssignmentNode* temp = FB_NEW_POOL(dsqlScratch->getPool()) AssignmentNode(dsqlScratch->getPool()); temp->asgnFrom = *ptr2; temp->asgnTo = *ptr; assignStatements->statements.add(temp); @@ -6774,7 +6775,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, dsqlScratch->context->pop(); } - dsqlSetParametersName(assignStatements, node->dsqlRelation); + dsqlSetParametersName(dsqlScratch, assignStatements, node->dsqlRelation); StmtNode* ret = node; if (!updateOrInsert) @@ -6788,13 +6789,13 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, StmtNode* StoreNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { bool needSavePoint; - StmtNode* node = SavepointEncloseNode::make(getPool(), dsqlScratch, + StmtNode* node = SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, internalDsqlPass(dsqlScratch, false, needSavePoint)); if (!needSavePoint || nodeIs(node)) return node; - return FB_NEW SavepointEncloseNode(getPool(), node); + return FB_NEW SavepointEncloseNode(dsqlScratch->getPool(), node); } string StoreNode::internalPrint(NodePrinter& printer) const @@ -6920,7 +6921,7 @@ bool StoreNode::pass1Store(thread_db* tdbb, CompilerScratch* csb, StoreNode* nod parentStream = stream; StreamType* map = CMP_alloc_map(tdbb, csb, stream); - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); if (trigger) { @@ -7372,7 +7373,7 @@ DmlNode* SelectNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* c SelectNode* SelectNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - SelectNode* node = FB_NEW_POOL(getPool()) SelectNode(getPool()); + SelectNode* node = FB_NEW_POOL(dsqlScratch->getPool()) SelectNode(dsqlScratch->getPool()); node->dsqlForUpdate = dsqlForUpdate; const DsqlContextStack::iterator base(*dsqlScratch->context); @@ -7872,7 +7873,7 @@ ReturnNode* ReturnNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_dsql_unsupported_in_auto_trans) << Arg::Str("RETURN")); } - ReturnNode* node = FB_NEW_POOL(getPool()) ReturnNode(getPool()); + ReturnNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ReturnNode(dsqlScratch->getPool()); node->value = doDsqlPass(dsqlScratch, value); return node; @@ -8294,7 +8295,7 @@ void SetSessionNode::execute(thread_db* tdbb, dsql_req* request) const StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { thread_db* tdbb = JRD_get_thread_data(); // necessary? - MemoryPool& pool = getPool(); + MemoryPool& pool = dsqlScratch->getPool(); if (!dsqlScratch->isPsql()) dsqlScratch->flags |= DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT; @@ -8497,11 +8498,11 @@ StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (!returning) dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_INSERT); - StmtNode* ret = SavepointEncloseNode::make(getPool(), dsqlScratch, list); + StmtNode* ret = SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, list); if (!needSavePoint || nodeIs(ret)) return ret; - return FB_NEW SavepointEncloseNode(getPool(), ret); + return FB_NEW SavepointEncloseNode(dsqlScratch->getPool(), ret); } string UpdateOrInsertNode::internalPrint(NodePrinter& printer) const @@ -8794,7 +8795,7 @@ static ValueListNode* dsqlPassArray(DsqlCompilerScratch* dsqlScratch, ValueListN if (!input) return NULL; - MemoryPool& pool = dsqlScratch->getStatement()->getPool(); + MemoryPool& pool = dsqlScratch->getPool(); ValueListNode* output = FB_NEW_POOL(pool) ValueListNode(pool, input->items.getCount()); NestConst* ptr = input->items.begin(); NestConst* ptr2 = output->items.begin(); @@ -9180,7 +9181,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); @@ -9206,9 +9207,15 @@ static void dsqlSetParameterName(ExprNode* exprNode, const ValueExprNode* fld_no case ExprNode::TYPE_SUBSTRING: case ExprNode::TYPE_SUBSTRING_SIMILAR: case ExprNode::TYPE_TRIM: - for (NodeRef** i = exprNode->dsqlChildNodes.begin(); i != exprNode->dsqlChildNodes.end(); ++i) - dsqlSetParameterName((*i)->getExpr(), fld_node, relation); + { + NodeRefsHolder holder(dsqlScratch->getPool()); + exprNode->getChildren(holder, true); + + for (auto ref : holder.refs) + dsqlSetParameterName(dsqlScratch, ref->getExpr(), fld_node, relation); + break; + } case ExprNode::TYPE_PARAMETER: { @@ -9222,7 +9229,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); @@ -9236,11 +9244,9 @@ static void dsqlSetParametersName(CompoundStmtNode* statements, const RecordSour AssignmentNode* assign = nodeAs(*ptr); 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 4652cffafa..4bb7eb0f18 100644 --- a/src/dsql/Visitors.h +++ b/src/dsql/Visitors.h @@ -51,12 +51,12 @@ enum FieldMatchType // Check for an aggregate expression in an expression. It could be buried in an expression // tree and therefore call itselfs again. The level parameters (currentLevel & deepestLevel) // are used to see how deep we are with passing sub-queries (= scope_level). -class AggregateFinder +class AggregateFinder : public Firebird::PermanentStorage { public: - AggregateFinder(DsqlCompilerScratch* aDsqlScratch, bool aWindow); + AggregateFinder(Firebird::MemoryPool& pool, DsqlCompilerScratch* aDsqlScratch, bool aWindow); - static bool find(DsqlCompilerScratch* dsqlScratch, bool window, ExprNode* node); + static bool find(Firebird::MemoryPool& pool, DsqlCompilerScratch* dsqlScratch, bool window, ExprNode* node); bool visit(ExprNode* node); @@ -83,12 +83,13 @@ public: // NOTE 160 - outer reference is defined in Subclause 6.7, "". // 2) The shall not contain a without an intervening // . -class Aggregate2Finder +class Aggregate2Finder : public Firebird::PermanentStorage { public: - Aggregate2Finder(USHORT aCheckScopeLevel, FieldMatchType aMatchType, bool aWindowOnly); + Aggregate2Finder(Firebird::MemoryPool& pool, USHORT aCheckScopeLevel, + FieldMatchType aMatchType, bool aWindowOnly); - static bool find(USHORT checkScopeLevel, FieldMatchType matchType, bool windowOnly, + static bool find(Firebird::MemoryPool& pool, USHORT checkScopeLevel, FieldMatchType matchType, bool windowOnly, ExprNode* node); bool visit(ExprNode* node); @@ -102,12 +103,12 @@ public: // Check the fields inside an aggregate and check if the field scope_level meets the specified // conditions. -class FieldFinder +class FieldFinder : public Firebird::PermanentStorage { public: - FieldFinder(USHORT aCheckScopeLevel, FieldMatchType aMatchType); + FieldFinder(Firebird::MemoryPool& pool, USHORT aCheckScopeLevel, FieldMatchType aMatchType); - static bool find(USHORT checkScopeLevel, FieldMatchType matchType, ExprNode* node); + static bool find(Firebird::MemoryPool& pool, USHORT checkScopeLevel, FieldMatchType matchType, ExprNode* node); bool visit(ExprNode* node); @@ -131,13 +132,15 @@ public: class InvalidReferenceFinder { public: - InvalidReferenceFinder(const dsql_ctx* aContext, const ValueListNode* aList); + InvalidReferenceFinder(DsqlCompilerScratch* aDsqlScratch, const dsql_ctx* aContext, const ValueListNode* aList); - static bool find(const dsql_ctx* context, const ValueListNode* list, ExprNode* node); + 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; @@ -147,17 +150,17 @@ public: // Called to map fields used in an aggregate-context after all pass1 calls // (SELECT-, ORDER BY-lists). Walk completly through the given node 'field' and map the fields // with same scope_level as the given context to the given context with the post_map function. -class FieldRemapper +class FieldRemapper : public Firebird::PermanentStorage { public: - FieldRemapper(DsqlCompilerScratch* aDsqlScratch, dsql_ctx* aContext, bool aWindow, + FieldRemapper(Firebird::MemoryPool& pool, DsqlCompilerScratch* aDsqlScratch, dsql_ctx* aContext, bool aWindow, WindowClause* aWindowNode = NULL); - static ExprNode* remap(DsqlCompilerScratch* dsqlScratch, dsql_ctx* context, bool window, + static ExprNode* remap(Firebird::MemoryPool& pool, DsqlCompilerScratch* dsqlScratch, dsql_ctx* context, bool window, ExprNode* field, WindowClause* windowNode = NULL) { // The bool value returned by the visitor is completely discarded in this class. - return FieldRemapper(dsqlScratch, context, window, windowNode).visit(field); + return FieldRemapper(pool, dsqlScratch, context, window, windowNode).visit(field); } ExprNode* visit(ExprNode* node); @@ -171,12 +174,17 @@ public: }; // Search if a sub select is buried inside a select list from a query expression. -class SubSelectFinder +class SubSelectFinder : public Firebird::PermanentStorage { public: - static bool find(ExprNode* node) + SubSelectFinder(MemoryPool& pool) + : PermanentStorage(pool) { - return SubSelectFinder().visit(node); + } + + static bool find(MemoryPool& pool, ExprNode* node) + { + return SubSelectFinder(pool).visit(node); } bool visit(ExprNode* node); @@ -184,11 +192,12 @@ public: // Generic node copier. -class NodeCopier +class NodeCopier : public Firebird::PermanentStorage { public: - NodeCopier(CompilerScratch* aCsb, StreamType* aRemap) - : csb(aCsb), + NodeCopier(Firebird::MemoryPool& pool, CompilerScratch* aCsb, StreamType* aRemap) + : PermanentStorage(pool), + csb(aCsb), remap(aRemap), message(NULL) { @@ -221,13 +230,13 @@ public: template static T* copy(thread_db* tdbb, CompilerScratch* csb, const T* input, StreamType* remap) { - return NodeCopier(csb, remap).copy(tdbb, input); + return NodeCopier(*tdbb->getDefaultPool(), csb, remap).copy(tdbb, input); } template static T* copy(thread_db* tdbb, CompilerScratch* csb, const NestConst& input, StreamType* remap) { - return NodeCopier(csb, remap).copy(tdbb, input.getObject()); + return NodeCopier(*tdbb->getDefaultPool(), csb, remap).copy(tdbb, input.getObject()); } virtual USHORT remapField(USHORT /*stream*/, USHORT fldId) diff --git a/src/dsql/WinNodes.cpp b/src/dsql/WinNodes.cpp index e04c452792..d644728e66 100644 --- a/src/dsql/WinNodes.cpp +++ b/src/dsql/WinNodes.cpp @@ -50,9 +50,6 @@ static WinFuncNode::RegisterFactory0 denseRankWinInfo("DENSE_R DenseRankWinNode::DenseRankWinNode(MemoryPool& pool) : WinFuncNode(pool, denseRankWinInfo) { - fb_assert(dsqlChildNodes.getCount() == 1 && jrdChildNodes.getCount() == 1); - dsqlChildNodes.clear(); - jrdChildNodes.clear(); } string DenseRankWinNode::internalPrint(NodePrinter& printer) const @@ -98,9 +95,9 @@ dsc* DenseRankWinNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const return &impure->vlu_desc; } -AggNode* DenseRankWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/ +AggNode* DenseRankWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) DenseRankWinNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) DenseRankWinNode(dsqlScratch->getPool()); } @@ -113,9 +110,6 @@ RankWinNode::RankWinNode(MemoryPool& pool) : WinFuncNode(pool, rankWinInfo), tempImpure(0) { - fb_assert(dsqlChildNodes.getCount() == 1 && jrdChildNodes.getCount() == 1); - dsqlChildNodes.clear(); - jrdChildNodes.clear(); } string RankWinNode::internalPrint(NodePrinter& printer) const @@ -183,9 +177,9 @@ dsc* RankWinNode::aggExecute(thread_db* tdbb, jrd_req* request) const return &impureTemp->vlu_desc; } -AggNode* RankWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/ +AggNode* RankWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) RankWinNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) RankWinNode(dsqlScratch->getPool()); } @@ -198,9 +192,6 @@ PercentRankWinNode::PercentRankWinNode(MemoryPool& pool) : WinFuncNode(pool, percentRankWinInfo), tempImpure(0) { - fb_assert(dsqlChildNodes.getCount() == 1 && jrdChildNodes.getCount() == 1); - dsqlChildNodes.clear(); - jrdChildNodes.clear(); } string PercentRankWinNode::internalPrint(NodePrinter& printer) const @@ -274,9 +265,9 @@ dsc* PercentRankWinNode::winPass(thread_db* /*tdbb*/, jrd_req* request, SlidingW return &impureTemp->vlu_desc; } -AggNode* PercentRankWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/ +AggNode* PercentRankWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) PercentRankWinNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) PercentRankWinNode(dsqlScratch->getPool()); } @@ -288,9 +279,6 @@ static WinFuncNode::RegisterFactory0 cumeDistWinInfo("CUME_DIST CumeDistWinNode::CumeDistWinNode(MemoryPool& pool) : WinFuncNode(pool, cumeDistWinInfo) { - fb_assert(dsqlChildNodes.getCount() == 1 && jrdChildNodes.getCount() == 1); - dsqlChildNodes.clear(); - jrdChildNodes.clear(); } string CumeDistWinNode::internalPrint(NodePrinter& printer) const @@ -339,9 +327,9 @@ dsc* CumeDistWinNode::winPass(thread_db* /*tdbb*/, jrd_req* request, SlidingWind return &impure->vlu_desc; } -AggNode* CumeDistWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/ +AggNode* CumeDistWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) CumeDistWinNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) CumeDistWinNode(dsqlScratch->getPool()); } @@ -353,9 +341,6 @@ static WinFuncNode::RegisterFactory0 rowNumberWinInfo("ROW_NUM RowNumberWinNode::RowNumberWinNode(MemoryPool& pool) : WinFuncNode(pool, rowNumberWinInfo) { - fb_assert(dsqlChildNodes.getCount() == 1 && jrdChildNodes.getCount() == 1); - dsqlChildNodes.clear(); - jrdChildNodes.clear(); } string RowNumberWinNode::internalPrint(NodePrinter& printer) const @@ -397,9 +382,9 @@ dsc* RowNumberWinNode::winPass(thread_db* /*tdbb*/, jrd_req* request, SlidingWin return &impure->vlu_desc; } -AggNode* RowNumberWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/ +AggNode* RowNumberWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) RowNumberWinNode(getPool()); + return FB_NEW_POOL(dsqlScratch->getPool()) RowNumberWinNode(dsqlScratch->getPool()); } @@ -463,7 +448,7 @@ dsc* FirstValueWinNode::winPass(thread_db* tdbb, jrd_req* request, SlidingWindow AggNode* FirstValueWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) FirstValueWinNode(getPool(), doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) FirstValueWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); } @@ -527,7 +512,7 @@ dsc* LastValueWinNode::winPass(thread_db* tdbb, jrd_req* request, SlidingWindow* AggNode* LastValueWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) LastValueWinNode(getPool(), doDsqlPass(dsqlScratch, arg)); + return FB_NEW_POOL(dsqlScratch->getPool()) LastValueWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); } @@ -542,8 +527,6 @@ NthValueWinNode::NthValueWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExp row(aRow), from(aFrom) { - addChildNode(row, row); - addChildNode(from, from); } void NthValueWinNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/) @@ -626,7 +609,7 @@ dsc* NthValueWinNode::winPass(thread_db* tdbb, jrd_req* request, SlidingWindow* AggNode* NthValueWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) NthValueWinNode(getPool(), + return FB_NEW_POOL(dsqlScratch->getPool()) NthValueWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, row), doDsqlPass(dsqlScratch, from)); } @@ -643,9 +626,6 @@ LagLeadWinNode::LagLeadWinNode(MemoryPool& pool, const AggInfo& aAggInfo, int aD outExpr(aOutExpr) { fb_assert(direction == -1 || direction == 1); - - addChildNode(rows, rows); - addChildNode(outExpr, outExpr); } void LagLeadWinNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/) @@ -734,7 +714,7 @@ ValueExprNode* LagWinNode::copy(thread_db* tdbb, NodeCopier& copier) const AggNode* LagWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) LagWinNode(getPool(), + return FB_NEW_POOL(dsqlScratch->getPool()) LagWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, rows), doDsqlPass(dsqlScratch, outExpr)); @@ -763,7 +743,7 @@ ValueExprNode* LeadWinNode::copy(thread_db* tdbb, NodeCopier& copier) const AggNode* LeadWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - return FB_NEW_POOL(getPool()) LeadWinNode(getPool(), + return FB_NEW_POOL(dsqlScratch->getPool()) LeadWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg), doDsqlPass(dsqlScratch, rows), doDsqlPass(dsqlScratch, outExpr)); @@ -888,7 +868,7 @@ dsc* NTileWinNode::winPass(thread_db* /*tdbb*/, jrd_req* request, SlidingWindow* AggNode* NTileWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ { - NTileWinNode* node = FB_NEW_POOL(getPool()) NTileWinNode(getPool(), + NTileWinNode* node = FB_NEW_POOL(dsqlScratch->getPool()) NTileWinNode(dsqlScratch->getPool(), doDsqlPass(dsqlScratch, arg)); dsc argDesc; diff --git a/src/dsql/WinNodes.h b/src/dsql/WinNodes.h index cbf9ec9060..34e9d96782 100644 --- a/src/dsql/WinNodes.h +++ b/src/dsql/WinNodes.h @@ -41,6 +41,11 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_AGG_CALLS; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + // nothing + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -65,6 +70,11 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_AGG_CALLS; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + // nothing + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -93,6 +103,11 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_AGG_CALLS | CAP_WANTS_WIN_PASS_CALL; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + // nothing + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -123,6 +138,11 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_WIN_PASS_CALL; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + // nothing + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -148,6 +168,11 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_WIN_PASS_CALL; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + // nothing + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -232,6 +257,13 @@ public: return CAP_RESPECTS_WINDOW_FRAME | CAP_WANTS_WIN_PASS_CALL; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + WinFuncNode::getChildren(holder, dsql); + holder.add(row); + holder.add(from); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); @@ -263,6 +295,13 @@ public: return CAP_SUPPORTS_WINDOW_FRAME | CAP_WANTS_WIN_PASS_CALL; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + WinFuncNode::getChildren(holder, dsql); + holder.add(rows); + holder.add(outExpr); + } + virtual Firebird::string internalPrint(NodePrinter& printer) const = 0; virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); diff --git a/src/dsql/dsql.cpp b/src/dsql/dsql.cpp index 6775c23196..f8f14f817b 100644 --- a/src/dsql/dsql.cpp +++ b/src/dsql/dsql.cpp @@ -586,10 +586,13 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr } -void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) { - node = Node::doDsqlPass(scratch, node); + { // scope + Jrd::ContextPoolHolder scratchContext(tdbb, &scratch->getPool()); + node = Node::doDsqlPass(scratch, node); + } if (scratch->clientDialect > SQL_DIALECT_V5) scratch->getStatement()->setBlrVersion(5); @@ -605,7 +608,7 @@ void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, // Allocate buffer for message const ULONG newLen = message->msg_length + FB_DOUBLE_ALIGN - 1; - UCHAR* msgBuffer = FB_NEW_POOL(*tdbb->getDefaultPool()) UCHAR[newLen]; + UCHAR* msgBuffer = FB_NEW_POOL(scratch->getStatement()->getPool()) UCHAR[newLen]; msgBuffer = FB_ALIGN(msgBuffer, FB_DOUBLE_ALIGN); message->msg_buffer_number = req_msg_buffers.add(msgBuffer); } @@ -667,6 +670,10 @@ void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, if (status) status_exception::raise(tdbb->tdbb_status_vector); + + // We don't need the scratch pool anymore. Tell our caller to delete it. + node = NULL; + *destroyScratchPool = true; } // Execute a dynamic SQL statement. @@ -822,7 +829,7 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle, trace.finish(have_cursor, ITracePlugin::RESULT_SUCCESS); } -void DsqlDdlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlDdlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) { internalScratch = scratch; @@ -907,7 +914,7 @@ void DsqlDdlRequest::rethrowDdlException(status_exception& ex, bool metadataUpda } -void DsqlTransactionRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlTransactionRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* /*traceResult*/) { node = Node::doDsqlPass(scratch, node); @@ -926,7 +933,7 @@ void DsqlTransactionRequest::execute(thread_db* tdbb, jrd_tra** traHandle, } -void DsqlSessionManagementRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, +void DsqlSessionManagementRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* /*traceResult*/) { node = Node::doDsqlPass(scratch, node); @@ -1393,37 +1400,47 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* // allocate the statement block, then prepare the statement - Jrd::ContextPoolHolder context(tdbb, database->createPool()); - MemoryPool& pool = *tdbb->getDefaultPool(); - - DsqlCompiledStatement* statement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool); - DsqlCompilerScratch* scratch = FB_NEW_POOL(pool) DsqlCompilerScratch(pool, database, - transaction, statement); - scratch->clientDialect = clientDialect; - - if (isInternalRequest) - scratch->flags |= DsqlCompilerScratch::FLAG_INTERNAL_REQUEST; - + MemoryPool* statementPool = database->createPool(); + MemoryPool* scratchPool = NULL; dsql_req* request = NULL; + Jrd::ContextPoolHolder statementContext(tdbb, statementPool); try { - // Parse the SQL statement. If it croaks, return + DsqlCompiledStatement* statement = FB_NEW_POOL(*statementPool) DsqlCompiledStatement(*statementPool); - Parser parser(tdbb, *tdbb->getDefaultPool(), scratch, clientDialect, - scratch->getAttachment()->dbb_db_SQL_dialect, text, textLength, - tdbb->getAttachment()->att_charset); + scratchPool = database->createPool(); - request = parser.parse(); + DsqlCompilerScratch* scratch = FB_NEW_POOL(*scratchPool) DsqlCompilerScratch(*scratchPool, database, + transaction, statement); + scratch->clientDialect = clientDialect; + + if (isInternalRequest) + scratch->flags |= DsqlCompilerScratch::FLAG_INTERNAL_REQUEST; + + string transformedText; + + { // scope to delete parser before the scratch pool is gone + Jrd::ContextPoolHolder scratchContext(tdbb, scratchPool); + + Parser parser(tdbb, *scratchPool, scratch, clientDialect, + scratch->getAttachment()->dbb_db_SQL_dialect, text, textLength, + tdbb->getAttachment()->att_charset); + + // Parse the SQL statement. If it croaks, return + request = parser.parse(); + request->liveScratchPool = scratchPool; + + if (parser.isStmtAmbiguous()) + scratch->flags |= DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT; + + transformedText = parser.getTransformedString(); + } request->req_dbb = scratch->getAttachment(); request->req_transaction = scratch->getTransaction(); request->statement = scratch->getStatement(); - if (parser.isStmtAmbiguous()) - scratch->flags |= DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT; - - string transformedText = parser.getTransformedString(); SSHORT charSetId = database->dbb_attachment->att_charset; // If the attachment charset is NONE, replace non-ASCII characters by question marks, so @@ -1457,12 +1474,12 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* transformedText.assign(temp.begin(), temp.getCount()); } - statement->setSqlText(FB_NEW_POOL(pool) RefString(pool, transformedText)); + statement->setSqlText(FB_NEW_POOL(*statementPool) RefString(*statementPool, transformedText)); // allocate the send and receive messages - statement->setSendMsg(FB_NEW_POOL(pool) dsql_msg(pool)); - dsql_msg* message = FB_NEW_POOL(pool) dsql_msg(pool); + statement->setSendMsg(FB_NEW_POOL(*statementPool) dsql_msg(*statementPool)); + dsql_msg* message = FB_NEW_POOL(*statementPool) dsql_msg(*statementPool); statement->setReceiveMsg(message); message->msg_number = 1; @@ -1474,7 +1491,14 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* ntrace_result_t traceResult = ITracePlugin::RESULT_SUCCESS; try { - request->dsqlPass(tdbb, scratch, &traceResult); + bool destroyScratchPool = false; + request->dsqlPass(tdbb, scratch, &destroyScratchPool, &traceResult); + + if (destroyScratchPool) + { + database->deletePool(scratchPool); + request->liveScratchPool = scratchPool = NULL; + } } catch (const Exception&) { @@ -1494,6 +1518,11 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* request->req_traced = false; dsql_req::destroy(tdbb, request, true); } + else + { + database->deletePool(scratchPool); + database->deletePool(statementPool); + } throw; } @@ -1561,6 +1590,7 @@ static void release_statement(DsqlCompiledStatement* statement) dsql_req::dsql_req(MemoryPool& pool) : req_pool(pool), statement(NULL), + liveScratchPool(NULL), cursors(req_pool), req_dbb(NULL), req_transaction(NULL), @@ -1756,7 +1786,10 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop) // Release the entire request if explicitly asked for if (drop) + { request->req_dbb->deletePool(&request->getPool()); + request->req_dbb->deletePool(request->liveScratchPool); + } } diff --git a/src/dsql/dsql.h b/src/dsql/dsql.h index 654daa0e6a..b5ca3823d1 100644 --- a/src/dsql/dsql.h +++ b/src/dsql/dsql.h @@ -490,8 +490,6 @@ public: } public: - MemoryPool& getPool() { return PermanentStorage::getPool(); } - Type getType() const { return type; } void setType(Type value) { type = value; } @@ -573,7 +571,7 @@ public: return statement; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult) = 0; virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -611,6 +609,7 @@ private: public: const DsqlCompiledStatement* statement; + MemoryPool* liveScratchPool; Firebird::Array cursors; // Cursor update statements dsql_dbb* req_dbb; // DSQL attachment @@ -651,7 +650,7 @@ public: { } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -681,7 +680,7 @@ public: { } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -708,7 +707,7 @@ public: req_traced = false; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, @@ -730,7 +729,7 @@ public: req_traced = false; } - virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, + virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool, ntrace_result_t* traceResult); virtual void execute(thread_db* tdbb, jrd_tra** traHandle, diff --git a/src/dsql/gen.cpp b/src/dsql/gen.cpp index 3233e5f1c0..3f5a92504c 100644 --- a/src/dsql/gen.cpp +++ b/src/dsql/gen.cpp @@ -124,8 +124,10 @@ void GEN_expr(DsqlCompilerScratch* dsqlScratch, ExprNode* node) // ASF: Shouldn't we check nod_gen_id2 too? - if (node->kind == DmlNode::KIND_VALUE && node->dsqlCompatDialectVerb && - dsqlScratch->clientDialect == SQL_DIALECT_V6_TRANSITION) + const char* compatDialectVerb; + + if (node->getKind() == DmlNode::KIND_VALUE && dsqlScratch->clientDialect == SQL_DIALECT_V6_TRANSITION && + (compatDialectVerb = node->getCompatDialectVerb())) { dsc desc; MAKE_desc(dsqlScratch, &desc, static_cast(node)); @@ -134,7 +136,7 @@ void GEN_expr(DsqlCompilerScratch* dsqlScratch, ExprNode* node) { ERRD_post_warning( Arg::Warning(isc_dsql_dialect_warning_expr) << - Arg::Str(node->dsqlCompatDialectVerb)); + Arg::Str(compatDialectVerb)); } } } diff --git a/src/dsql/make.cpp b/src/dsql/make.cpp index 919ac088d5..9c03ded99e 100644 --- a/src/dsql/make.cpp +++ b/src/dsql/make.cpp @@ -412,7 +412,7 @@ dsql_par* MAKE_parameter(dsql_msg* message, bool sqlda_flag, bool null_flag, thread_db* tdbb = JRD_get_thread_data(); - dsql_par* parameter = FB_NEW_POOL(*tdbb->getDefaultPool()) dsql_par(*tdbb->getDefaultPool()); + dsql_par* parameter = FB_NEW_POOL(message->getPool()) dsql_par(message->getPool()); parameter->par_message = message; message->msg_parameters.insert(0, parameter); parameter->par_parameter = message->msg_parameter++; diff --git a/src/dsql/parse.y b/src/dsql/parse.y index 53da894416..2adee6f8ac 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -792,10 +792,10 @@ top %type statement statement - : dml_statement { $$ = newNode($1); } - | ddl_statement { $$ = newNode($1); } - | tra_statement { $$ = newNode($1); } - | mng_statement { $$ = newNode($1); } + : dml_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlDmlRequest(getStatementPool(), $1); } + | ddl_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlDdlRequest(getStatementPool(), $1); } + | tra_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlTransactionRequest(getStatementPool(), $1); } + | mng_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlSessionManagementRequest(getStatementPool(), $1); } ; %type dml_statement diff --git a/src/dsql/pass1.cpp b/src/dsql/pass1.cpp index bfc9738d02..f385c98c88 100644 --- a/src/dsql/pass1.cpp +++ b/src/dsql/pass1.cpp @@ -190,8 +190,9 @@ static void pass1_union_auto_cast(DsqlCompilerScratch*, ExprNode*, const dsc&, F static void remap_streams_to_parent_context(ExprNode*, dsql_ctx*); -AggregateFinder::AggregateFinder(DsqlCompilerScratch* aDsqlScratch, bool aWindow) - : dsqlScratch(aDsqlScratch), +AggregateFinder::AggregateFinder(MemoryPool& pool, DsqlCompilerScratch* aDsqlScratch, bool aWindow) + : PermanentStorage(pool), + dsqlScratch(aDsqlScratch), window(aWindow), currentLevel(dsqlScratch->scopeLevel), deepestLevel(0), @@ -199,9 +200,9 @@ AggregateFinder::AggregateFinder(DsqlCompilerScratch* aDsqlScratch, bool aWindow { } -bool AggregateFinder::find(DsqlCompilerScratch* dsqlScratch, bool window, ExprNode* node) +bool AggregateFinder::find(MemoryPool& pool, DsqlCompilerScratch* dsqlScratch, bool window, ExprNode* node) { - AggregateFinder visitor(dsqlScratch, window); + AggregateFinder visitor(pool, dsqlScratch, window); return visitor.visit(node); } @@ -211,18 +212,20 @@ bool AggregateFinder::visit(ExprNode* node) } -Aggregate2Finder::Aggregate2Finder(USHORT aCheckScopeLevel, FieldMatchType aMatchType, bool aWindowOnly) - : checkScopeLevel(aCheckScopeLevel), +Aggregate2Finder::Aggregate2Finder(MemoryPool& pool, USHORT aCheckScopeLevel, + FieldMatchType aMatchType, bool aWindowOnly) + : PermanentStorage(pool), + checkScopeLevel(aCheckScopeLevel), matchType(aMatchType), windowOnly(aWindowOnly), currentScopeLevelEqual(true) { } -bool Aggregate2Finder::find(USHORT checkScopeLevel, FieldMatchType matchType, bool windowOnly, - ExprNode* node) +bool Aggregate2Finder::find(MemoryPool& pool, USHORT checkScopeLevel, + FieldMatchType matchType, bool windowOnly, ExprNode* node) { - Aggregate2Finder visitor(checkScopeLevel, matchType, windowOnly); + Aggregate2Finder visitor(pool, checkScopeLevel, matchType, windowOnly); return visitor.visit(node); } @@ -232,16 +235,17 @@ bool Aggregate2Finder::visit(ExprNode* node) } -FieldFinder::FieldFinder(USHORT aCheckScopeLevel, FieldMatchType aMatchType) - : checkScopeLevel(aCheckScopeLevel), +FieldFinder::FieldFinder(MemoryPool& pool, USHORT aCheckScopeLevel, FieldMatchType aMatchType) + : PermanentStorage(pool), + checkScopeLevel(aCheckScopeLevel), matchType(aMatchType), field(false) { } -bool FieldFinder::find(USHORT checkScopeLevel, FieldMatchType matchType, ExprNode* node) +bool FieldFinder::find(MemoryPool& pool, USHORT checkScopeLevel, FieldMatchType matchType, ExprNode* node) { - FieldFinder visitor(checkScopeLevel, matchType); + FieldFinder visitor(pool, checkScopeLevel, matchType); return visitor.visit(node); } @@ -251,8 +255,10 @@ bool FieldFinder::visit(ExprNode* node) } -InvalidReferenceFinder::InvalidReferenceFinder(const dsql_ctx* aContext, const ValueListNode* aList) - : context(aContext), +InvalidReferenceFinder::InvalidReferenceFinder(DsqlCompilerScratch* aDsqlScratch, + const dsql_ctx* aContext, const ValueListNode* aList) + : dsqlScratch(aDsqlScratch), + context(aContext), list(aList), insideOwnMap(false), insideHigherMap(false) @@ -260,9 +266,10 @@ InvalidReferenceFinder::InvalidReferenceFinder(const dsql_ctx* aContext, const V DEV_BLKCHK(list, dsql_type_nod); } -bool InvalidReferenceFinder::find(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(context, list); + InvalidReferenceFinder visitor(dsqlScratch, context, list); return visitor.visit(node); } @@ -290,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; } } @@ -299,9 +306,10 @@ bool InvalidReferenceFinder::visit(ExprNode* node) } -FieldRemapper::FieldRemapper(DsqlCompilerScratch* aDsqlScratch, dsql_ctx* aContext, bool aWindow, +FieldRemapper::FieldRemapper(MemoryPool& pool, DsqlCompilerScratch* aDsqlScratch, dsql_ctx* aContext, bool aWindow, WindowClause* aWindowNode) - : dsqlScratch(aDsqlScratch), + : PermanentStorage(pool), + dsqlScratch(aDsqlScratch), context(aContext), window(aWindow), windowNode(aWindowNode), @@ -786,7 +794,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(); @@ -815,10 +824,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 = nodeAs(node1); @@ -832,10 +841,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 = nodeAs(node1); @@ -845,13 +854,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. @@ -869,17 +878,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); } @@ -1054,7 +1063,7 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i bool foundSubSelect = false; RseNode* queryNode = nodeAs(query); if (queryNode) - foundSubSelect = SubSelectFinder::find(queryNode->dsqlSelectList); + foundSubSelect = SubSelectFinder::find(dsqlScratch->getPool(), queryNode->dsqlSelectList); if (foundSubSelect) { @@ -1414,7 +1423,7 @@ void PASS1_expand_select_node(DsqlCompilerScratch* dsqlScratch, ExprNode* node, } else { - fb_assert(node->kind == DmlNode::KIND_VALUE); + fb_assert(node->getKind() == DmlNode::KIND_VALUE); list->add(static_cast(node)); } } @@ -1854,8 +1863,8 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod // AB: An aggregate pointing to it's own parent_context isn't // allowed, HAVING should be used instead - if (Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, - rse->dsqlWhere)) + if (Aggregate2Finder::find(dsqlScratch->getPool(), dsqlScratch->scopeLevel, + FIELD_MATCH_TYPE_EQUAL, false, rse->dsqlWhere)) { // Cannot use an aggregate in a WHERE clause, use HAVING instead ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << @@ -1910,7 +1919,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod if (inputRse->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE) { - if (Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, + if (Aggregate2Finder::find(dsqlScratch->getPool(), dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, rse->dsqlSelectList)) { // Recursive member of CTE cannot use aggregate function @@ -1928,7 +1937,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod if (inputRse->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE) { - if (Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, + if (Aggregate2Finder::find(dsqlScratch->getPool(), dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, rse->dsqlOrder)) { // Recursive member of CTE cannot use aggregate function @@ -1946,8 +1955,8 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod if (inputRse->dsqlGroup || inputRse->dsqlHaving || - (rse->dsqlSelectList && AggregateFinder::find(dsqlScratch, false, rse->dsqlSelectList)) || - (rse->dsqlOrder && AggregateFinder::find(dsqlScratch, false, rse->dsqlOrder))) + (rse->dsqlSelectList && AggregateFinder::find(dsqlScratch->getPool(), dsqlScratch, false, rse->dsqlSelectList)) || + (rse->dsqlOrder && AggregateFinder::find(dsqlScratch->getPool(), dsqlScratch, false, rse->dsqlOrder))) { // dimitr: don't allow WITH LOCK for aggregates if (updateLock) @@ -1999,8 +2008,8 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod // AB: An field pointing to another parent_context isn't // allowed and GROUP BY items can't contain aggregates - if (FieldFinder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_LOWER, aggregate->dsqlGroup) || - Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_LOWER_EQUAL, + if (FieldFinder::find(dsqlScratch->getPool(), dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_LOWER, aggregate->dsqlGroup) || + Aggregate2Finder::find(dsqlScratch->getPool(), dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_LOWER_EQUAL, false, aggregate->dsqlGroup)) { // Cannot use an aggregate in a GROUP BY clause @@ -2042,7 +2051,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod if (parent_context) { - FieldRemapper remapper(dsqlScratch, parent_context, false); + FieldRemapper remapper(dsqlScratch->getPool(), dsqlScratch, parent_context, false); // Reset context of select items to point to the parent stream @@ -2056,7 +2065,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(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) @@ -2078,7 +2087,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(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) @@ -2104,7 +2113,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod // AB: Check for invalid contructions inside the HAVING clause - if (InvalidReferenceFinder::find(parent_context, aggregate->dsqlGroup, + if (InvalidReferenceFinder::find(dsqlScratch, parent_context, aggregate->dsqlGroup, parentRse->dsqlWhere)) { // Invalid expression in the HAVING clause @@ -2113,7 +2122,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod Arg::Gds(isc_dsql_agg_having_err) << Arg::Str("HAVING clause")); } - if (AggregateFinder::find(dsqlScratch, true, parentRse->dsqlWhere)) + if (AggregateFinder::find(dsqlScratch->getPool(), dsqlScratch, true, parentRse->dsqlWhere)) { // Cannot use an aggregate in a WHERE clause, use HAVING instead ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << @@ -2126,8 +2135,8 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod parent_context->ctx_context = dsqlScratch->contextNumber++; } - bool isWindow = (rse->dsqlOrder && AggregateFinder::find(dsqlScratch, true, rse->dsqlOrder)) || - (rse->dsqlSelectList && AggregateFinder::find(dsqlScratch, true, rse->dsqlSelectList)) || + bool isWindow = (rse->dsqlOrder && AggregateFinder::find(dsqlScratch->getPool(), dsqlScratch, true, rse->dsqlOrder)) || + (rse->dsqlSelectList && AggregateFinder::find(dsqlScratch->getPool(), dsqlScratch, true, rse->dsqlSelectList)) || inputRse->dsqlNamedWindows; // WINDOW functions @@ -2181,7 +2190,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(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) @@ -2191,7 +2200,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod } } - FieldRemapper remapper(dsqlScratch, parent_context, true); + FieldRemapper remapper(dsqlScratch->getPool(), dsqlScratch, parent_context, true); ExprNode::doDsqlFieldRemapper(remapper, parentRse->dsqlSelectList, rse->dsqlSelectList); rse->dsqlSelectList = NULL; @@ -2205,7 +2214,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(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) @@ -2236,7 +2245,7 @@ static RseNode* pass1_rse_impl(DsqlCompilerScratch* dsqlScratch, RecordSourceNod windowMap->partitionRemapped = Node::doDsqlPass(dsqlScratch, windowMap->window->partition); - FieldRemapper remapper2(dsqlScratch, parent_context, true, windowMap->window); + FieldRemapper remapper2(dsqlScratch->getPool(), dsqlScratch, parent_context, true, windowMap->window); ExprNode::doDsqlFieldRemapper(remapper2, windowMap->partitionRemapped); } } @@ -2847,7 +2856,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; @@ -2970,7 +2979,7 @@ WindowMap* dsql_ctx::getWindowMap(DsqlCompilerScratch* dsqlScratch, WindowClause !windowMap && i != ctx_win_maps.end(); ++i) { - if (PASS1_node_match((*i)->window, windowNode, false)) + if (PASS1_node_match(dsqlScratch, (*i)->window, windowNode, false)) { windowMap = *i; } diff --git a/src/dsql/pass1_proto.h b/src/dsql/pass1_proto.h index 47c80dd51b..dc3f4b4016 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::WindowClause*); Jrd::RecordSourceNode* PASS1_relation(Jrd::DsqlCompilerScratch*, Jrd::RecordSourceNode*); diff --git a/src/jrd/ExtEngineManager.cpp b/src/jrd/ExtEngineManager.cpp index 436f4bfc6d..eba14a14f9 100644 --- a/src/jrd/ExtEngineManager.cpp +++ b/src/jrd/ExtEngineManager.cpp @@ -352,10 +352,10 @@ namespace { SuspendNode* suspend = FB_NEW_POOL(pool) SuspendNode(pool); suspend->message = intOutMessageNode; - suspend->statement = FB_NEW_POOL(getPool()) MessageMoverNode(pool, extOutMessageNode, intOutMessageNode); + suspend->statement = FB_NEW_POOL(pool) MessageMoverNode(pool, extOutMessageNode, intOutMessageNode); statements.add(suspend); - statements.add(FB_NEW_POOL(getPool()) StallNode(pool)); + statements.add(FB_NEW_POOL(pool) StallNode(pool)); } virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const diff --git a/src/jrd/JrdStatement.cpp b/src/jrd/JrdStatement.cpp index 738c4aacc8..fc70a76b4a 100644 --- a/src/jrd/JrdStatement.cpp +++ b/src/jrd/JrdStatement.cpp @@ -68,7 +68,7 @@ JrdStatement::JrdStatement(thread_db* tdbb, MemoryPool* p, CompilerScratch* csb) makeSubRoutines(tdbb, this, csb, csb->subProcedures); makeSubRoutines(tdbb, this, csb, csb->subFunctions); - topNode = (csb->csb_node->kind == DmlNode::KIND_STATEMENT) ? + topNode = (csb->csb_node->getKind() == DmlNode::KIND_STATEMENT) ? static_cast(csb->csb_node) : NULL; accessList = csb->csb_access; @@ -223,7 +223,7 @@ JrdStatement* JrdStatement::makeStatement(thread_db* tdbb, CompilerScratch* csb, if (fieldInfo.validationExpr) { - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); fieldInfo.validationExpr = copier.copy(tdbb, fieldInfo.validationExpr); } @@ -231,7 +231,7 @@ JrdStatement* JrdStatement::makeStatement(thread_db* tdbb, CompilerScratch* csb, DmlNode::doPass1(tdbb, csb, fieldInfo.validationExpr.getAddress()); } - if (csb->csb_node->kind == DmlNode::KIND_STATEMENT) + if (csb->csb_node->getKind() == DmlNode::KIND_STATEMENT) StmtNode::doPass2(tdbb, csb, reinterpret_cast(&csb->csb_node), NULL); else ExprNode::doPass2(tdbb, csb, &csb->csb_node); diff --git a/src/jrd/Optimizer.cpp b/src/jrd/Optimizer.cpp index 9171420f35..74ef4b79d5 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 = nodeAs(node); CastNode* const cast = nodeAs(node); @@ -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) @@ -699,7 +699,7 @@ void OptimizerRetrieval::analyzeNavigation() if (idx->idx_flags & idx_expressn) { - if (!checkExpressionIndex(idx, node, stream)) + if (!checkExpressionIndex(csb, idx, node, stream)) { usableIndex = false; break; @@ -1673,11 +1673,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; @@ -2193,7 +2193,7 @@ InversionCandidate* OptimizerRetrieval::matchOnIndexes( { BoolExprNode* condition = binaryNode->arg2; - if (condition->computable(csb, INVALID_STREAM, false) && !condition->findStream(stream)) + if (condition->computable(csb, INVALID_STREAM, false) && !condition->findStream(csb, stream)) { if (invCandidate1->condition) { @@ -2214,7 +2214,7 @@ InversionCandidate* OptimizerRetrieval::matchOnIndexes( { BoolExprNode* condition = binaryNode->arg1; - if (condition->computable(csb, INVALID_STREAM, false) && !condition->findStream(stream)) + if (condition->computable(csb, INVALID_STREAM, false) && !condition->findStream(csb, stream)) { if (invCandidate2->condition) { @@ -2384,13 +2384,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/Optimizer.h b/src/jrd/Optimizer.h index 8b8061a45a..bf84a03b6a 100644 --- a/src/jrd/Optimizer.h +++ b/src/jrd/Optimizer.h @@ -161,6 +161,11 @@ public: bool outer, bool inner, SortNode* sortNode); ~OptimizerRetrieval(); + MemoryPool& getPool() const + { + return pool; + } + InversionCandidate* getInversion() { createIndexScanNodes = true; diff --git a/src/jrd/RecordSourceNodes.cpp b/src/jrd/RecordSourceNodes.cpp index dce5470d85..4b96995d56 100644 --- a/src/jrd/RecordSourceNodes.cpp +++ b/src/jrd/RecordSourceNodes.cpp @@ -50,7 +50,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); @@ -221,11 +221,13 @@ MapNode* MapNode::pass2(thread_db* tdbb, CompilerScratch* csb) PlanNode* PlanNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - PlanNode* node = FB_NEW_POOL(getPool()) PlanNode(getPool(), type); + MemoryPool& pool = dsqlScratch->getPool(); + + PlanNode* node = FB_NEW_POOL(pool) PlanNode(pool, type); if (accessType) { - node->accessType = FB_NEW_POOL(getPool()) AccessType(getPool(), accessType->type); + node->accessType = FB_NEW_POOL(pool) AccessType(pool, accessType->type); node->accessType->items = accessType->items; } @@ -236,14 +238,14 @@ PlanNode* PlanNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (dsqlNames) { - node->dsqlNames = FB_NEW_POOL(getPool()) ObjectsArray(getPool()); + node->dsqlNames = FB_NEW_POOL(pool) ObjectsArray(pool); *node->dsqlNames = *dsqlNames; dsql_ctx* context = dsqlPassAliasList(dsqlScratch); if (context->ctx_relation) { - RelationSourceNode* relNode = FB_NEW_POOL(getPool()) RelationSourceNode(getPool()); + RelationSourceNode* relNode = FB_NEW_POOL(pool) RelationSourceNode(pool); relNode->dsqlContext = context; node->dsqlRecordSourceNode = relNode; } @@ -251,7 +253,7 @@ PlanNode* PlanNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { // ASF: Note that usage of procedure name in a PLAN clause causes errors when // parsing the BLR. - ProcedureSourceNode* procNode = FB_NEW_POOL(getPool()) ProcedureSourceNode(getPool()); + ProcedureSourceNode* procNode = FB_NEW_POOL(pool) ProcedureSourceNode(pool); procNode->dsqlContext = context; node->dsqlRecordSourceNode = procNode; } @@ -312,7 +314,7 @@ dsql_ctx* PlanNode::dsqlPassAliasList(DsqlCompilerScratch* dsqlScratch) { // AB: Pretty ugly huh? // make up a dummy context to hold the resultant relation. - dsql_ctx* newContext = FB_NEW_POOL(getPool()) dsql_ctx(getPool()); + dsql_ctx* newContext = FB_NEW_POOL(dsqlScratch->getPool()) dsql_ctx(dsqlScratch->getPool()); newContext->ctx_context = context->ctx_context; newContext->ctx_relation = relation; @@ -425,20 +427,20 @@ RecSourceListNode::RecSourceListNode(MemoryPool& pool, unsigned count) items.resize(count); for (unsigned i = 0; i < count; ++i) - addDsqlChildNode((items[i] = NULL)); + items[i] = NULL; } RecSourceListNode::RecSourceListNode(MemoryPool& pool, RecordSourceNode* arg1) : TypedNode(pool), items(pool) { - items.resize(1); - addDsqlChildNode((items[0] = arg1)); + items.push(arg1); } RecSourceListNode* RecSourceListNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - RecSourceListNode* node = FB_NEW_POOL(getPool()) RecSourceListNode(getPool(), items.getCount()); + RecSourceListNode* node = FB_NEW_POOL(dsqlScratch->getPool()) RecSourceListNode(dsqlScratch->getPool(), + items.getCount()); NestConst* dst = node->items.begin(); @@ -558,7 +560,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 = nodeAs(other); return o && dsqlContext == o->dsqlContext; @@ -741,7 +744,7 @@ void RelationSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseN viewRse->rse_sorted || viewRse->rse_projection || viewRse->rse_first || viewRse->rse_skip || viewRse->rse_plan) { - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); RseNode* copy = viewRse->copy(tdbb, copier); DEBUG; doPass1(tdbb, csb, ©); @@ -768,7 +771,7 @@ void RelationSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseN for (const NestConst* const end = viewRse->rse_relations.end(); arg != end; ++arg) { // this call not only copies the node, it adds any streams it finds to the map - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); RecordSourceNode* node = (*arg)->copy(tdbb, copier); // Now go out and process the base table itself. This table might also be a view, @@ -786,7 +789,7 @@ void RelationSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseN if (viewRse->rse_projection) { - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); rse->rse_projection = viewRse->rse_projection->copy(tdbb, copier); doPass1(tdbb, csb, rse->rse_projection.getAddress()); } @@ -796,7 +799,7 @@ void RelationSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseN if (viewRse->rse_boolean) { - NodeCopier copier(csb, map); + NodeCopier copier(csb->csb_pool, csb, map); BoolExprNode* node = copier.copy(tdbb, viewRse->rse_boolean); doPass1(tdbb, csb, &node); @@ -1026,7 +1029,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 = nodeAs(other); return o && dsqlContext == o->dsqlContext; @@ -1252,15 +1256,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); } @@ -1329,13 +1333,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 = nodeAs(other); 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) @@ -1598,7 +1602,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 @@ -1966,7 +1970,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)); @@ -2363,7 +2367,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 window = windows.begin(); window != windows.end(); @@ -2493,7 +2497,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 = nodeAs(other); @@ -2503,7 +2507,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). @@ -2513,6 +2517,7 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) // that it includes system (e.g. trigger) contexts (if present), // as well as any outer (from other levels) contexts. + MemoryPool& pool = dsqlScratch->getPool(); DsqlContextStack* const base_context = dsqlScratch->context; DsqlContextStack temp; dsqlScratch->context = &temp; @@ -2530,10 +2535,10 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) const size_t visibleContexts = temp.getCount(); RecSourceListNode* fromList = dsqlFrom; - RecSourceListNode* streamList = FB_NEW_POOL(getPool()) RecSourceListNode( - getPool(), fromList->items.getCount()); + RecSourceListNode* streamList = FB_NEW_POOL(pool) RecSourceListNode( + pool, fromList->items.getCount()); - RseNode* node = FB_NEW_POOL(getPool()) RseNode(getPool()); + RseNode* node = FB_NEW_POOL(pool) RseNode(pool); node->dsqlExplicitJoin = dsqlExplicitJoin; node->rse_jointype = rse_jointype; node->dsqlStreams = streamList; @@ -2582,13 +2587,13 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) Arg::Gds(isc_dsql_unsupp_feature_dialect) << Arg::Num(dsqlScratch->clientDialect)); } - ValueListNode leftStack(dsqlScratch->getPool(), 0u); - ValueListNode rightStack(dsqlScratch->getPool(), 0u); + ValueListNode leftStack(pool, 0u); + ValueListNode rightStack(pool, 0u); if (usingList->items.isEmpty()) // NATURAL JOIN { - StrArray leftNames(dsqlScratch->getPool()); - ValueListNode* matched = FB_NEW_POOL(getPool()) ValueListNode(getPool(), 0u); + StrArray leftNames(pool); + ValueListNode* matched = FB_NEW_POOL(pool) ValueListNode(pool, 0u); PASS1_expand_select_node(dsqlScratch, streamList->items[0], &leftStack, true); PASS1_expand_select_node(dsqlScratch, streamList->items[1], &rightStack, true); @@ -2635,7 +2640,7 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (usingList) // JOIN ... USING { BoolExprNode* newBoolean = NULL; - StrArray usedColumns(dsqlScratch->getPool()); + StrArray usedColumns(pool); for (FB_SIZE_T i = 0; i < usingList->items.getCount(); ++i) { @@ -2669,7 +2674,7 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) ValueExprNode* arg2 = resolveUsingField(dsqlScratch, field->dsqlName, &rightStack, field, "right", rightCtx); - ComparativeBoolNode* eqlNode = FB_NEW_POOL(getPool()) ComparativeBoolNode(getPool(), + ComparativeBoolNode* eqlNode = FB_NEW_POOL(pool) ComparativeBoolNode(pool, blr_eql, arg1, arg2); fb_assert(leftCtx); @@ -2679,7 +2684,7 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) ImplicitJoin* impJoinLeft; if (!leftCtx->ctx_imp_join.get(field->dsqlName, impJoinLeft)) { - impJoinLeft = FB_NEW_POOL(dsqlScratch->getPool()) ImplicitJoin(); + impJoinLeft = FB_NEW_POOL(pool) ImplicitJoin(); impJoinLeft->value = eqlNode->arg1; impJoinLeft->visibleInContext = leftCtx; } @@ -2689,14 +2694,14 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) ImplicitJoin* impJoinRight; if (!rightCtx->ctx_imp_join.get(field->dsqlName, impJoinRight)) { - impJoinRight = FB_NEW_POOL(dsqlScratch->getPool()) ImplicitJoin(); + impJoinRight = FB_NEW_POOL(pool) ImplicitJoin(); impJoinRight->value = arg2; } else fb_assert(impJoinRight->visibleInContext == rightCtx); // create the COALESCE - ValueListNode* stack = FB_NEW_POOL(getPool()) ValueListNode(getPool(), 0u); + ValueListNode* stack = FB_NEW_POOL(pool) ValueListNode(pool, 0u); NestConst tempNode = impJoinLeft->value; NestConst aliasNode = nodeAs(tempNode); @@ -2742,9 +2747,9 @@ RseNode* RseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) stack->add(doDsqlPass(dsqlScratch, tempNode)); } - coalesceNode = FB_NEW_POOL(getPool()) CoalesceNode(getPool(), stack); + coalesceNode = FB_NEW_POOL(pool) CoalesceNode(pool, stack); - aliasNode = FB_NEW_POOL(getPool()) DsqlAliasNode(getPool(), field->dsqlName, coalesceNode); + aliasNode = FB_NEW_POOL(pool) DsqlAliasNode(pool, field->dsqlName, coalesceNode); aliasNode->implicitJoin = impJoinLeft; impJoinLeft->value = aliasNode; @@ -3367,27 +3372,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); } @@ -3653,12 +3658,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) { @@ -3674,7 +3677,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) { @@ -3779,7 +3782,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]; @@ -3787,7 +3790,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 b3d75d5959..787d30c7dd 100644 --- a/src/jrd/RecordSourceNodes.h +++ b/src/jrd/RecordSourceNodes.h @@ -295,7 +295,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; @@ -377,7 +377,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; @@ -406,7 +406,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); @@ -470,7 +470,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; @@ -624,7 +624,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 { @@ -673,19 +673,11 @@ public: rse_relations(pool), flags(0) { - addDsqlChildNode(dsqlStreams); - addDsqlChildNode(dsqlWhere); - addDsqlChildNode(dsqlJoinUsing); - addDsqlChildNode(dsqlOrder); - addDsqlChildNode(dsqlDistinct); - addDsqlChildNode(dsqlSelectList); - addDsqlChildNode(dsqlFirst); - addDsqlChildNode(dsqlSkip); } - RseNode* clone() + RseNode* clone(MemoryPool& pool) { - RseNode* obj = FB_NEW_POOL(getPool()) RseNode(getPool()); + RseNode* obj = FB_NEW_POOL(pool) RseNode(pool); obj->dsqlFirst = dsqlFirst; obj->dsqlSkip = dsqlSkip; @@ -717,6 +709,23 @@ public: return obj; } + virtual void getChildren(NodeRefsHolder& holder, bool dsql) const + { + RecordSourceNode::getChildren(holder, dsql); + + if (dsql) + { + holder.add(dsqlStreams); + holder.add(dsqlWhere); + holder.add(dsqlJoinUsing); + holder.add(dsqlOrder); + holder.add(dsqlDistinct); + holder.add(dsqlSelectList); + holder.add(dsqlFirst); + holder.add(dsqlSkip); + } + } + virtual Firebird::string internalPrint(NodePrinter& printer) const; virtual bool dsqlAggregateFinder(AggregateFinder& visitor); virtual bool dsqlAggregate2Finder(Aggregate2Finder& visitor); @@ -725,7 +734,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; @@ -748,7 +757,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/cmp.cpp b/src/jrd/cmp.cpp index 150d132453..9afe800e2e 100644 --- a/src/jrd/cmp.cpp +++ b/src/jrd/cmp.cpp @@ -106,7 +106,7 @@ IMPLEMENT_TRACE_ROUTINE(cmp_trace, "CMP") // Clone a node. ValueExprNode* CMP_clone_node(thread_db* tdbb, CompilerScratch* csb, ValueExprNode* node) { - SubExprNodeCopier copier(csb); + SubExprNodeCopier copier(csb->csb_pool, csb); return copier.copy(tdbb, node); } @@ -123,7 +123,7 @@ ValueExprNode* CMP_clone_node_opt(thread_db* tdbb, CompilerScratch* csb, ValueEx if (nodeIs(node)) return node; - SubExprNodeCopier copier(csb); + SubExprNodeCopier copier(csb->csb_pool, csb); ValueExprNode* clone = copier.copy(tdbb, node); ExprNode::doPass2(tdbb, csb, &clone); @@ -136,7 +136,7 @@ BoolExprNode* CMP_clone_node_opt(thread_db* tdbb, CompilerScratch* csb, BoolExpr DEV_BLKCHK(csb, type_csb); - SubExprNodeCopier copier(csb); + SubExprNodeCopier copier(csb->csb_pool, csb); BoolExprNode* clone = copier.copy(tdbb, node); ExprNode::doPass2(tdbb, csb, &clone); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index c9186f910b..1862cf3893 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -1267,7 +1267,8 @@ const StmtNode* EXE_looper(thread_db* tdbb, jrd_req* request, const StmtNode* no SET_TDBB(tdbb); Database* dbb = tdbb->getDatabase(); - if (!node || node->kind != DmlNode::KIND_STATEMENT) + // ASF: It's already a StmtNode, so do not do a virtual call in execution. + if (!node) /// if (!node || node->getKind() != DmlNode::KIND_STATEMENT BUGCHECK(147); // Save the old pool and request to restore on exit diff --git a/src/jrd/met.epp b/src/jrd/met.epp index d2ea63e105..6a649a177d 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -3826,7 +3826,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation) if (rseNode) { - fb_assert(rseNode->kind == DmlNode::KIND_REC_SOURCE); + fb_assert(rseNode->getKind() == DmlNode::KIND_REC_SOURCE); relation->rel_view_rse = static_cast(rseNode); fb_assert(relation->rel_view_rse->type == RseNode::TYPE); } diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index c6f1bfd131..9b3dbfa63f 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; @@ -288,7 +288,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); @@ -467,7 +467,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; @@ -517,7 +517,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 @@ -1000,7 +1000,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) { /************************************** * @@ -1187,7 +1187,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. @@ -2286,7 +2286,7 @@ static RecordSource* gen_retrieval(thread_db* tdbb, if (inversion && condition && (!condition->computable(csb, INVALID_STREAM, false) || - condition->findStream(stream))) + condition->findStream(csb, stream))) { fb_assert(false); inversion = NULL; @@ -2354,7 +2354,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); @@ -2797,9 +2797,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; @@ -2813,7 +2813,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/par.cpp b/src/jrd/par.cpp index 4ad3dff4a6..99fc60c1ec 100644 --- a/src/jrd/par.cpp +++ b/src/jrd/par.cpp @@ -177,7 +177,7 @@ namespace *tdbb->getDefaultPool()); DmlNode* relationNode = PAR_parse_node(tdbb, csb); - if (relationNode->kind != DmlNode::KIND_REC_SOURCE) + if (relationNode->getKind() != DmlNode::KIND_REC_SOURCE) PAR_syntax_error(csb, "TABLE"); RelationSourceNode* relationSource = static_cast(relationNode); @@ -1482,7 +1482,7 @@ BoolExprNode* PAR_parse_boolean(thread_db* tdbb, CompilerScratch* csb) { DmlNode* node = PAR_parse_node(tdbb, csb); - if (node->kind != DmlNode::KIND_BOOLEAN) + if (node->getKind() != DmlNode::KIND_BOOLEAN) PAR_syntax_error(csb, "boolean"); return static_cast(node); @@ -1493,7 +1493,7 @@ ValueExprNode* PAR_parse_value(thread_db* tdbb, CompilerScratch* csb) { DmlNode* node = PAR_parse_node(tdbb, csb); - if (node->kind != DmlNode::KIND_VALUE) + if (node->getKind() != DmlNode::KIND_VALUE) PAR_syntax_error(csb, "value"); return static_cast(node); @@ -1504,7 +1504,7 @@ StmtNode* PAR_parse_stmt(thread_db* tdbb, CompilerScratch* csb) { DmlNode* node = PAR_parse_node(tdbb, csb); - if (node->kind != DmlNode::KIND_STATEMENT) + if (node->getKind() != DmlNode::KIND_STATEMENT) PAR_syntax_error(csb, "statement"); return static_cast(node); @@ -1561,7 +1561,7 @@ DmlNode* PAR_parse_node(thread_db* tdbb, CompilerScratch* csb) DmlNode* node = blr_parsers[blr_operator](tdbb, *tdbb->getDefaultPool(), csb, blr_operator); FB_SIZE_T pos = 0; - if (node->kind == DmlNode::KIND_STATEMENT && csb->csb_dbg_info->blrToSrc.find(blr_offset, pos)) + if (node->getKind() == DmlNode::KIND_STATEMENT && csb->csb_dbg_info->blrToSrc.find(blr_offset, pos)) { MapBlrToSrcItem& i = csb->csb_dbg_info->blrToSrc[pos]; StmtNode* stmt = static_cast(node); 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;