mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 07:23:04 +01:00
Rework new aggregate functions so that they use the single blr_agg_function BLR verb.
This commit is contained in:
parent
4554ee24f5
commit
43977cc4bf
@ -48,6 +48,10 @@ using namespace Jrd;
|
|||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
|
|
||||||
|
static RegisterNode<AggNode> regAggNode(blr_agg_function);
|
||||||
|
|
||||||
|
AggNode::Factory* AggNode::factories = NULL;
|
||||||
|
|
||||||
AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
||||||
ValueExprNode* aArg)
|
ValueExprNode* aArg)
|
||||||
: TypedNode<ValueExprNode, ExprNode::TYPE_AGGREGATE>(pool),
|
: TypedNode<ValueExprNode, ExprNode::TYPE_AGGREGATE>(pool),
|
||||||
@ -61,6 +65,35 @@ AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool
|
|||||||
addChildNode(arg, arg);
|
addChildNode(arg, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DmlNode* AggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/)
|
||||||
|
{
|
||||||
|
MetaName name;
|
||||||
|
PAR_name(csb, name);
|
||||||
|
|
||||||
|
AggNode* node = NULL;
|
||||||
|
|
||||||
|
for (const Factory* factory = factories; factory; factory = factory->next)
|
||||||
|
{
|
||||||
|
if (name == factory->name)
|
||||||
|
{
|
||||||
|
node = factory->newInstance(pool);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
PAR_error(csb, Arg::Gds(isc_funnotdef) << name);
|
||||||
|
|
||||||
|
UCHAR count = csb->csb_blr_reader.getByte();
|
||||||
|
|
||||||
|
if (count != node->jrdChildNodes.getCount())
|
||||||
|
PAR_error(csb, Arg::Gds(isc_funmismat) << name);
|
||||||
|
|
||||||
|
node->parseArgs(tdbb, csb, count);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
AggNode* AggNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
AggNode* AggNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
if (dsqlScratch->isPsql())
|
if (dsqlScratch->isPsql())
|
||||||
@ -1173,10 +1206,14 @@ AggNode* MaxMinAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static AggNode::Register<StdDevAggNode> stdDevSampAggInfo("STDDEV_SAMP", blr_agg_stddev_samp);
|
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> stdDevSampAggInfo(
|
||||||
static AggNode::Register<StdDevAggNode> stdDevPopAggInfo("STDDEV_POP", blr_agg_stddev_pop);
|
"STDDEV_SAMP", StdDevAggNode::TYPE_STDDEV_SAMP);
|
||||||
static AggNode::Register<StdDevAggNode> varSampAggInfo("VAR_SAMP", blr_agg_var_samp);
|
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> stdDevPopAggInfo(
|
||||||
static AggNode::Register<StdDevAggNode> varPopAggInfo("VAR_POP", blr_agg_var_pop);
|
"STDDEV_POP", StdDevAggNode::TYPE_STDDEV_POP);
|
||||||
|
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> varSampAggInfo(
|
||||||
|
"VAR_SAMP", StdDevAggNode::TYPE_VAR_SAMP);
|
||||||
|
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> varPopAggInfo(
|
||||||
|
"VAR_POP", StdDevAggNode::TYPE_VAR_POP);
|
||||||
|
|
||||||
StdDevAggNode::StdDevAggNode(MemoryPool& pool, StdDevType aType, ValueExprNode* aArg)
|
StdDevAggNode::StdDevAggNode(MemoryPool& pool, StdDevType aType, ValueExprNode* aArg)
|
||||||
: AggNode(pool,
|
: AggNode(pool,
|
||||||
@ -1190,42 +1227,17 @@ StdDevAggNode::StdDevAggNode(MemoryPool& pool, StdDevType aType, ValueExprNode*
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StdDevAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/)
|
||||||
|
{
|
||||||
|
arg = PAR_parse_value(tdbb, csb);
|
||||||
|
}
|
||||||
|
|
||||||
void StdDevAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
void StdDevAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
||||||
{
|
{
|
||||||
AggNode::aggPostRse(tdbb, csb);
|
AggNode::aggPostRse(tdbb, csb);
|
||||||
impure2Offset = CMP_impure(csb, sizeof(StdDevImpure));
|
impure2Offset = CMP_impure(csb, sizeof(StdDevImpure));
|
||||||
}
|
}
|
||||||
|
|
||||||
DmlNode* StdDevAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
|
||||||
{
|
|
||||||
StdDevType type;
|
|
||||||
|
|
||||||
switch (blrOp)
|
|
||||||
{
|
|
||||||
case blr_agg_stddev_samp:
|
|
||||||
type = TYPE_STDDEV_SAMP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_stddev_pop:
|
|
||||||
type = TYPE_STDDEV_POP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_var_samp:
|
|
||||||
type = TYPE_VAR_SAMP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_var_pop:
|
|
||||||
type = TYPE_VAR_POP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fb_assert(false);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FB_NEW(pool) StdDevAggNode(pool, type, PAR_parse_value(tdbb, csb));
|
|
||||||
}
|
|
||||||
|
|
||||||
void StdDevAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
void StdDevAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||||
{
|
{
|
||||||
desc->makeDouble();
|
desc->makeDouble();
|
||||||
@ -1317,9 +1329,12 @@ AggNode* StdDevAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static AggNode::Register<CorrAggNode> coVarSampAggInfo("COVAR_SAMP", blr_agg_covar_samp);
|
static AggNode::RegisterFactory1<CorrAggNode, CorrAggNode::CorrType> coVarSampAggInfo(
|
||||||
static AggNode::Register<CorrAggNode> coVarPopAggInfo("COVAR_POP", blr_agg_covar_pop);
|
"COVAR_SAMP", CorrAggNode::TYPE_COVAR_SAMP);
|
||||||
static AggNode::Register<CorrAggNode> corrAggInfo("CORR", blr_agg_corr);
|
static AggNode::RegisterFactory1<CorrAggNode, CorrAggNode::CorrType> coVarPopAggInfo(
|
||||||
|
"COVAR_POP", CorrAggNode::TYPE_COVAR_POP);
|
||||||
|
static AggNode::RegisterFactory1<CorrAggNode, CorrAggNode::CorrType> corrAggInfo(
|
||||||
|
"CORR", CorrAggNode::TYPE_CORR);
|
||||||
|
|
||||||
CorrAggNode::CorrAggNode(MemoryPool& pool, CorrType aType, ValueExprNode* aArg, ValueExprNode* aArg2)
|
CorrAggNode::CorrAggNode(MemoryPool& pool, CorrType aType, ValueExprNode* aArg, ValueExprNode* aArg2)
|
||||||
: AggNode(pool,
|
: AggNode(pool,
|
||||||
@ -1334,40 +1349,18 @@ CorrAggNode::CorrAggNode(MemoryPool& pool, CorrType aType, ValueExprNode* aArg,
|
|||||||
addChildNode(arg2, arg2);
|
addChildNode(arg2, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CorrAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/)
|
||||||
|
{
|
||||||
|
arg = PAR_parse_value(tdbb, csb);
|
||||||
|
arg2 = PAR_parse_value(tdbb, csb);
|
||||||
|
}
|
||||||
|
|
||||||
void CorrAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
void CorrAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
||||||
{
|
{
|
||||||
AggNode::aggPostRse(tdbb, csb);
|
AggNode::aggPostRse(tdbb, csb);
|
||||||
impure2Offset = CMP_impure(csb, sizeof(CorrImpure));
|
impure2Offset = CMP_impure(csb, sizeof(CorrImpure));
|
||||||
}
|
}
|
||||||
|
|
||||||
DmlNode* CorrAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
|
||||||
{
|
|
||||||
CorrType type;
|
|
||||||
|
|
||||||
switch (blrOp)
|
|
||||||
{
|
|
||||||
case blr_agg_covar_samp:
|
|
||||||
type = TYPE_COVAR_SAMP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_covar_pop:
|
|
||||||
type = TYPE_COVAR_POP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_corr:
|
|
||||||
type = TYPE_CORR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fb_assert(false);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueExprNode* a1 = PAR_parse_value(tdbb, csb);
|
|
||||||
ValueExprNode* a2 = PAR_parse_value(tdbb, csb);
|
|
||||||
return FB_NEW(pool) CorrAggNode(pool, type, a1, a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CorrAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
void CorrAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||||
{
|
{
|
||||||
desc->makeDouble();
|
desc->makeDouble();
|
||||||
@ -1492,14 +1485,22 @@ AggNode* CorrAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
static AggNode::Register<RegrAggNode> regrAvgxAggInfo("REGR_AVGX", blr_agg_regr_avgx);
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrAvgxAggInfo(
|
||||||
static AggNode::Register<RegrAggNode> regrAvgyAggInfo("REGR_AVGY", blr_agg_regr_avgy);
|
"REGR_AVGX", RegrAggNode::TYPE_REGR_AVGX);
|
||||||
static AggNode::Register<RegrAggNode> regrInterceptAggInfo("REGR_INTERCEPT", blr_agg_regr_intercept);
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrAvgyAggInfo(
|
||||||
static AggNode::Register<RegrAggNode> regrR2AggInfo("REGR_R2", blr_agg_regr_r2);
|
"REGR_AVGY", RegrAggNode::TYPE_REGR_AVGY);
|
||||||
static AggNode::Register<RegrAggNode> regrSlopeAggInfo("REGR_SLOPE", blr_agg_regr_slope);
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrInterceptAggInfo(
|
||||||
static AggNode::Register<RegrAggNode> regrSxxAggInfo("REGR_SXX", blr_agg_regr_sxx);
|
"REGR_INTERCEPT", RegrAggNode::TYPE_REGR_INTERCEPT);
|
||||||
static AggNode::Register<RegrAggNode> regrSxyAggInfo("REGR_SXY", blr_agg_regr_sxy);
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrR2AggInfo(
|
||||||
static AggNode::Register<RegrAggNode> regrSyyAggInfo("REGR_SYY", blr_agg_regr_syy);
|
"REGR_R2", RegrAggNode::TYPE_REGR_R2);
|
||||||
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrSlopeAggInfo(
|
||||||
|
"REGR_SLOPE", RegrAggNode::TYPE_REGR_SLOPE);
|
||||||
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrSxxAggInfo(
|
||||||
|
"REGR_SXX", RegrAggNode::TYPE_REGR_SXX);
|
||||||
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrSxyAggInfo(
|
||||||
|
"REGR_SXY", RegrAggNode::TYPE_REGR_SXY);
|
||||||
|
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrSyyAggInfo(
|
||||||
|
"REGR_SYY", RegrAggNode::TYPE_REGR_SYY);
|
||||||
|
|
||||||
RegrAggNode::RegrAggNode(MemoryPool& pool, RegrType aType, ValueExprNode* aArg, ValueExprNode* aArg2)
|
RegrAggNode::RegrAggNode(MemoryPool& pool, RegrType aType, ValueExprNode* aArg, ValueExprNode* aArg2)
|
||||||
: AggNode(pool,
|
: AggNode(pool,
|
||||||
@ -1520,60 +1521,18 @@ RegrAggNode::RegrAggNode(MemoryPool& pool, RegrType aType, ValueExprNode* aArg,
|
|||||||
addChildNode(arg2, arg2);
|
addChildNode(arg2, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegrAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/)
|
||||||
|
{
|
||||||
|
arg = PAR_parse_value(tdbb, csb);
|
||||||
|
arg2 = PAR_parse_value(tdbb, csb);
|
||||||
|
}
|
||||||
|
|
||||||
void RegrAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
void RegrAggNode::aggPostRse(thread_db* tdbb, CompilerScratch* csb)
|
||||||
{
|
{
|
||||||
AggNode::aggPostRse(tdbb, csb);
|
AggNode::aggPostRse(tdbb, csb);
|
||||||
impure2Offset = CMP_impure(csb, sizeof(RegrImpure));
|
impure2Offset = CMP_impure(csb, sizeof(RegrImpure));
|
||||||
}
|
}
|
||||||
|
|
||||||
DmlNode* RegrAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
|
||||||
{
|
|
||||||
RegrType type;
|
|
||||||
|
|
||||||
switch (blrOp)
|
|
||||||
{
|
|
||||||
case blr_agg_regr_avgx:
|
|
||||||
type = TYPE_REGR_AVGX;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_avgy:
|
|
||||||
type = TYPE_REGR_AVGY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_intercept:
|
|
||||||
type = TYPE_REGR_INTERCEPT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_r2:
|
|
||||||
type = TYPE_REGR_R2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_slope:
|
|
||||||
type = TYPE_REGR_SLOPE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_sxx:
|
|
||||||
type = TYPE_REGR_SXX;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_sxy:
|
|
||||||
type = TYPE_REGR_SXY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case blr_agg_regr_syy:
|
|
||||||
type = TYPE_REGR_SYY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fb_assert(false);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueExprNode* a1 = PAR_parse_value(tdbb, csb);
|
|
||||||
ValueExprNode* a2 = PAR_parse_value(tdbb, csb);
|
|
||||||
return FB_NEW(pool) RegrAggNode(pool, type, a1, a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegrAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
void RegrAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||||
{
|
{
|
||||||
desc->makeDouble();
|
desc->makeDouble();
|
||||||
@ -1724,7 +1683,7 @@ AggNode* RegrAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static AggNode::Register<RegrCountAggNode> regrCountAggInfo("REGR_COUNT", blr_agg_regr_count);
|
static AggNode::RegisterFactory0<RegrCountAggNode> regrCountAggInfo("REGR_COUNT");
|
||||||
|
|
||||||
RegrCountAggNode::RegrCountAggNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aArg2)
|
RegrCountAggNode::RegrCountAggNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aArg2)
|
||||||
: AggNode(pool, regrCountAggInfo, false, false, aArg),
|
: AggNode(pool, regrCountAggInfo, false, false, aArg),
|
||||||
@ -1733,11 +1692,10 @@ RegrCountAggNode::RegrCountAggNode(MemoryPool& pool, ValueExprNode* aArg, ValueE
|
|||||||
addChildNode(arg2, arg2);
|
addChildNode(arg2, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
DmlNode* RegrCountAggNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
void RegrCountAggNode::parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned /*count*/)
|
||||||
{
|
{
|
||||||
ValueExprNode* a1 = PAR_parse_value(tdbb, csb);
|
arg = PAR_parse_value(tdbb, csb);
|
||||||
ValueExprNode* a2 = PAR_parse_value(tdbb, csb);
|
arg2 = PAR_parse_value(tdbb, csb);
|
||||||
return FB_NEW(pool) RegrCountAggNode(pool, a1, a2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegrCountAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
void RegrCountAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||||
|
@ -170,9 +170,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
explicit StdDevAggNode(MemoryPool& pool, StdDevType aType, ValueExprNode* aArg = NULL);
|
explicit StdDevAggNode(MemoryPool& pool, StdDevType aType, ValueExprNode* aArg = NULL);
|
||||||
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
|
||||||
|
|
||||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count);
|
||||||
|
|
||||||
|
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
@ -210,9 +211,9 @@ public:
|
|||||||
explicit CorrAggNode(MemoryPool& pool, CorrType aType,
|
explicit CorrAggNode(MemoryPool& pool, CorrType aType,
|
||||||
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
||||||
|
|
||||||
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count);
|
||||||
|
|
||||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
@ -257,9 +258,9 @@ public:
|
|||||||
explicit RegrAggNode(MemoryPool& pool, RegrType aType,
|
explicit RegrAggNode(MemoryPool& pool, RegrType aType,
|
||||||
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
||||||
|
|
||||||
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count);
|
||||||
|
|
||||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
virtual void aggPostRse(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
@ -287,7 +288,7 @@ public:
|
|||||||
explicit RegrCountAggNode(MemoryPool& pool,
|
explicit RegrCountAggNode(MemoryPool& pool,
|
||||||
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
ValueExprNode* aArg = NULL, ValueExprNode* aArg2 = NULL);
|
||||||
|
|
||||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
virtual void parseArgs(thread_db* tdbb, CompilerScratch* csb, unsigned count);
|
||||||
|
|
||||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
|
108
src/dsql/Nodes.h
108
src/dsql/Nodes.h
@ -818,7 +818,60 @@ protected:
|
|||||||
const UCHAR distinctBlr;
|
const UCHAR distinctBlr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Base factory to create instance of subclasses.
|
||||||
|
class Factory : public AggInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Factory(const char* aName)
|
||||||
|
: AggInfo(aName, 0, 0)
|
||||||
|
{
|
||||||
|
next = factories;
|
||||||
|
factories = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual AggNode* newInstance(MemoryPool& pool) const = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const Factory* next;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Concrete implementations for the factory.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RegisterFactory0 : public Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit RegisterFactory0(const char* aName)
|
||||||
|
: Factory(aName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AggNode* newInstance(MemoryPool& pool) const
|
||||||
|
{
|
||||||
|
return new T(pool);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Type>
|
||||||
|
class RegisterFactory1 : public Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit RegisterFactory1(const char* aName, Type aType)
|
||||||
|
: Factory(aName),
|
||||||
|
type(aType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AggNode* newInstance(MemoryPool& pool) const
|
||||||
|
{
|
||||||
|
return new T(pool, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
const Type type;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Register : public AggInfo
|
class Register : public AggInfo
|
||||||
{
|
{
|
||||||
@ -844,6 +897,8 @@ public:
|
|||||||
explicit AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
explicit AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
||||||
ValueExprNode* aArg = NULL);
|
ValueExprNode* aArg = NULL);
|
||||||
|
|
||||||
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
||||||
|
|
||||||
virtual void print(Firebird::string& text) const;
|
virtual void print(Firebird::string& text) const;
|
||||||
|
|
||||||
virtual bool dsqlAggregateFinder(AggregateFinder& visitor);
|
virtual bool dsqlAggregateFinder(AggregateFinder& visitor);
|
||||||
@ -916,6 +971,11 @@ public:
|
|||||||
virtual AggNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
virtual AggNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void parseArgs(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, unsigned count)
|
||||||
|
{
|
||||||
|
fb_assert(count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ = 0;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -925,59 +985,17 @@ public:
|
|||||||
NestConst<ValueExprNode> arg;
|
NestConst<ValueExprNode> arg;
|
||||||
const AggregateSort* asb;
|
const AggregateSort* asb;
|
||||||
bool indexed;
|
bool indexed;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Factory* factories;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Base class for window functions.
|
// Base class for window functions.
|
||||||
class WinFuncNode : public AggNode
|
class WinFuncNode : public AggNode
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
// Base factory to create instance of subclasses.
|
|
||||||
class Factory : public AggInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Factory(const char* aName)
|
|
||||||
: AggInfo(aName, 0, 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual WinFuncNode* newInstance(MemoryPool& pool) const = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
const Factory* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Concrete implementation of the factory.
|
|
||||||
template <typename T>
|
|
||||||
class Register : public Factory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Register(const char* aName)
|
|
||||||
: Factory(aName)
|
|
||||||
{
|
|
||||||
next = factories;
|
|
||||||
factories = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
WinFuncNode* newInstance(MemoryPool& pool) const
|
|
||||||
{
|
|
||||||
return new T(pool);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, ValueExprNode* aArg = NULL);
|
explicit WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, ValueExprNode* aArg = NULL);
|
||||||
|
|
||||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void parseArgs(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, unsigned count)
|
|
||||||
{
|
|
||||||
fb_assert(count == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Factory* factories;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,49 +36,16 @@ using namespace Jrd;
|
|||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
|
|
||||||
static RegisterNode<WinFuncNode> regWinFuncNode(blr_agg_function);
|
|
||||||
|
|
||||||
WinFuncNode::Factory* WinFuncNode::factories = NULL;
|
|
||||||
|
|
||||||
WinFuncNode::WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, ValueExprNode* aArg)
|
WinFuncNode::WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, ValueExprNode* aArg)
|
||||||
: AggNode(pool, aAggInfo, false, false, aArg)
|
: AggNode(pool, aAggInfo, false, false, aArg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DmlNode* WinFuncNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/)
|
|
||||||
{
|
|
||||||
MetaName name;
|
|
||||||
PAR_name(csb, name);
|
|
||||||
|
|
||||||
WinFuncNode* node = NULL;
|
|
||||||
|
|
||||||
for (const Factory* factory = factories; factory; factory = factory->next)
|
|
||||||
{
|
|
||||||
if (name == factory->name)
|
|
||||||
{
|
|
||||||
node = factory->newInstance(pool);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node)
|
|
||||||
PAR_error(csb, Arg::Gds(isc_funnotdef) << name);
|
|
||||||
|
|
||||||
UCHAR count = csb->csb_blr_reader.getByte();
|
|
||||||
|
|
||||||
if (count != node->jrdChildNodes.getCount())
|
|
||||||
PAR_error(csb, Arg::Gds(isc_funmismat) << name);
|
|
||||||
|
|
||||||
node->parseArgs(tdbb, csb, count);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<DenseRankWinNode> denseRankWinInfo("DENSE_RANK");
|
static WinFuncNode::RegisterFactory0<DenseRankWinNode> denseRankWinInfo("DENSE_RANK");
|
||||||
|
|
||||||
DenseRankWinNode::DenseRankWinNode(MemoryPool& pool)
|
DenseRankWinNode::DenseRankWinNode(MemoryPool& pool)
|
||||||
: WinFuncNode(pool, denseRankWinInfo)
|
: WinFuncNode(pool, denseRankWinInfo)
|
||||||
@ -134,7 +101,7 @@ AggNode* DenseRankWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*cons
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<RankWinNode> rankWinInfo("RANK");
|
static WinFuncNode::RegisterFactory0<RankWinNode> rankWinInfo("RANK");
|
||||||
|
|
||||||
RankWinNode::RankWinNode(MemoryPool& pool)
|
RankWinNode::RankWinNode(MemoryPool& pool)
|
||||||
: WinFuncNode(pool, rankWinInfo),
|
: WinFuncNode(pool, rankWinInfo),
|
||||||
@ -210,7 +177,7 @@ AggNode* RankWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<RowNumberWinNode> rowNumberWinInfo("ROW_NUMBER");
|
static WinFuncNode::RegisterFactory0<RowNumberWinNode> rowNumberWinInfo("ROW_NUMBER");
|
||||||
|
|
||||||
RowNumberWinNode::RowNumberWinNode(MemoryPool& pool)
|
RowNumberWinNode::RowNumberWinNode(MemoryPool& pool)
|
||||||
: WinFuncNode(pool, rowNumberWinInfo)
|
: WinFuncNode(pool, rowNumberWinInfo)
|
||||||
@ -272,7 +239,7 @@ AggNode* RowNumberWinNode::dsqlCopy(DsqlCompilerScratch* /*dsqlScratch*/) /*cons
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<FirstValueWinNode> firstValueWinInfo("FIRST_VALUE");
|
static WinFuncNode::RegisterFactory0<FirstValueWinNode> firstValueWinInfo("FIRST_VALUE");
|
||||||
|
|
||||||
FirstValueWinNode::FirstValueWinNode(MemoryPool& pool, ValueExprNode* aArg)
|
FirstValueWinNode::FirstValueWinNode(MemoryPool& pool, ValueExprNode* aArg)
|
||||||
: WinFuncNode(pool, firstValueWinInfo, aArg)
|
: WinFuncNode(pool, firstValueWinInfo, aArg)
|
||||||
@ -346,7 +313,7 @@ AggNode* FirstValueWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<LastValueWinNode> lastValueWinInfo("LAST_VALUE");
|
static WinFuncNode::RegisterFactory0<LastValueWinNode> lastValueWinInfo("LAST_VALUE");
|
||||||
|
|
||||||
LastValueWinNode::LastValueWinNode(MemoryPool& pool, ValueExprNode* aArg)
|
LastValueWinNode::LastValueWinNode(MemoryPool& pool, ValueExprNode* aArg)
|
||||||
: WinFuncNode(pool, lastValueWinInfo, aArg)
|
: WinFuncNode(pool, lastValueWinInfo, aArg)
|
||||||
@ -411,7 +378,7 @@ AggNode* LastValueWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<NthValueWinNode> nthValueWinInfo("NTH_VALUE");
|
static WinFuncNode::RegisterFactory0<NthValueWinNode> nthValueWinInfo("NTH_VALUE");
|
||||||
|
|
||||||
NthValueWinNode::NthValueWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRow,
|
NthValueWinNode::NthValueWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRow,
|
||||||
ValueExprNode* aFrom)
|
ValueExprNode* aFrom)
|
||||||
@ -603,7 +570,7 @@ dsc* LagLeadWinNode::winPass(thread_db* tdbb, jrd_req* request, SlidingWindow* w
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<LagWinNode> lagWinInfo("LAG");
|
static WinFuncNode::RegisterFactory0<LagWinNode> lagWinInfo("LAG");
|
||||||
|
|
||||||
LagWinNode::LagWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRows,
|
LagWinNode::LagWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRows,
|
||||||
ValueExprNode* aOutExpr)
|
ValueExprNode* aOutExpr)
|
||||||
@ -632,7 +599,7 @@ AggNode* LagWinNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
|
|||||||
//--------------------
|
//--------------------
|
||||||
|
|
||||||
|
|
||||||
static WinFuncNode::Register<LeadWinNode> leadWinInfo("LEAD");
|
static WinFuncNode::RegisterFactory0<LeadWinNode> leadWinInfo("LEAD");
|
||||||
|
|
||||||
LeadWinNode::LeadWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRows,
|
LeadWinNode::LeadWinNode(MemoryPool& pool, ValueExprNode* aArg, ValueExprNode* aRows,
|
||||||
ValueExprNode* aOutExpr)
|
ValueExprNode* aOutExpr)
|
||||||
|
@ -241,21 +241,5 @@ static const struct
|
|||||||
{"subfunc", function},
|
{"subfunc", function},
|
||||||
{"record_version2", byte_line},
|
{"record_version2", byte_line},
|
||||||
{"gen_id2", gen_id2}, // 210
|
{"gen_id2", gen_id2}, // 210
|
||||||
{"agg_stddev_samp", one},
|
|
||||||
{"agg_stddev_pop", one},
|
|
||||||
{"agg_var_samp", one},
|
|
||||||
{"agg_var_pop", one},
|
|
||||||
{"agg_covar_samp", two},
|
|
||||||
{"agg_covar_pop", two},
|
|
||||||
{"agg_corr", two},
|
|
||||||
{"blr_agg_regr_avgx", two},
|
|
||||||
{"blr_agg_regr_avgy", two},
|
|
||||||
{"blr_agg_regr_count", two},
|
|
||||||
{"blr_agg_regr_intercept", two},
|
|
||||||
{"blr_agg_regr_r2", two},
|
|
||||||
{"blr_agg_regr_slope", two},
|
|
||||||
{"blr_agg_regr_sxx", two},
|
|
||||||
{"blr_agg_regr_sxy", two},
|
|
||||||
{"blr_agg_regr_syy", two},
|
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
@ -407,21 +407,4 @@
|
|||||||
#define blr_record_version2 (unsigned char) 209
|
#define blr_record_version2 (unsigned char) 209
|
||||||
#define blr_gen_id2 (unsigned char) 210 // NEXT VALUE FOR generator
|
#define blr_gen_id2 (unsigned char) 210 // NEXT VALUE FOR generator
|
||||||
|
|
||||||
#define blr_agg_stddev_samp (unsigned char) 211
|
|
||||||
#define blr_agg_stddev_pop (unsigned char) 212
|
|
||||||
#define blr_agg_var_samp (unsigned char) 213
|
|
||||||
#define blr_agg_var_pop (unsigned char) 214
|
|
||||||
#define blr_agg_covar_samp (unsigned char) 215
|
|
||||||
#define blr_agg_covar_pop (unsigned char) 216
|
|
||||||
#define blr_agg_corr (unsigned char) 217
|
|
||||||
#define blr_agg_regr_avgx (unsigned char) 218
|
|
||||||
#define blr_agg_regr_avgy (unsigned char) 219
|
|
||||||
#define blr_agg_regr_count (unsigned char) 220
|
|
||||||
#define blr_agg_regr_intercept (unsigned char) 221
|
|
||||||
#define blr_agg_regr_r2 (unsigned char) 222
|
|
||||||
#define blr_agg_regr_slope (unsigned char) 223
|
|
||||||
#define blr_agg_regr_sxx (unsigned char) 224
|
|
||||||
#define blr_agg_regr_sxy (unsigned char) 225
|
|
||||||
#define blr_agg_regr_syy (unsigned char) 226
|
|
||||||
|
|
||||||
#endif // JRD_BLR_H
|
#endif // JRD_BLR_H
|
||||||
|
Loading…
Reference in New Issue
Block a user