CFunctionProp
CFunctionProp代表了function properties函数属性,主要由function stability函数易变性( enum EFuncStbl { EfsImmutable, /* never changes for given input */ EfsStable, /* does not change within a scan */ EfsVolatile, /* can change even within a scan */ EfsSentinel };
)、表达式是否含有volatile函数扫描标志m_fHasVolatileFunctionScan、函数是否用作scan operator标志m_fScan成员组成。其中函数易变性EFuncStbl是最关键的function properties。
//---------------------------------------------------------------------------
// @class:
// CFunctionProp
// @doc:
// Representation of function properties
//---------------------------------------------------------------------------
class CFunctionProp : public CRefCount {
private: IMDFunction::EFuncStbl m_efs; // function stability BOOL m_fHasVolatileFunctionScan; // does this expression have a volatile Function Scan BOOL m_fScan; // is this function used as a scan operatorCFunctionProp(const CFunctionProp &); // hidden copy ctor
public: CFunctionProp(IMDFunction::EFuncStbl func_stability, BOOL fHasVolatileFunctionScan, BOOL fScan); // ctor virtual ~CFunctionProp(); // dtor IMDFunction::EFuncStbl Efs() const { return m_efs; } // function stabilityvirtual BOOL FHasVolatileFunctionScan() const { return m_fHasVolatileFunctionScan; } // does this expression have a volatile Function Scan BOOL NeedsSingletonExecution() const; // check if must execute on a single host IOstream &OsPrint(IOstream &os) const; // print}; // class CFunctionProp//---------------------------------------------------------------------------
// @function:
// CFunctionProp::SingletonExecution
// @doc:
// Check if must execute on a single host based on function properties
//---------------------------------------------------------------------------
BOOL CFunctionProp::NeedsSingletonExecution() const {// a function needs to execute on a single host if any of the following holds:// a) it reads or modifies SQL data// b) it is volatile and used as a scan operator (i.e. in the from clause)// TODO: - Feb 10, 2014; enable the following line instead of the// current return statement once all function properties are fixed//return (IMDFunction::EfdaContainsSQL < m_efda || (m_fScan && IMDFunction::EfsVolatile == m_efs));return m_fScan && (IMDFunction::EfsVolatile == m_efs || IMDFunction::EfsStable == m_efs);
}
其中NeedsSingletonExecution函数用于检查function properties指明该函数只能在single host上执行。这种函数有如下之一的特征:a) it reads or modifies SQL data b) it is volatile and used as a scan operator (i.e. in the from clause)。
COperator
COperator作为Base class for all operators: logical, physical, scalar, patterns。其提供了两个protected的静态函数和function properties相关的函数,定义如下所示。
class COperator : public CRefCount
{
private:// private copy ctorCOperator(COperator &);protected:// operator id that is unique over all instances of all operator types// for the current queryULONG m_ulOpId;// memory pool for internal allocationsCMemoryPool *m_mp;// is pattern of xformBOOL m_fPattern;// return an addref'ed copy of the operatorvirtual COperator *PopCopyDefault();// derive stability function property from childrenstatic IMDFunction::EFuncStbl EfsDeriveFromChildren(CExpressionHandle &exprhdl, IMDFunction::EFuncStbl efsDefault);// derive function properties from childrenstatic CFunctionProp *PfpDeriveFromChildren(CMemoryPool *mp, CExpressionHandle &exprhdl,IMDFunction::EFuncStbl efsDefault, BOOL fHasVolatileFunctionScan,BOOL fScan);// generate unique operator idsstatic ULONG m_aulOpIdCounter;...
}
COperator::EfsDeriveFromChildren函数用于从子表达式中提取stability function property函数易变属性。从代码实现可以看出其也是通过CExpressionHandle接口来获取对应子表达式的CFunctionProp function properties,从而获取其易变属性值的。从逻辑实现来看EfsImmutable, /* never changes for given input */ EfsStable, /* does not change within a scan */ EfsVolatile, /* can change even within a scan */ EfsSentinel
只要子表达式中的函数出现易变属性,将会掩盖其他函数的非易变属性。
//---------------------------------------------------------------------------
// @function:
// COperator::EfsDeriveFromChildren
// @doc:
// Derive stability function property from child expressions
//---------------------------------------------------------------------------
IMDFunction::EFuncStbl COperator::EfsDeriveFromChildren(CExpressionHandle &exprhdl, IMDFunction::EFuncStbl efsDefault) {IMDFunction::EFuncStbl efs = efsDefault;const ULONG arity = exprhdl.Arity();for (ULONG ul = 0; ul < arity; ul++){IMDFunction::EFuncStbl efsChild = exprhdl.PfpChild(ul)->Efs();if (efsChild > efs){efs = efsChild;}}return efs;
}
而COperator::PfpDeriveFromChildren则是调用EfsDeriveFromChildren函数获取易变属性,然后调用CFunctionProp构造函数创建函数属性变量。
//---------------------------------------------------------------------------
// @function:
// COperator::PfpDeriveFromChildren
// @doc:
// Derive function properties from child expressions
//---------------------------------------------------------------------------
CFunctionProp *COperator::PfpDeriveFromChildren(CMemoryPool *mp, CExpressionHandle &exprhdl, IMDFunction::EFuncStbl efsDefault, BOOL fHasVolatileFunctionScan, BOOL fScan){IMDFunction::EFuncStbl efs = EfsDeriveFromChildren(exprhdl, efsDefault);return GPOS_NEW(mp) CFunctionProp(efs,fHasVolatileFunctionScan || exprhdl.FChildrenHaveVolatileFuncScan(),fScan);
}