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

Fixed CORE-5611 and CORE-5646 - pull request #114

- CORE-5611 - Higher memory consumption for prepared statements in FB3.
- CORE-5646 - Parse error when compiling a statement causes memory leak until attachment is disconnected.
This commit is contained in:
Adriano dos Santos Fernandes 2017-11-26 20:20:02 -02:00 committed by GitHub
commit 9f834aba16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1366 additions and 899 deletions

View File

@ -56,13 +56,12 @@ AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool
ValueExprNode* aArg)
: TypedNode<ValueExprNode, ExprNode::TYPE_AGGREGATE>(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<USHORT> autoDeepestLevel(&visitor.deepestLevel, 0);
AutoSetRestore<bool> 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<USHORT> 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<AggNode>(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<SumAggNode> 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));
}

View File

@ -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);

View File

@ -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<BinaryBoolNode>(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<BinaryBoolNode>(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<ComparativeBoolNode>(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<ComparativeBoolNode>(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<RecordSourceNode*>(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<BoolExprNode, ExprNode::TYPE_NOT_BOOL>(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<NotBoolNode>(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<SelectExprNode>(dsqlRse), false));
// Finish off by cleaning up contexts
@ -1660,9 +1655,9 @@ void RseBoolNode::genBlr(DsqlCompilerScratch* dsqlScratch)
GEN_rse(dsqlScratch, nodeAs<RseNode>(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<RseBoolNode>(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<RseBoolNode>(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<BoolExprNode*>(newNode));
}

View File

@ -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);

View File

@ -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<CreateDropConstraint>& 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);
}

View File

@ -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<BlrWriter> blrWritersHolder;
};
struct CreateDropConstraint : public PermanentStorage
struct CreateDropConstraint
{
explicit CreateDropConstraint(MemoryPool& p)
: PermanentStorage(p),
name(p)
: name(p)
{
}
@ -1230,7 +1228,7 @@ public:
Firebird::AutoPtr<Constraint> 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;

View File

@ -896,7 +896,7 @@ RseNode* DsqlCompilerScratch::pass1RseIsRecursive(RseNode* input)
{
fb_assert(rseNode->dsqlExplicitJoin);
RseNode* dstRse = rseNode->clone();
RseNode* dstRse = rseNode->clone(getPool());
*pDstTable = dstRse;

File diff suppressed because it is too large Load Diff

View File

@ -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<ValueExprNode, ExprNode::TYPE_COALESCE>(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<ValueExprNode, ExprNode::TYPE_COLLATE>
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<SLONG*>(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<ValueExprNode> 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<Frame>(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<FrameExtent>(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<WindowClause>(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;

View File

@ -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 <typename T> void add(const NestConst<T>& node);
public:
Firebird::HalfStaticArray<NodeRef*, 8> 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 <typename T> 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 <typename T1, typename T2>
void addChildNode(NestConst<T1>& dsqlNode, NestConst<T2>& jrdNode)
{
addDsqlChildNode(dsqlNode);
addChildNode(jrdNode);
}
template <typename T>
void addDsqlChildNode(NestConst<T>& dsqlNode)
{
dsqlChildNodes.add(FB_NEW_POOL(getPool()) NodeRefImpl<T>(dsqlNode.getAddress()));
}
template <typename T>
void addChildNode(NestConst<T>& jrdNode)
{
jrdChildNodes.add(FB_NEW_POOL(getPool()) NodeRefImpl<T>(jrdNode.getAddress()));
}
public:
const Type type;
unsigned nodFlags;
ULONG impureOffset;
const char* dsqlCompatDialectVerb;
Firebird::Array<NodeRef*> dsqlChildNodes;
Firebird::Array<NodeRef*> jrdChildNodes;
};
@ -749,14 +744,26 @@ inline void NodeRefImpl<T>::internalPass2(thread_db* tdbb, CompilerScratch* csb)
}
template <typename T>
inline void NodeRefsHolder::add(const NestConst<T>& node)
{
refs.add(FB_NEW_POOL(getPool()) NodeRefImpl<T>(const_cast<T**>(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<ValueExprNode> 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<ListExprNode, ExprNode::TYPE_VALUE_LIST>
public:
ValueListNode(MemoryPool& pool, unsigned count)
: TypedNode<ListExprNode, ExprNode::TYPE_VALUE_LIST>(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<ListExprNode, ExprNode::TYPE_VALUE_LIST>(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<ValueExprNode>* 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<ValueExprNode>* 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<NestConst<RecordSourceNode> > 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<StreamType> 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.

View File

@ -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<Signature> existingFuncs(getPool());
SortedObjectsArray<Signature> existingProcs(getPool());
SortedObjectsArray<Signature> existingFuncs(pool);
SortedObjectsArray<Signature> existingProcs(pool);
collectPackagedItems(tdbb, transaction, name, existingFuncs, existingProcs, false);
for (SortedObjectsArray<Signature>::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<Signature> existingFuncs(getPool());
SortedObjectsArray<Signature> existingProcs(getPool());
SortedObjectsArray<Signature> existingFuncs(pool);
SortedObjectsArray<Signature> existingProcs(pool);
collectPackagedItems(tdbb, transaction, name, existingFuncs, existingProcs, false);
for (SortedObjectsArray<Signature>::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<Signature>::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<Signature> headerFuncs(getPool());
SortedObjectsArray<Signature> headerProcs(getPool());
SortedObjectsArray<Signature> headerFuncs(pool);
SortedObjectsArray<Signature> headerProcs(pool);
collectPackagedItems(tdbb, transaction, name, headerFuncs, headerProcs, false);
SortedObjectsArray<Signature> existingFuncs(getPool());
SortedObjectsArray<Signature> existingProcs(getPool());
SortedObjectsArray<Signature> existingFuncs(pool);
SortedObjectsArray<Signature> existingProcs(pool);
// process declaredItems and items
Array<CreateAlterPackageNode::Item>* arrays[] = {declaredItems, items};
@ -803,15 +811,15 @@ void CreatePackageBodyNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
}
}
SortedObjectsArray<Signature> newFuncs(getPool());
SortedObjectsArray<Signature> newProcs(getPool());
SortedObjectsArray<Signature> newFuncs(pool);
SortedObjectsArray<Signature> newProcs(pool);
collectPackagedItems(tdbb, transaction, name, newFuncs, newProcs, true);
for (SortedObjectsArray<Signature>::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);

View File

@ -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*);

View File

@ -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<StmtNode>* 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<RelationSourceNode> 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<ValueExprNode>* 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<ParameterClause>* 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<SavepointEncloseNode>(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<SavepointEncloseNode>(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<ValueExprNode>* ptr = input->items.begin();
NestConst<ValueExprNode>* 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<AssignmentNode>(*ptr);
if (assign)
dsqlSetParameterName(assign->asgnFrom, assign->asgnTo, relation);
dsqlSetParameterName(dsqlScratch, assign->asgnFrom, assign->asgnTo, relation);
else
{
fb_assert(false);
}
}
}

View File

@ -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, "<column reference>".
// 2) The <search condition> shall not contain a <window function> without an intervening
// <query expression>.
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 <typename T>
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 <typename T>
static T* copy(thread_db* tdbb, CompilerScratch* csb, const NestConst<T>& 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)

View File

@ -50,9 +50,6 @@ static WinFuncNode::RegisterFactory0<DenseRankWinNode> 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<CumeDistWinNode> 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<RowNumberWinNode> 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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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<DsqlCompiledStatement*> 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,

View File

@ -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<ValueExprNode*>(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));
}
}
}

View File

@ -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++;

View File

@ -792,10 +792,10 @@ top
%type <dsqlReq> statement
statement
: dml_statement { $$ = newNode<DsqlDmlRequest>($1); }
| ddl_statement { $$ = newNode<DsqlDdlRequest>($1); }
| tra_statement { $$ = newNode<DsqlTransactionRequest>($1); }
| mng_statement { $$ = newNode<DsqlSessionManagementRequest>($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 <stmtNode> dml_statement

View File

@ -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<ValueExprNode>* ptr = list->items.begin();
for (const NestConst<ValueExprNode>* 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<DsqlMapNode>(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<DsqlAliasNode>(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<RseNode>(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<ValueExprNode*>(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<ValueExprNode>* ptr = valueList->items.begin();
for (const NestConst<ValueExprNode>* 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<ValueExprNode>* ptr = valueList->items.begin();
for (const NestConst<ValueExprNode>* 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<ValueExprNode>* ptr = valueList->items.begin();
for (const NestConst<ValueExprNode>* 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<ValueExprNode>* ptr = valueList->items.begin();
for (const NestConst<ValueExprNode>* 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;
}

View File

@ -49,7 +49,7 @@ void PASS1_limit(Jrd::DsqlCompilerScratch*, NestConst<Jrd::ValueExprNode>,
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*);

View File

@ -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

View File

@ -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<StmtNode*>(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<StmtNode**>(&csb->csb_node), NULL);
else
ExprNode::doPass2(tdbb, csb, &csb->csb_node);

View File

@ -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<DerivedExprNode>(node);
CastNode* const cast = nodeAs<CastNode>(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;

View File

@ -161,6 +161,11 @@ public:
bool outer, bool inner, SortNode* sortNode);
~OptimizerRetrieval();
MemoryPool& getPool() const
{
return pool;
}
InversionCandidate* getInversion()
{
createIndexScanNodes = true;

View File

@ -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<MetaName>(getPool());
node->dsqlNames = FB_NEW_POOL(pool) ObjectsArray<MetaName>(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<ListExprNode, ExprNode::TYPE_REC_SOURCE_LIST>(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<RecordSourceNode>* 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<RelationSourceNode>(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, &copy);
@ -768,7 +771,7 @@ void RelationSourceNode::pass1Source(thread_db* tdbb, CompilerScratch* csb, RseN
for (const NestConst<RecordSourceNode>* 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<ProcedureSourceNode>(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<AggregateSourceNode>(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<Window>::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<RseNode>(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<ValueExprNode> tempNode = impJoinLeft->value;
NestConst<DsqlAliasNode> aliasNode = nodeAs<DsqlAliasNode>(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<RecordSourceNode>* ptr;
const NestConst<RecordSourceNode>* 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];
}
}

View File

@ -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);

View File

@ -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<ParameterNode>(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);

View File

@ -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

View File

@ -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*>(rseNode);
fb_assert(relation->rel_view_rse->type == RseNode::TYPE);
}

View File

@ -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)
{

View File

@ -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<RelationSourceNode*>(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<BoolExprNode*>(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<ValueExprNode*>(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<StmtNode*>(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<StmtNode*>(node);

View File

@ -55,7 +55,8 @@ class OptimizerBlk : public pool_alloc<type_opt>
{
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_conjunct, OPT_STATIC_ITEMS> opt_conjuncts;
Firebird::HalfStaticArray<opt_stream, OPT_STATIC_ITEMS> opt_streams;