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:
commit
9f834aba16
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
|
295
src/dsql/Nodes.h
295
src/dsql/Nodes.h
@ -38,6 +38,7 @@ class Cursor;
|
||||
class Node;
|
||||
class NodePrinter;
|
||||
class ExprNode;
|
||||
class NodeRefsHolder;
|
||||
class OptimizerBlk;
|
||||
class OptimizerRetrieval;
|
||||
class RecordSource;
|
||||
@ -101,12 +102,11 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Node : public Firebird::PermanentStorage, public Printable
|
||||
class Node : public Printable
|
||||
{
|
||||
public:
|
||||
explicit Node(MemoryPool& pool)
|
||||
: PermanentStorage(pool),
|
||||
line(0),
|
||||
: line(0),
|
||||
column(0)
|
||||
{
|
||||
}
|
||||
@ -153,6 +153,10 @@ public:
|
||||
|
||||
virtual Firebird::string internalPrint(NodePrinter& printer) const = 0;
|
||||
|
||||
virtual void getChildren(NodeRefsHolder& holder, bool dsql) const
|
||||
{
|
||||
}
|
||||
|
||||
virtual Node* dsqlPass(DsqlCompilerScratch* /*dsqlScratch*/)
|
||||
{
|
||||
return this;
|
||||
@ -316,9 +320,8 @@ public:
|
||||
KIND_LIST
|
||||
};
|
||||
|
||||
explicit DmlNode(MemoryPool& pool, Kind aKind)
|
||||
: Node(pool),
|
||||
kind(aKind)
|
||||
explicit DmlNode(MemoryPool& pool)
|
||||
: Node(pool)
|
||||
{
|
||||
}
|
||||
|
||||
@ -332,13 +335,11 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Kind getKind() = 0;
|
||||
virtual void genBlr(DsqlCompilerScratch* dsqlScratch) = 0;
|
||||
virtual DmlNode* pass1(thread_db* tdbb, CompilerScratch* csb) = 0;
|
||||
virtual DmlNode* pass2(thread_db* tdbb, CompilerScratch* csb) = 0;
|
||||
virtual DmlNode* copy(thread_db* tdbb, NodeCopier& copier) const = 0;
|
||||
|
||||
public:
|
||||
const Kind kind;
|
||||
};
|
||||
|
||||
|
||||
@ -438,6 +439,28 @@ private:
|
||||
T** ptr;
|
||||
};
|
||||
|
||||
class NodeRefsHolder : public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
NodeRefsHolder(MemoryPool& pool)
|
||||
: PermanentStorage(pool),
|
||||
refs(pool)
|
||||
{
|
||||
}
|
||||
|
||||
~NodeRefsHolder()
|
||||
{
|
||||
for (auto& ref : refs)
|
||||
delete ref;
|
||||
}
|
||||
|
||||
public:
|
||||
template <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.
|
||||
|
@ -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);
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -161,6 +161,11 @@ public:
|
||||
bool outer, bool inner, SortNode* sortNode);
|
||||
~OptimizerRetrieval();
|
||||
|
||||
MemoryPool& getPool() const
|
||||
{
|
||||
return pool;
|
||||
}
|
||||
|
||||
InversionCandidate* getInversion()
|
||||
{
|
||||
createIndexScanNodes = true;
|
||||
|
@ -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, ©);
|
||||
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user