mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 02:03: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 {
|
||||
|
||||
|
||||
static RegisterNode<AggNode> regAggNode(blr_agg_function);
|
||||
|
||||
AggNode::Factory* AggNode::factories = NULL;
|
||||
|
||||
AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
||||
ValueExprNode* aArg)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_AGGREGATE>(pool),
|
||||
@ -61,6 +65,35 @@ AggNode::AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool
|
||||
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)
|
||||
{
|
||||
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::Register<StdDevAggNode> stdDevPopAggInfo("STDDEV_POP", blr_agg_stddev_pop);
|
||||
static AggNode::Register<StdDevAggNode> varSampAggInfo("VAR_SAMP", blr_agg_var_samp);
|
||||
static AggNode::Register<StdDevAggNode> varPopAggInfo("VAR_POP", blr_agg_var_pop);
|
||||
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> stdDevSampAggInfo(
|
||||
"STDDEV_SAMP", StdDevAggNode::TYPE_STDDEV_SAMP);
|
||||
static AggNode::RegisterFactory1<StdDevAggNode, StdDevAggNode::StdDevType> stdDevPopAggInfo(
|
||||
"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)
|
||||
: 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)
|
||||
{
|
||||
AggNode::aggPostRse(tdbb, csb);
|
||||
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)
|
||||
{
|
||||
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::Register<CorrAggNode> coVarPopAggInfo("COVAR_POP", blr_agg_covar_pop);
|
||||
static AggNode::Register<CorrAggNode> corrAggInfo("CORR", blr_agg_corr);
|
||||
static AggNode::RegisterFactory1<CorrAggNode, CorrAggNode::CorrType> coVarSampAggInfo(
|
||||
"COVAR_SAMP", CorrAggNode::TYPE_COVAR_SAMP);
|
||||
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)
|
||||
: AggNode(pool,
|
||||
@ -1334,40 +1349,18 @@ CorrAggNode::CorrAggNode(MemoryPool& pool, CorrType aType, ValueExprNode* aArg,
|
||||
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)
|
||||
{
|
||||
AggNode::aggPostRse(tdbb, csb);
|
||||
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)
|
||||
{
|
||||
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::Register<RegrAggNode> regrAvgyAggInfo("REGR_AVGY", blr_agg_regr_avgy);
|
||||
static AggNode::Register<RegrAggNode> regrInterceptAggInfo("REGR_INTERCEPT", blr_agg_regr_intercept);
|
||||
static AggNode::Register<RegrAggNode> regrR2AggInfo("REGR_R2", blr_agg_regr_r2);
|
||||
static AggNode::Register<RegrAggNode> regrSlopeAggInfo("REGR_SLOPE", blr_agg_regr_slope);
|
||||
static AggNode::Register<RegrAggNode> regrSxxAggInfo("REGR_SXX", blr_agg_regr_sxx);
|
||||
static AggNode::Register<RegrAggNode> regrSxyAggInfo("REGR_SXY", blr_agg_regr_sxy);
|
||||
static AggNode::Register<RegrAggNode> regrSyyAggInfo("REGR_SYY", blr_agg_regr_syy);
|
||||
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrAvgxAggInfo(
|
||||
"REGR_AVGX", RegrAggNode::TYPE_REGR_AVGX);
|
||||
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrAvgyAggInfo(
|
||||
"REGR_AVGY", RegrAggNode::TYPE_REGR_AVGY);
|
||||
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrInterceptAggInfo(
|
||||
"REGR_INTERCEPT", RegrAggNode::TYPE_REGR_INTERCEPT);
|
||||
static AggNode::RegisterFactory1<RegrAggNode, RegrAggNode::RegrType> regrR2AggInfo(
|
||||
"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)
|
||||
: AggNode(pool,
|
||||
@ -1520,60 +1521,18 @@ RegrAggNode::RegrAggNode(MemoryPool& pool, RegrType aType, ValueExprNode* aArg,
|
||||
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)
|
||||
{
|
||||
AggNode::aggPostRse(tdbb, csb);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
: AggNode(pool, regrCountAggInfo, false, false, aArg),
|
||||
@ -1733,11 +1692,10 @@ RegrCountAggNode::RegrCountAggNode(MemoryPool& pool, ValueExprNode* aArg, ValueE
|
||||
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);
|
||||
ValueExprNode* a2 = PAR_parse_value(tdbb, csb);
|
||||
return FB_NEW(pool) RegrCountAggNode(pool, a1, a2);
|
||||
arg = PAR_parse_value(tdbb, csb);
|
||||
arg2 = PAR_parse_value(tdbb, csb);
|
||||
}
|
||||
|
||||
void RegrCountAggNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
||||
|
@ -170,9 +170,10 @@ public:
|
||||
};
|
||||
|
||||
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 getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
@ -210,9 +211,9 @@ public:
|
||||
explicit CorrAggNode(MemoryPool& pool, CorrType aType,
|
||||
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 getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
@ -257,9 +258,9 @@ public:
|
||||
explicit RegrAggNode(MemoryPool& pool, RegrType aType,
|
||||
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 getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
@ -287,7 +288,7 @@ public:
|
||||
explicit RegrCountAggNode(MemoryPool& pool,
|
||||
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 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;
|
||||
};
|
||||
|
||||
// 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:
|
||||
// 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>
|
||||
class Register : public AggInfo
|
||||
{
|
||||
@ -844,6 +897,8 @@ public:
|
||||
explicit AggNode(MemoryPool& pool, const AggInfo& aAggInfo, bool aDistinct, bool aDialect1,
|
||||
ValueExprNode* aArg = NULL);
|
||||
|
||||
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
||||
|
||||
virtual void print(Firebird::string& text) const;
|
||||
|
||||
virtual bool dsqlAggregateFinder(AggregateFinder& visitor);
|
||||
@ -916,6 +971,11 @@ public:
|
||||
virtual AggNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
||||
|
||||
protected:
|
||||
virtual void parseArgs(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, unsigned count)
|
||||
{
|
||||
fb_assert(count == 0);
|
||||
}
|
||||
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/ = 0;
|
||||
|
||||
public:
|
||||
@ -925,59 +985,17 @@ public:
|
||||
NestConst<ValueExprNode> arg;
|
||||
const AggregateSort* asb;
|
||||
bool indexed;
|
||||
|
||||
private:
|
||||
static Factory* factories;
|
||||
};
|
||||
|
||||
|
||||
// Base class for window functions.
|
||||
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:
|
||||
// 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);
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
static RegisterNode<WinFuncNode> regWinFuncNode(blr_agg_function);
|
||||
|
||||
WinFuncNode::Factory* WinFuncNode::factories = NULL;
|
||||
|
||||
WinFuncNode::WinFuncNode(MemoryPool& pool, const AggInfo& aAggInfo, ValueExprNode* 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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)
|
||||
: 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,
|
||||
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,
|
||||
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,
|
||||
ValueExprNode* aOutExpr)
|
||||
|
@ -241,21 +241,5 @@ static const struct
|
||||
{"subfunc", function},
|
||||
{"record_version2", byte_line},
|
||||
{"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}
|
||||
};
|
||||
|
@ -407,21 +407,4 @@
|
||||
#define blr_record_version2 (unsigned char) 209
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user