| /*********************************************************************** |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| **********************************************************************/ |
| #ifndef RELMISC_H |
| #define RELMISC_H |
| /* -*-C++-*- |
| ****************************************************************************** |
| * |
| * File: RelMisc.h |
| * Description: Miscellaneous relational operators |
| * (both physical and logical operators) |
| * Created: 4/28/94 |
| * Language: C++ |
| * |
| * |
| * |
| * |
| ****************************************************************************** |
| */ |
| |
| //#include "exp_clause_derived.h" |
| #include "ObjectNames.h" |
| #include "RelExpr.h" |
| #include "SQLCLIdev.h" |
| #include "OptUtilIncludes.h" |
| #include "BinderUtils.h" |
| #include "StmtNode.h" |
| #include "LateBindInfo.h" |
| #include "SequenceGeneratorAttributes.h" |
| #include "ComSecurityKey.h" |
| #include "CmpStatement.h" |
| |
| class TrafDesc; |
| |
| // ----------------------------------------------------------------------- |
| // contents of this file |
| // ----------------------------------------------------------------------- |
| class RelRoot; |
| class Tuple; |
| class TupleList; |
| class Filter; |
| class Rename; |
| class RenameTable; |
| class RenameReference; |
| class BeforeTrigger; |
| class Refresh; |
| class MapValueIds; |
| class Pack; |
| class PhyPack; |
| class FirstN; |
| class ExtractSource; |
| class SequenceGenerator; |
| class Rowset; |
| class RowsetRowwise; |
| class RowsetInto; |
| class RowsetFor; |
| class ControlRunningQuery; |
| class CommonSubExprRef; |
| class Union; |
| |
| |
| // The following are physical operators |
| // class Tuple is both a logical and a physical operator!!! |
| |
| |
| // ----------------------------------------------------------------------- |
| // forward references |
| // ----------------------------------------------------------------------- |
| class LogicalProperty; |
| class BindWA; |
| class Generator; |
| class SearchKey; |
| class RaiseError; |
| class ItemExprList; |
| class UpdateColumns; |
| class QuerySimilarityInfo; |
| class HostArraysWA; |
| class DeltaDefinition; |
| class PipelineDef; |
| class IncrementalRefreshOption; |
| class DeltaDefinitionPtrList; |
| class NRowsClause; |
| class PipelineClause; |
| class MVInfo; |
| class MvRefreshBuilder; |
| class MvBindContext; |
| class RangePartitioningFunction; |
| class ElemDDLNode; |
| class ElemProxyColDef; |
| class ItemExprList; |
| class RtmdCompileTimeObj; |
| class HbaseAccessOptions; |
| class Union; |
| |
| // TreeStore struct |
| struct TreeStore : public NABasicObject |
| { |
| public: |
| RelExpr * rep; //rel expr ptr |
| Int32 cindex; //compressed index |
| //constructor |
| TreeStore(RelExpr * r, Int32 c){rep=r; cindex=c;} |
| }; |
| |
| // ----------------------------------------------------------------------- |
| // A RelRoot operator returns a computed expression for each of its |
| // child rows. A typical application for the RelRoot node is the SELECT |
| // list of an SQL query, like SELECT a+1, b+c, d from t; A RelRoot node |
| // also keeps a list of input variables. Both computed expressions and |
| // input variables are lists rather than sets. |
| // ----------------------------------------------------------------------- |
| |
| class RelRoot : public RelExpr |
| { |
| public: |
| |
| // constructor |
| RelRoot(RelExpr *child, |
| OperatorTypeEnum otype = REL_ROOT, |
| ItemExpr *compExpr = NULL, |
| ItemExpr *orderBy = NULL, |
| ItemExpr *updateCol = NULL, |
| RelExpr *reqdShape = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| RelRoot(RelExpr *child, |
| TransMode::AccessType at, |
| LockMode lm, |
| OperatorTypeEnum otype = REL_ROOT, |
| ItemExpr *compExpr = NULL, |
| ItemExpr *orderBy = NULL, |
| ItemExpr *updateCol = NULL, |
| RelExpr *reqdShape = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| RelRoot(const RelRoot & other); |
| |
| // virtual destructor |
| virtual ~RelRoot(); |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const; |
| |
| void setFirstNRowsParam(ItemExpr *firstNRowsParam) |
| { firstNRowsParam_ = firstNRowsParam; } |
| ItemExpr * getFirstNRowsParam() { return firstNRowsParam_; } |
| |
| // access (get and set) the count of output variables for this (dynamic) query |
| Int32 &outputVarCnt() { return outputVarCnt_; } |
| NABoolean outputVarCntValid() const { return outputVarCnt_ >= 0; } |
| |
| // get and set the input variables as a parse tree |
| void addInputVarTree(ItemExpr *inputVar); |
| ItemExpr * removeInputVarTree(); |
| |
| // add input variable to the top of tree. As of R1.5 called only for |
| // ODBC initiated dynamic rowset queries. |
| void addAtTopOfInputVarTree(ItemExpr *inputVar); |
| |
| // get and set the output variables as a parse tree |
| ItemExpr *& outputVarTree() { return outputVarTree_; } |
| void addOutputVarTree(ItemExpr *outputVar); |
| ItemExpr * removeOutputVarTree(); |
| |
| ItemExpr *& assignmentStTree() {return assignmentStTree_; } |
| void addAssignmentStTree(ItemExpr *inputOutputVar); |
| ItemExpr * removeAssignmentStTree(); |
| ItemExpr *& assignList() { return assignList_; } |
| |
| // get and set the compute predicate as a parse tree |
| ItemExpr * getCompExprTree() const { return compExprTree_; } |
| void addCompExprTree(ItemExpr *compExpr); |
| ItemExpr * removeCompExprTree(); |
| |
| // get and set the order by list as a parse tree |
| void addOrderByTree(ItemExpr *orderBy); |
| ItemExpr * removeOrderByTree(); |
| NABoolean hasOrderBy() { return orderByTree_ || reqdOrder_.entries(); } |
| ItemExpr * getOrderByTree() const { return orderByTree_; } |
| |
| // get and set the where predicate as a parse tree |
| ItemExpr * getPredExprTree() const { return predExprTree_; } |
| void addPredExprTree(ItemExpr *predExpr); |
| ItemExpr * removePredExprTree(); |
| |
| // partitioning type, TMUDF only |
| TMUDFInputPartReq getPartReqType() {return partReqType_;} |
| void setPartReqType(TMUDFInputPartReq val) {partReqType_= val;} |
| |
| // get and set the partition By set as a parse tree, TMUDF only |
| void addPartitionByTree(ItemExpr *partBy); |
| ItemExpr * removePartitionByTree(); |
| NABoolean hasPartitionBy() { return partitionByTree_ || partArrangement_.entries() ; } |
| ItemExpr * getPartitionByTree() const { return partitionByTree_; } |
| |
| // get and set the update column list as a parse tree |
| void addUpdateColTree(ItemExpr *updateCol); |
| ItemExpr * removeUpdateColTree(); |
| |
| // return a (short-lived) read/write reference to the input/output lists |
| ValueIdList & compExpr() { return compExpr_; } |
| const ValueIdList & compExpr() const { return compExpr_; } |
| void setCompExpr(const ValueIdList& c) { compExpr_ = c; } |
| |
| ValueIdList & assignmentStVars() { return assignmentStVars_; } |
| void setAssignmentStVars(const ValueIdList &c) {assignmentStVars_ = c; } |
| ValueIdList & inputVars() { return inputVars_; } |
| const ValueIdList & inputVars() const { return inputVars_; } |
| ValueIdList & outputVars() { return outputVars_; } |
| const ValueIdList & outputVars() const { return outputVars_; } |
| |
| ValueIdList & reqdOrder() { return reqdOrder_; } |
| const ValueIdList & reqdOrder() const { return reqdOrder_; } |
| |
| // TMUDF only |
| ValueIdSet & partitionArrangement() { return partArrangement_; } |
| const ValueIdSet & partitionArrangement() const { return partArrangement_; } |
| ValueIdList & updateCol() { return updateCol_; } |
| const ValueIdList & updateCol() const { return updateCol_; } |
| |
| void setReqdShape(RelExpr *shape) { reqdShape_ = shape; } |
| RelExpr *getReqdShape() const { return reqdShape_; } |
| ValueIdList &pkeyList() { return pkeyList_; } |
| ItemExpr *&currOfCursorName() { return currOfCursorName_; } |
| NABoolean &updatableSelect() { return updatableSelect_; } |
| NABoolean &updateCurrentOf() { return updateCurrentOf_; } |
| NABoolean &rollbackOnError() { return rollbackOnError_; } |
| |
| void processRownum(BindWA * bindWA); |
| |
| // a virtual function for performing name binding within the query tree |
| virtual RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // a virtual function to get addressability to the list of output values |
| virtual ItemExpr * selectList(); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| // a method used during subquery transformation for pulling up predicates |
| // towards the root of the transformed subquery tree |
| virtual void pullUpPreds(); |
| |
| // a method used for recomputing the outer references (external dataflow |
| // input values) that are still referenced by each operator in the |
| // subquery tree after the preidcate pull up is complete. |
| virtual void recomputeOuterReferences(); |
| |
| // Each operator supports a (virtual) method for rewriting its |
| // value expressions. |
| virtual void rewriteNode(NormWA & normWARef); |
| |
| // Each operator supports a (virtual) method for performing |
| // predicate pushdown and computing a "minimal" set of |
| // characteristic input and characteristic output values. |
| virtual RelExpr * normalizeNode(NormWA & normWARef); |
| |
| // subqueries are unnested in this method |
| virtual RelExpr * semanticQueryOptimizeNode(NormWA & normWARef); |
| RelExpr * inlineTempTablesForCSEs(NormWA & normWARef); |
| |
| // Method to push down predicates from a RelRoot node into the |
| // children |
| virtual |
| void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator, |
| const ValueIdSet & newExternalInputs, |
| ValueIdSet& predOnOperator, |
| const ValueIdSet * nonPredExprOnOperator = NULL, |
| Lng32 childId = (-MAX_REL_ARITY) ); |
| |
| // The set of values that I can potentially produce as output. |
| virtual void getPotentialOutputValues(ValueIdSet & vs) const; |
| |
| void setRootFlag(NABoolean trueRootFlag) { trueRoot_ = trueRootFlag; } |
| NABoolean isTrueRoot() const { return trueRoot_; } |
| |
| void setSubRoot(NABoolean subRoot) { subRoot_ = subRoot; } |
| NABoolean isSubRoot() const { return subRoot_; } |
| |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // synthesize logical properties |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // optimizer functions |
| virtual CostMethod* costMethod() const; |
| virtual Context* createContextForAChild(Context* myContext, |
| PlanWorkSpace* pws, |
| Lng32& childIndex); |
| |
| virtual NABoolean currentPlanIsAcceptable(Lng32 planNo, |
| const ReqdPhysicalProperty* const rppForMe) const; |
| |
| virtual PhysicalProperty *synthPhysicalProperty(const Context *context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| |
| // method to do code generation |
| RelExpr * preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| virtual short codeGen(Generator*); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| virtual void computeMyRequiredResources(RequiredResources & reqResources, |
| EstLogPropSharedPtr & inLP); |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| // set display on/off. |
| void setDisplayTree(NABoolean val) {displayTree_ = val;} |
| NABoolean getDisplayTree() const {return displayTree_;} |
| |
| ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *explainTuple, |
| ComTdb * tdb, |
| Generator *generator); |
| |
| |
| StmtLevelAccessOptions& accessOptions() { return accessOptions_; } |
| NABoolean &readOnlyTransIsOK() { return readOnlyTransIsOK_; } |
| |
| NABoolean isUpdatableCursor(); |
| NABoolean isUpdatableView(NABoolean &isInsertable) const; |
| |
| LIST(OptSqlTableOpenInfo *) &getViewStoiList() { return viewStoiList_; } |
| LIST(OptSqlTableOpenInfo *) &getDDLStoiList() { return ddlStoiList_; } |
| LIST(OptUdrOpenInfo *) &getUdrStoiList() { return stoiUdrList_; } |
| LIST(OptUDFInfo *) &getUDFList() { return udfList_; } |
| ComSecurityKeySet &getSecurityKeySet() { return securityKeySet_; } |
| |
| NABoolean &needFirstSortedRows() { return needFirstSortedRows_; } |
| |
| //++ Privs |
| NABoolean checkPrivileges(BindWA* bindWA); |
| void findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab |
| , const uint32_t userHashValue |
| , const PrivType which ); |
| |
| //++ MVs |
| NABoolean hasMvBindContext() const; |
| MvBindContext * getMvBindContext() const; |
| void setMvBindContext(MvBindContext * pMvBindContext); |
| |
| // -- MVs |
| void setRootOfInternalRefresh() { isRootOfInternalRefresh_ = TRUE; } |
| NABoolean isRootOfInternalRefresh() const { return isRootOfInternalRefresh_; } |
| void setMVQRqueryNonCacheable() { isQueryNonCacheable_ = TRUE; } |
| NABoolean isMVQRqueryNonCacheable() const { return isQueryNonCacheable_;} |
| |
| // -- Triggers |
| void setEmptySelectList() { isEmptySelectList_ = TRUE; } |
| NABoolean isEmptySelectList() const { return isEmptySelectList_; } |
| |
| void setDontOpenNewScope() { isDontOpenNewScope_ = TRUE; } |
| NABoolean isDontOpenNewScope() const { return isDontOpenNewScope_; } |
| |
| // NABoolean &doOltpQueryOptimization() { return doOltpQueryOptimization_; } |
| |
| OperatorType &childOperType() { return childOperType_;}; |
| ItemExpr *getInputVarTree() { return inputVarTree_; } |
| ItemExpr *getOutputVarTree() { return outputVarTree_; } |
| |
| inline LIST(ComTimestamp) * getTriggersList() const { return triggersList_; } |
| |
| // QSTUFF |
| // -------------------------------------------------------------------- |
| // This routine checks whether a table is both read and updated |
| // -------------------------------------------------------------------- |
| virtual rwErrorStatus checkReadWriteConflicts(NormWA & normWARef); |
| |
| inline NABoolean avoidHalloween() const |
| { return avoidHalloween_; } |
| |
| inline void setAvoidHalloween(NABoolean h) |
| { avoidHalloween_ = h; } |
| |
| inline NABoolean disableESPParallelism() const |
| { return disableESPParallelism_; } |
| |
| inline void setDisableESPParallelism(NABoolean e) |
| { disableESPParallelism_ = e; } |
| |
| HostArraysWA *getHostArraysArea() { return hostArraysArea_; } |
| void setHostArraysArea(HostArraysWA *ha) { hostArraysArea_ = ha; } |
| |
| // apply xforRowsetsInTree to RelRoot & return transformed tree |
| RelExpr *xformRowsetsInTree(BindWA& wa, |
| const ULng32 inputArrayMaxsize = 0, |
| const RelExpr::AtomicityType atomicity = RelExpr::UNSPECIFIED_); |
| |
| // append an ascii-version of RelRoot into cachewa.qryText_ |
| virtual void generateCacheKey(CacheWA& cwa) const; |
| |
| // is this entire expression cacheable after this phase? |
| virtual NABoolean isCacheableExpr(CacheWA& cwa); |
| |
| // change literals of a cacheable query into ConstantParameters and |
| // save true root into cachewa so we can add ConstantParameters as inputs |
| virtual RelExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA); |
| |
| // For defect id: 10-010522-2978 |
| |
| RelRoot *getParentForRowsetReqdOrder() |
| { return parentForRowsetReqdOrder_; }; |
| void setParentForRowsetReqdOrder(RelRoot * pRR) |
| { parentForRowsetReqdOrder_ = pRR; }; |
| |
| // End defect id: 10-010522-2978 |
| |
| inline const ItemExprList *getSpOutParams (void) |
| |
| { |
| return spOutParams_; |
| } |
| |
| NABoolean forceCQS(RelExpr *); |
| |
| RelRoot * transformGroupByWithOrdinalPhase1(BindWA *bindWA); |
| RelRoot * transformGroupByWithOrdinalPhase2(BindWA *bindWA); |
| RelRoot * transformOrderByWithExpr(BindWA *bindWA); |
| ItemExpr * processGroupingID(ItemExpr * ie, BindWA *bindWA); |
| |
| // MV -- |
| NABoolean virtual isIncrementalMV() { return getFirstNRows()==-1 && !needFirstSortedRows(); } |
| |
| NABoolean downrevCompileNeeded() const |
| { |
| return (downrevCompileMXV_ != COM_VERS_CURR_PLAN); |
| } |
| |
| void setDownrevCompileMXV(COM_VERSION mxv) |
| { downrevCompileMXV_ = mxv;} |
| COM_VERSION getDownrevCompileMXV() { return downrevCompileMXV_;} |
| |
| // For parallel extract producer queries |
| NABoolean isParallelExtractProducer() const |
| { return (numExtractStreams_ > 0 ? TRUE : FALSE); } |
| void setNumExtractStreams(ComUInt32 n) |
| { numExtractStreams_ = n; } |
| ComUInt32 getNumExtractStreams() const |
| { return numExtractStreams_; } |
| |
| inline NABoolean containsOnStatementMV() const |
| { return containsOnStatementMV_; } |
| |
| inline void setContainsOnStatementMV(NABoolean h) |
| { containsOnStatementMV_ = h; } |
| |
| inline NABoolean containsLRU() const |
| { return containsLRU_; } |
| |
| inline void setContainsLRU(NABoolean h) |
| { containsLRU_ = h; } |
| |
| // MVQR |
| inline NABoolean isAnalyzeOnly() |
| { return isAnalyzeOnly_; } |
| |
| inline void setAnalyzeOnly() |
| { isAnalyzeOnly_ = true; } |
| |
| inline NABoolean hasMandatoryXP() const |
| { return hasMandatoryXP_; } |
| |
| inline void setHasMandatoryXP(NABoolean h) |
| { hasMandatoryXP_ = h; } |
| |
| // olap functions support |
| |
| void setHasOlapFunctions(NABoolean v) { hasOlapFunctions_ = v; } |
| NABoolean getHasOlapFunctions() { return hasOlapFunctions_; } |
| |
| void setHasTDFunctions(NABoolean v) { hasTDFunctions_ = v; } |
| NABoolean getHasTDFunctions() { return hasTDFunctions_; } |
| |
| private: |
| |
| enum |
| { |
| HDFS_ACCESS = 0x0001 |
| }; |
| |
| void transformTDPartitionOrdinals(BindWA *bindWA); |
| void resolveAggregates(BindWA *bindWA); |
| void resolveSequenceFunctions(BindWA *bindWA); |
| |
| NABoolean isUpdatableBasic(NABoolean isView, NABoolean &isInsertable) const; |
| |
| NABoolean checkFirstNRowsNotAllowed(BindWA* bindWA) ; |
| |
| // defined in generator/GenRelMisc.cpp |
| TrafQuerySimilarityInfo * genSimilarityInfo(Generator *generator); |
| |
| // returns TRUE if a GroupByAgg node was added |
| NABoolean addOneRowAggregates(BindWA * bindWA, NABoolean forceGroupByAgg); |
| |
| inline void setNumBMOs(unsigned short num) { numBMOs_ = num; } |
| inline unsigned short getNumBMOs() { return numBMOs_; } |
| |
| // set and get the total BMO memory usage of the fragment rooted |
| // at the root node |
| inline void setBMOsMemoryUsage(CostScalar x) { BMOsMemoryUsage_ = x; } |
| inline CostScalar getBMOsMemoryUsage() { return BMOsMemoryUsage_ ; } |
| |
| inline void setNBMOsMemoryUsage(CostScalar x) { nBMOsMemoryUsage_ = x; } |
| inline CostScalar getNBMOsMemoryUsage() { return nBMOsMemoryUsage_ ; } |
| |
| NABoolean hdfsAccess() |
| { return (flags_ & HDFS_ACCESS) != 0; } |
| void setHdfsAccess(NABoolean v) |
| { (v ? flags_ |= HDFS_ACCESS : flags_ &= ~HDFS_ACCESS); } |
| |
| NABoolean trueRoot_; // set in the true root of the query tree |
| // reset in the roots of all subquery trees |
| Int32 outputVarCnt_; // -1 if not true root, else no. of output :hv's |
| NABoolean subRoot_; // true iff this is a subroot (ie, the root of a |
| // sql statement that's inside a compound statement) |
| ItemExpr * compExprTree_; |
| ItemExpr * inputVarTree_; |
| ItemExpr * outputVarTree_; |
| ItemExpr * orderByTree_; |
| TMUDFInputPartReq partReqType_; //NONE, REPLICATE, ANY, SPECIFIED |
| ItemExpr * partitionByTree_; // used by TMUDF only. If this member is set |
| // orderBy is for each partition (OLAP style) |
| ItemExpr * updateColTree_; |
| ItemExpr * assignmentStTree_; // Variables in left-hand side of assignment |
| // statement in Compound Statements |
| ItemExpr * assignList_; // List of assign nodes. Used by assignment statement; |
| // contains first and last value id of host variables |
| // in the statement. Used at code generation time |
| // predicate to be evaluated before returning a row. If specified, rows are returned |
| // only if this pred passes |
| ItemExpr * predExprTree_; |
| |
| ValueIdList compExpr_; // select list |
| ValueIdList inputVars_; // list of input host variables or parameters |
| ValueIdList reqdOrder_; // ORDER BY list |
| ValueIdSet partArrangement_; // PARTITION BY set for TMUDF |
| ValueIdList updateCol_; // update column list |
| RelExpr * reqdShape_; // forced plan shape of this query |
| ValueIdList outputVars_; // list of output host variables or parameters |
| ValueIdList assignmentStVars_;// Bound variables in left-hand side of |
| // assignment statement in Compund Statements |
| ItemExprList *spOutParams_;// List of HVs/DPs in CALL OUT/INOUT parameter list |
| |
| // list of all the views open information of this query. |
| LIST(OptSqlTableOpenInfo *) viewStoiList_; |
| |
| // list of all the table open information of this DDL stmt. |
| // used by Trigger and MV |
| LIST(OptSqlTableOpenInfo *) ddlStoiList_; |
| |
| // list of all routines open in the context of this query. |
| LIST(OptUdrOpenInfo *) stoiUdrList_; |
| |
| // list of all UDFs open in the context of this query. |
| // This list applies only to TRIGGERS. |
| LIST(OptUDFInfo *) udfList_; |
| |
| // list of ComSecurityKeys used by this query |
| // If a privilege is obtained by more than one means, compiler chooses a path |
| ComSecurityKeySet securityKeySet_; |
| |
| //////////////////////////////////////////////////////////////////// |
| // The fields updatableSelect_, updateCurrentOf_ and pkeyList_ are |
| // used to process an 'update where current of query'. |
| // Only ONE of the two flags (updatableSelect_ and updateCurrentOf_) |
| // could be TRUE. |
| //////////////////////////////////////////////////////////////////// |
| |
| // this flag indicates that the query below this root node is |
| // a 'simple' SELECT cursor declared via "DECLARE CURSOR..." statement. |
| // and the base table could be updated/deleted via an |
| // "UPDATE...WHERE CURRENT OF..." statement. |
| // A select is not 'simple' if there are Aggrs, multiple tables, |
| // subqueries in a select statement. |
| NABoolean updatableSelect_; |
| |
| // this flag, if set, indicates that this is a static update where current |
| // of query. |
| NABoolean updateCurrentOf_; |
| |
| // The next list contains one of the following two lists: |
| // -- if updatableSelect_ is TRUE, then this contains the list of |
| // child SELECT's primary key columns. Used to create a 'row' of |
| // primary keys which are passed to the 'update' query at runtime. |
| // |
| // -- if updateCurrentOf_ is TRUE, this list contains the list of |
| // fabricated hostvars. See class GenericUpdate, field pkeyHvarList_. |
| ValueIdList pkeyList_; |
| |
| // Name of the cursor or a hostvar which will contain the cursor |
| // name at runtime. Valid if updateCurrentOf_ is TRUE. Initialized |
| // at bind time from the child update/delete node. |
| ItemExpr * currOfCursorName_; |
| |
| // contains the |
| NABoolean displayTree_; // if set, this tree needs to be displayed. |
| // Set by parser on seeing a DISPLAY command. |
| |
| // this flag is set to TRUE if this is an update, delete or insert |
| // query. This information is needed at runtime to rollback/abort |
| // the transaction in case of an error. What we really need is |
| // support for statement atomicity. But until we have that, the |
| // only way to have a consistent database in case of an error is |
| // to rollback the transaction. This makes us ANSI incompatible. |
| NABoolean rollbackOnError_; |
| |
| // user specified BROWSE, STABLE or REPEATABLE access type and |
| // user specified SHARE or EXCLUSIVE mode |
| StmtLevelAccessOptions accessOptions_; |
| NABoolean readOnlyTransIsOK_; |
| |
| // if TRUE, return first N sorted rows. |
| NABoolean needFirstSortedRows_; |
| |
| // Tells how many scalar variables this node contains |
| Int32 numSimpleVar_; |
| |
| // Tells how many host array variables this node contains |
| Int32 numHostVar_; |
| |
| // if set to TRUE, then message buffers between FS and DP2 could |
| // be small. This is set by binder if the true root of query tree |
| // is an update, delete, insert-values or select-into query. |
| // This is still a hint. The actual buffer size is computed by |
| // the generator depending on whether a unique operation is chosen. |
| //NABoolean doOltpQueryOptimization_; |
| |
| OperatorType childOperType_; |
| |
| // points to a class used by RowSets code |
| HostArraysWA *hostArraysArea_; |
| |
| // -- MVs |
| // Is this true root above a Refresh node (before binding). |
| // This flag is propagated to the physical node by the optimizer, |
| // and later used at generation time. |
| NABoolean isRootOfInternalRefresh_; |
| |
| // true iff result descriptor has Provided range or residual predicate(s) |
| NABoolean isQueryNonCacheable_; // default is FALSE |
| |
| //++ MV OZ |
| // this context will be passed to the new scope created by the root |
| MvBindContext * pMvBindContextForScope_; |
| |
| ULng32 flags_; |
| |
| // For defect id: 10-010522-2978 |
| // Points to ORDER BY required to properly support a lower level RelRoot |
| // which has an ORDER by and an input host variable array (i.e. Rowset used |
| // for input). The idea is to always force the ordering to be for |
| // the entire output from the upper level RelRoot rather than just the |
| // output from each of the elements of the input host variable array(s). |
| // This is used in the HostArraysWA::modifyTree() method. It puts the |
| // bound identifiers for the ORDER BY into the upper level RelRoot, but |
| // avoids prematurely populating the reqdOrder_ member of that upper level |
| // RelRoot; in other words, this was added to avoid putting bound |
| // identifiers into reqdOrder_ until after it is bound. |
| // rowsetReqdOrder_ is populated when the lower level RelRoot |
| // is executing RelRoot::bindNode(). These bound variables will be |
| // saved here until we reach the upper level RelRoot::bindNode() and |
| // the contents are merged into the upper level RelRoot's reqdOrder_. |
| // NOTE: This code assumes that there are no modifications to the |
| // RelExpr tree which would move between the parent RelRoot node for |
| // and the RelExprs created below it during HostArraysWA::modifyTree(). |
| // Should such modifications be needed, this may need to change to |
| // accomodate the tree structure. |
| ValueIdList rowsetReqdOrder_; |
| |
| // This pointer to the parent level RelRoot is initialized to NULL by |
| // the constructors and potentially set by the code in |
| // HostArraysWA::modifyTree(). It is checked for non-NULL and used during |
| // RelRoot::bindNode() to allow the lower level RelRoot to quickly |
| // populate the parent level's rowsetReqdOrder_. This could be |
| // changed to be a flag and then have code to search upwards in the |
| // tree to find the correct upper level parent if the tree could get |
| // rewritten to have another intervening RelRoot which should then |
| // become the new target of the parentForRowsetReqdOrder_. (In other words, |
| // we would need to find correct upper level parent algorithmically). |
| RelRoot *parentForRowsetReqdOrder_; |
| |
| // End defect id: 10-010522-2978 |
| |
| // -- Triggers |
| // This root has no data flowing up. |
| NABoolean isEmptySelectList_; |
| // Dont open a new BindScope when binding this root. |
| NABoolean isDontOpenNewScope_; |
| |
| // List of trigger ID's in this RelExpr tree |
| LIST(ComTimestamp) *triggersList_; |
| |
| // downrevCompileMXV_ contains the version of code which needs to be |
| // generated. It is the min MXV of all partitions which we can access. |
| // It is set in RelRoot::bindNode. |
| // For coyote, we need to generate either roadrunner or R2 fcs code, |
| // depending on the min MXV. |
| // This will be removed when real versioning support is in. |
| COM_VERSION downrevCompileMXV_; |
| |
| UninitializedMvNameList *uninitializedMvList_; |
| |
| // Support self-referencing updates and avoid the Halloween problem. |
| NABoolean avoidHalloween_; |
| |
| // Disable ESP parallel execution for certain kind of queries. |
| // Right now being done for Merge statement. |
| // Merge is only done on unique predicates. |
| // Right now, even with unique predicate, the merge request is sent |
| // to each ESP. |
| // That incorrectly inserts rows if row to be updated |
| // is not found. |
| // This may be temporary if code is fixed so merge request is only |
| // sent to the ESP based on the unique merge predicate. |
| NABoolean disableESPParallelism_; |
| |
| // For a parallel extract producer query, the number of extract |
| // streams |
| ComUInt32 numExtractStreams_; |
| |
| // TRUE, if in a grouped query, all columns specified in the |
| // order by clause are also specified in the group by clause. |
| // Valid for queries with GROUP BY and ORDER BY clauses. |
| NABoolean allOrderByRefsInGby_; |
| |
| // olap functions support |
| NABoolean hasOlapFunctions_; |
| NABoolean hasTDFunctions_; |
| |
| |
| // TRUE, if the IUD statement contains an ON STATMENT MV |
| NABoolean containsOnStatementMV_; |
| |
| // TRUE, if the IUD statement is an LRU |
| NABoolean containsLRU_; |
| |
| // MVQR |
| // TRUE if the query result should be the query descriptor used for MV Query Reqrite. |
| NABoolean isAnalyzeOnly_; |
| |
| // TRUE, if query has mandatory cross products |
| NABoolean hasMandatoryXP_; |
| |
| // Updated and used only in the generator. Counts BMOs in master fragment. |
| unsigned short numBMOs_; |
| |
| // Updated and used only in the generator. Total BMO memory usage in master fragment. |
| CostScalar BMOsMemoryUsage_ ; |
| CostScalar nBMOsMemoryUsage_ ; |
| |
| // flag used to indicate whether CIF is on or off in the explain plan only |
| NABoolean isCIFOn_; |
| |
| ItemExpr * firstNRowsParam_; |
| }; // class RelRoot |
| |
| // ----------------------------------------------------------------------- |
| // The PhysicalRelRoot replaces the logical RelRoot through the |
| // application of the PhysicalRelRootRule. This transformation is |
| // designed to present a purely physical verison of an operator |
| // that is both logical and physical. |
| // ----------------------------------------------------------------------- |
| class PhysicalRelRoot : public RelRoot |
| { |
| public: |
| PhysicalRelRoot(RelExpr * childExpr, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelRoot(childExpr, REL_ROOT, NULL, NULL, NULL, NULL, oHeap) {}; |
| PhysicalRelRoot(const RelRoot & other) : RelRoot(other) {}; |
| |
| virtual NABoolean isLogical() const; |
| virtual NABoolean isPhysical() const; |
| |
| }; // class PhysicalRelRoot |
| |
| // ----------------------------------------------------------------------- |
| // The Tuple class represents a table with a single row (tuple) in it. |
| // This is both a logical and a physical operator. |
| // ----------------------------------------------------------------------- |
| class Tuple : public RelExpr |
| { |
| public: |
| |
| // constructor |
| Tuple(OperatorTypeEnum oper, ItemExpr *tupleExpr = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(oper,NULL,NULL,oHeap), |
| tupleExprTree_(tupleExpr), |
| rejectPredicates_(FALSE) |
| { |
| id_ = ++idCounter_; |
| } |
| |
| Tuple(ItemExpr *tupleExpr = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_TUPLE,NULL,NULL,oHeap), |
| tupleExprTree_(tupleExpr), |
| rejectPredicates_(FALSE) |
| { |
| id_ = ++idCounter_; |
| } |
| |
| Tuple(const Tuple & other); |
| |
| virtual ~Tuple(); |
| |
| // get the degree of this node (it is a leaf op). |
| virtual Int32 getArity() const; |
| |
| // get and set the tuple predicate, add and remove individual predicates |
| // from the list of expressions |
| ItemExpr * tupleExprTree() const { return tupleExprTree_; } |
| void addTupleExprTree(ItemExpr *tupleExpr); |
| ItemExpr * removeTupleExprTree(); |
| |
| // return a (short-lived) read/write reference to the tuple expression |
| ValueIdList & tupleExpr() { return tupleExpr_; } |
| |
| // return a read-only reference to the tuple expression |
| const ValueIdList & tupleExpr() const { return tupleExpr_; } |
| |
| // a virtual function for performing name binding within the query tree |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // MV -- |
| NABoolean virtual isIncrementalMV() { return TRUE; } |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| // |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| // a method used for recomputing the outer references (external dataflow |
| // input values) that are still referenced by each operator in the |
| // subquery tree after the preidcate pull up is complete. |
| virtual void recomputeOuterReferences(); |
| |
| // Each operator supports a (virtual) method for rewriting its |
| // value expressions. |
| virtual void rewriteNode(NormWA & normWARef); |
| |
| // Each operator supports a (virtual) method for performing |
| // predicate pushdown and computing a "minimal" set of |
| // characteristic input and characteristic output values. |
| virtual RelExpr * normalizeNode(NormWA & normWARef); |
| |
| // method to do code generation |
| virtual RelExpr * preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| virtual short codeGen(Generator*); |
| |
| virtual void getPotentialOutputValues(ValueIdSet & vs) const; |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // synthesize logical properties |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // cost functions |
| virtual CostMethod* costMethod() const; |
| virtual PhysicalProperty *synthPhysicalProperty(const Context *context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| |
| NABoolean& rejectPredicates() { return rejectPredicates_; } |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| // append an ascii-version of Tuple into cachewa.qryText_ |
| virtual void generateCacheKey(CacheWA& cwa) const; |
| |
| // is this entire expression cacheable after this phase? |
| virtual NABoolean isCacheableExpr(CacheWA& cwa); |
| |
| // change literals of a cacheable query into ConstantParameters |
| virtual RelExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA); |
| |
| private: |
| |
| // an expression with the value of the single tuple |
| ItemExpr * tupleExprTree_; |
| ValueIdList tupleExpr_; |
| |
| // If TRUE, will not accept predicates pushed from above. |
| NABoolean rejectPredicates_; |
| |
| // This id is added to uniquely distinguish tuple expressions |
| // We do not want valus(1) and values(1) to be considered the same |
| // RelExpr in cascades memo which results in eliminating legitimate |
| // Tuple expressions |
| Lng32 id_; |
| |
| // Static counter used to ensure unique id to each Tuple object |
| static THREAD_P Lng32 idCounter_; |
| }; // class Tuple |
| |
| // ------------------------------------------------------------------------- |
| // The TupleList class represents a table with multiple rows (tuples) in it. |
| // This is both a logical and a physical operator. |
| // ------------------------------------------------------------------------- |
| class TupleList : public Tuple |
| { |
| public: |
| |
| // constructor |
| TupleList(ItemExpr *tupleListExpr, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : Tuple(REL_TUPLE_LIST,tupleListExpr, oHeap), numberOfTuples_(-1), createdForInList_(FALSE) |
| {} |
| |
| TupleList(const TupleList & other); |
| |
| ValueIdList & castToList() { return castToList_; } |
| Lng32 numTuples() const { return numberOfTuples_; } |
| NABoolean createdForInList() const { return createdForInList_; } |
| void setCreatedForInList (NABoolean flag) { createdForInList_ = flag; } |
| |
| // a virtual function for performing name binding within the query tree |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| // |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| // a method used for recomputing the outer references (external dataflow |
| // input values) that are still referenced by each operator in the |
| // subquery tree after the preidcate pull up is complete. |
| virtual void recomputeOuterReferences(); |
| |
| // Each operator supports a (virtual) method for rewriting its |
| // value expressions. |
| virtual void rewriteNode(NormWA & normWARef); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // synthesize logical properties |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // method to do code generation |
| virtual short codeGen(Generator*); |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| virtual NABoolean isLogical() const { return TRUE; }; |
| virtual NABoolean isPhysical() const { return FALSE; }; |
| |
| // set vidlist = ith tuple of this tuplelist and return TRUE |
| RelExpr* getTuple(BindWA *bindWA, ValueIdList& vidList, CollIndex i); |
| |
| private: |
| |
| // set needsFixup to TRUE iff tuplelist needs INFER_CHARSET fixup |
| RelExpr* needsCharSetFixup(BindWA *bindWA, |
| CollIndex arity, |
| CollIndex nTuples, |
| NAList<NABoolean> &strNeedsFixup, |
| NABoolean &needsFixup); |
| |
| // find fixable strings' inferredCharTypes |
| RelExpr* pushDownCharType(BindWA *bindWA, |
| enum CharInfo::CharSet cs, |
| NAList<const CharType*> &inferredCharType, |
| NAList<NABoolean> &strNeedsFixup, |
| CollIndex arity, |
| CollIndex nTuples); |
| |
| // do INFER_CHARSET fixup |
| RelExpr* doInferCharSetFixup(BindWA *bindWA, |
| enum CharInfo::CharSet cs, |
| CollIndex arity, |
| CollIndex nTuples); |
| |
| // cached number of tuples in the tuple list |
| Lng32 numberOfTuples_; |
| |
| // list containing the value ids whose type the tuples are to be |
| // converted before returning. Used (currently) if this list will be |
| // inserted into a table. |
| ValueIdList castToList_; |
| NABoolean createdForInList_; |
| }; // class TupleList |
| |
| // ----------------------------------------------------------------------- |
| // The PhysicalTuple replaces the logical Tuple through the |
| // application of the PhysicalTupleRule. This transformation is |
| // designed to present a purely physical verison of an operator |
| // that is both logical and physical. |
| // ----------------------------------------------------------------------- |
| class PhysicalTuple : public Tuple |
| { |
| public: |
| PhysicalTuple(const Tuple & other) : Tuple(other) {}; |
| |
| PhysicalTuple(CollHeap *oHeap = CmpCommon::statementHeap()) |
| : Tuple(REL_TUPLE, NULL, oHeap) {}; |
| |
| virtual NABoolean isLogical() const; |
| virtual NABoolean isPhysical() const; |
| virtual RelExpr* preCodeGen(Generator*, const ValueIdSet&, ValueIdSet &); |
| |
| }; // class PhysicalTuple |
| |
| // ----------------------------------------------------------------------- |
| // The PhysicalTupleList replaces the logical TupleList through the |
| // application of the PhysicalTupleListRule. This transformation is |
| // designed to present a purely physical verison of an operator. |
| // ----------------------------------------------------------------------- |
| class PhysicalTupleList : public TupleList |
| { |
| public: |
| PhysicalTupleList(const TupleList & other) : TupleList(other) {}; |
| |
| PhysicalTupleList(CollHeap *oHeap = CmpCommon::statementHeap()) |
| : TupleList(NULL, oHeap) {}; |
| |
| virtual NABoolean isLogical() const { return FALSE; } |
| virtual NABoolean isPhysical() const { return TRUE; } |
| virtual RelExpr* preCodeGen(Generator*, const ValueIdSet&, ValueIdSet &); |
| |
| }; // class PhysicalTupleList |
| |
| // ----------------------------------------------------------------------- |
| // The Filter is introduced as well as eliminated by the rules. |
| // It is a placeholder for predicates that are pushed down. |
| // ----------------------------------------------------------------------- |
| class Filter : public RelExpr |
| { |
| public: |
| |
| // constructor, destructor |
| Filter(RelExpr * queryTree, CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_FILTER, queryTree, NULL, oHeap) |
| { |
| reattemptPushDown_ = FALSE; |
| } |
| |
| virtual ~Filter(); |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const; |
| |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual void getPotentialOutputValues(ValueIdSet & vs) const; |
| |
| virtual RelExpr * normalizeNode(NormWA & normWARef) ; |
| |
| // flows compRefOpt constraints up the query tree. |
| virtual void processCompRefOptConstraints(NormWA * normWAPtr) ; |
| |
| // synthesize logical properties |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| virtual const NAString getText() const; |
| |
| void setReattemptPushDown() { reattemptPushDown_ = TRUE; } |
| void resetReattemptPushDown() { reattemptPushDown_ = FALSE; } |
| NABoolean reattemptPushDown() { return reattemptPushDown_; } |
| |
| //////////////////////////////////// |
| virtual void primeGroupAnalysis(); |
| //////////////////////////////////// |
| |
| private: |
| |
| // Indicator of whether this filter node carries predicates which we want |
| // to re-attempt to push down. That is, they were not successfully pushed |
| // down last time we tried, but we want to retry this again, due to new |
| // conditions (like elimination of a group by). This flag is here as part |
| // of a temporary fix. |
| // |
| NABoolean reattemptPushDown_; |
| |
| }; // class Filter |
| |
| // ----------------------------------------------------------------------- |
| // The Rename class is an abstract class for name mapping operations. |
| // Derived from it: RenameTable, and RenameReference and BeforeTrigger. |
| // Rename objects pass name mapping information from the parser to the binder, |
| // or are used internally in the binder. These nodes disappear during |
| // transformation, therefore the normalization method below just ASSERT. |
| // ----------------------------------------------------------------------- |
| class Rename : public RelExpr |
| { |
| public: |
| |
| // constructors, destructor |
| Rename(RelExpr *child, OperatorTypeEnum otype = REL_RENAME, |
| CollHeap *oHeap = CmpCommon::statementHeap() ) |
| : RelExpr(otype, child, NULL, oHeap) |
| {} |
| |
| virtual ~Rename(); |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const; |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| // Make sure Rename nodes dissappear during Transformation. |
| virtual RelExpr * normalizeNode(NormWA & normWARef) |
| { CMPASSERT(FALSE); return this; } |
| |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| |
| // get a printable string that identifies the operator |
| // Pure virtual - implemented by sub-classes. |
| virtual const NAString getText() const = 0; |
| |
| }; // class Rename |
| |
| // ----------------------------------------------------------------------- |
| // The RenameTable operator is used by Parser and Binder to allow name |
| // mapping of external (ANSI) SQL table and column names. |
| // ----------------------------------------------------------------------- |
| class RenameTable : public Rename |
| { |
| public: |
| |
| // constructors, destructor |
| RenameTable(RelExpr *child, |
| const NAString &corrName, |
| ItemExpr *colNames = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap(), |
| const NABoolean isView = FALSE) |
| : Rename(child, REL_RENAME_TABLE, oHeap), |
| newTableName_(corrName, FALSE/*not fabricated, but name IS corr only*/, oHeap), |
| newColNamesTree_(colNames), |
| isView_(isView), |
| viewNATable_(NULL) |
| {} |
| |
| RenameTable(NABoolean /*just to make it obvious a different ctor is called*/, |
| RelExpr *child, |
| const CorrName &corrName, |
| ItemExpr *colNames = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap(), |
| const NABoolean isView = FALSE) |
| : Rename(child, REL_RENAME_TABLE, oHeap), |
| newTableName_(corrName, oHeap), // (non-standard) copy ctor |
| newColNamesTree_(colNames), |
| isView_(isView), |
| viewNATable_(NULL) |
| { |
| CMPASSERT(!newTableName_.isFabricated()); |
| // This next code is wrong, doesn't work for bindView()! |
| // |
| // if (newTableName_.getCorrNameAsString().isNull()) { |
| // newTableName_.setCorrName( |
| // newTableName_.getQualifiedNameObj().getObjectName()); |
| // CMPASSERT(!newTableName_.getCorrNameAsString().isNull()); |
| // } |
| } |
| |
| // copy ctor |
| RenameTable (const RenameTable & orig, |
| CollHeap * h=CmpCommon::statementHeap()) ; // not written |
| |
| virtual ~RenameTable(); |
| |
| // get the table and column names |
| const CorrName &getTableName() const { return newTableName_; } |
| ItemExpr *removeColNameTree(); |
| |
| // is this object created for a view? |
| NABoolean isView() const { return isView_; } |
| |
| // a virtual function for performing name binding within the query tree |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // MV -- |
| NABoolean virtual isIncrementalMV() { return TRUE; } |
| void virtual collectMVInformation(MVInfoForDDL *mvInfo, |
| NABoolean isNormalized); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| const NATable * getViewNATable() {return viewNATable_ ;} |
| void setViewNATable(const NATable * val) {viewNATable_ = val;} |
| |
| |
| private: |
| |
| // the new user-specified name of the table |
| CorrName newTableName_; |
| |
| // the column name list specified in the rename clause |
| ItemExpr *newColNamesTree_; |
| |
| // is this object created for a view? |
| NABoolean isView_; |
| |
| // NATable for view |
| const NATable * viewNATable_ ; |
| }; // class RenameTable |
| |
| // ----------------------------------------------------------------------- |
| // The RenameReference node implements the REFERENCING clause of trigger |
| // definitions. A list of TableRefName objects is passed from the parser |
| // to the binder. |
| // ----------------------------------------------------------------------- |
| class RenameReference : public Rename |
| { |
| public: |
| |
| // constructors, destructor |
| RenameReference(RelExpr *child, |
| TableRefList& tableReferences, |
| CollHeap *oHeap = CmpCommon::statementHeap() ) |
| : Rename(child, REL_RENAME_REFERENCE, oHeap), |
| tableReferences_(tableReferences) |
| {} |
| |
| virtual ~RenameReference(); |
| |
| // a virtual function for performing name binding within the query tree |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // utility method for binding. |
| void prepareRETDescWithTableRefs(BindWA *bindWA); |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| // get the table references list |
| TableRefList& getRefList() |
| { return tableReferences_; } |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| private: |
| |
| TableRefList tableReferences_; |
| }; // class RenameReference |
| |
| // ----------------------------------------------------------------------- |
| // The BeforeTrigger class implements a before trigger. |
| // ----------------------------------------------------------------------- |
| class BeforeTrigger : public Rename |
| { |
| public: |
| // constructors, destructor |
| BeforeTrigger(TableRefList& tableReferences, |
| ItemExpr *whenClause, |
| ItemExprList *setList, |
| CollHeap *oHeap = CmpCommon::statementHeap() ) |
| : Rename(NULL, REL_BEFORE_TRIGGER, oHeap), |
| tableReferences_(tableReferences), |
| whenClause_(whenClause), |
| signal_(NULL), |
| setList_(setList), |
| isSignal_(FALSE), |
| parentTSJ_(NULL) |
| { } |
| |
| BeforeTrigger(TableRefList& tableReferences, |
| ItemExpr *whenClause, |
| RaiseError *signal, |
| CollHeap *oHeap = CmpCommon::statementHeap() ) |
| : Rename(NULL, REL_BEFORE_TRIGGER, oHeap), |
| tableReferences_(tableReferences), |
| whenClause_(whenClause), |
| signal_(signal), |
| setList_(NULL), |
| isSignal_(TRUE), |
| parentTSJ_(NULL) |
| { } |
| |
| virtual ~BeforeTrigger(); |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const; |
| |
| // a virtual function for performing name binding within the query tree |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| ItemExpr *getWhenClause() { return whenClause_; } |
| void setWhenClause(ItemExpr *exp) { whenClause_ = exp; } |
| |
| void bindSetClause(BindWA *bindWA, RETDesc *origRETDesc, CollHeap *heap); |
| void bindSignalClause(BindWA *bindWA, RETDesc *origRETDesc, CollHeap *heap); |
| |
| // Fix the inputs before calling the inherited method. |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| // get the table references list |
| TableRefList& getRefList() |
| { return tableReferences_; } |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| // Find the position and name of a Assign target column. |
| Lng32 getTargetColumn(CollIndex i, ColRefName* targetColName, const NATable *naTable); |
| |
| // Do DDL semantic checks on the SET clause. |
| void doSetSemanticChecks(BindWA *bindWA, RETDesc *origRETDesc); |
| |
| // Add the positions of all Assign target columns to ColsToSet. |
| void addUpdatedColumns(UpdateColumns *colsToSet, const NATable *naTable); |
| |
| void setParentTSJ(RelExpr *parent) { parentTSJ_ = parent; } |
| |
| private: |
| |
| TableRefList tableReferences_; |
| ItemExpr *whenClause_; |
| RaiseError *signal_; |
| ItemExprList *setList_; |
| NABoolean isSignal_; |
| RelExpr *parentTSJ_; |
| }; // class BeforeTrigger |
| |
| // ----------------------------------------------------------------------- |
| // The BinderOnlyNode class is an abstract class for nodes that implement |
| // commands that transform themselves during binding to more complex |
| // RelExpr trees. Derived from it are Refresh and MvLog. |
| // Their bindNode() method constructs a complex RelExpr tree that |
| // replaces the node itself in the tree. This is why the transformNode() |
| // method is implemented as an assert(FALSE). |
| // ----------------------------------------------------------------------- |
| class BinderOnlyNode : public RelExpr |
| { |
| public: |
| |
| // constructors, destructor |
| BinderOnlyNode(OperatorTypeEnum otype = REL_BINDER_ONLY, |
| CollHeap *oHeap = CmpCommon::statementHeap() ) |
| : RelExpr(otype, NULL, NULL, oHeap) |
| {} |
| |
| virtual ~BinderOnlyNode() |
| {}; |
| |
| // Since the destructor is never really called, at least clean up |
| // internal data before disappearing. Should be called before returning |
| // from bindNode(). |
| virtual void cleanupBeforeSelfDestruct() = 0; |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const { return 0; } |
| |
| // This is where all the action is. |
| // Pure virtual - implemented by sub-classes. |
| virtual RelExpr *bindNode(BindWA *bindWA) = 0; |
| |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe) |
| { CMPASSERT(FALSE);} |
| |
| }; // class BinderAnimal |
| |
| // ----------------------------------------------------------------------- |
| // The map value ids operator is used to create a link between |
| // logically equivalent expressions that have incompatible |
| // characteristic outputs and therefore cannot be in the same group. |
| // ----------------------------------------------------------------------- |
| class MapValueIds : public RelExpr |
| { |
| public: |
| |
| // constructor and destructor |
| MapValueIds(RelExpr *child = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_MAP_VALUEIDS,child,NULL,oHeap), |
| includesFavoriteMV_(FALSE), |
| cseRef_(NULL) {} |
| |
| MapValueIds(RelExpr *child, |
| const ValueIdSet &identity, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_MAP_VALUEIDS,child,NULL,oHeap), |
| map_(identity), includesFavoriteMV_(FALSE), |
| cseRef_(NULL) {} |
| |
| MapValueIds(RelExpr *child, |
| const ValueIdMap &map, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_MAP_VALUEIDS,child,NULL,oHeap), |
| map_(map), includesFavoriteMV_(FALSE), |
| cseRef_(NULL) {} |
| |
| MapValueIds(const MapValueIds & other) |
| : RelExpr(REL_MAP_VALUEIDS, other.child(0)), |
| map_(other.map_), |
| valuesNeededForVEGRewrite_(other.valuesNeededForVEGRewrite_), |
| includesFavoriteMV_(other.includesFavoriteMV_), |
| cseRef_(other.cseRef_) {} |
| |
| virtual ~MapValueIds(); |
| |
| // various PC methods |
| virtual Int32 getArity() const; |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual const NAString getText() const; |
| |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| virtual CostMethod* costMethod() const; |
| virtual Context* createContextForAChild(Context* myContext, |
| PlanWorkSpace* pws, |
| Lng32& childIndex); |
| virtual PhysicalProperty *synthPhysicalProperty(const Context *context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| |
| // accessor functions |
| ValueIdMap & getMap() { return map_; } |
| const ValueIdMap & getMap2() const { return map_; } |
| inline void remapTopValue(const ValueId & newTopValue, |
| const ValueId & bottomValue) |
| { map_.remapTopValue(newTopValue,bottomValue); } |
| inline void remapBottomValue(const ValueId & topValue, |
| const ValueId & newBottomValue) |
| { map_.remapBottomValue(topValue,newBottomValue); } |
| inline void addMapEntry(const ValueId & newTopValue, |
| const ValueId & newBottomValue) |
| { map_.addMapEntry(newTopValue,newBottomValue); } |
| inline void clear() { map_.clear(); } |
| inline const ValueIdSet & valuesForVEGRewrite() |
| { return valuesNeededForVEGRewrite_; } |
| inline void addValueForVEGRewrite(const ValueId & v) |
| { valuesNeededForVEGRewrite_ += v; } |
| inline void addValuesForVEGRewrite(const ValueIdSet & v) |
| { valuesNeededForVEGRewrite_ += v; } |
| inline void clearValuesForVEGRewrite() |
| { valuesNeededForVEGRewrite_.clear(); } |
| void addSameMapEntries(const ValueIdSet & newTopBottomValues); |
| void setCSERef(CommonSubExprRef *cse) { cseRef_ = cse; } |
| |
| // Method to compute child's characteristic outputs |
| virtual |
| void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator, |
| const ValueIdSet & newExternalInputs, |
| ValueIdSet& predOnOperator, |
| const ValueIdSet * nonPredExprOnOperator = NULL, |
| Lng32 childId = (-MAX_REL_ARITY) ); |
| |
| // The set of values that I can potentially produce as output. |
| virtual void getPotentialOutputValues(ValueIdSet & vs) const; |
| |
| // method to do code generation |
| virtual RelExpr * preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| virtual short codeGen(Generator*); |
| |
| // ----------------------------------------------------------------------- |
| // Performs mapping on the partitioning function, from the mapValueIds |
| // node to the child. |
| // ----------------------------------------------------------------------- |
| virtual PartitioningFunction* mapPartitioningFunction( |
| const PartitioningFunction* partFunc, |
| NABoolean rewriteForChild0) ; |
| |
| // for mv query rewrite |
| void setIncludesFavoriteMV (NABoolean value) |
| {includesFavoriteMV_ = value;} |
| |
| NABoolean includesFavoriteMV () const |
| {return includesFavoriteMV_;} |
| |
| private: |
| |
| ValueIdMap map_; |
| ValueIdSet valuesNeededForVEGRewrite_; |
| NABoolean includesFavoriteMV_; |
| NABoolean replaceVEGUsingList_; |
| CommonSubExprRef *cseRef_; |
| }; |
| |
| // ----------------------------------------------------------------------- |
| // The PhysicalMapValueIds replaces the logical MapValueIds through the |
| // application of the PhysicalMapValueIdsRule. This transformation is |
| // designed to present a purely physical version of an operator |
| // that is both logical and physical. |
| // ----------------------------------------------------------------------- |
| class PhysicalMapValueIds : public MapValueIds |
| { |
| public: |
| PhysicalMapValueIds(RelExpr *childExpr, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : MapValueIds(childExpr,oHeap) {}; |
| |
| PhysicalMapValueIds(const MapValueIds & other) : MapValueIds(other) {}; |
| |
| virtual NABoolean isLogical() const; |
| virtual NABoolean isPhysical() const; |
| |
| virtual PlanPriority computeOperatorPriority |
| (const Context* context, |
| PlanWorkSpace *pws=NULL, |
| Lng32 planNumber=0); |
| |
| }; // class PhysicalMapValueIds |
| |
| // ----------------------------------------------------------------------- |
| // The FirstN class is used to return the first N rows that are returned |
| // by its child. At runtime, it sends a Get_N to its child and returns the |
| // N rows returned by its child to its parent. It doesn't do anything |
| // else on those returned row. |
| // This class could be put anywhere in query tree. It eliminates the need |
| // for a runtime operator to know if it needs to look at its compile time |
| // first N rows entry or its down queue GET_N entry before it could return |
| // the N rows. With this node, the runtime operators only need to process |
| // the GET_N down queue correctly. |
| // ----------------------------------------------------------------------- |
| class FirstN : public RelExpr |
| { |
| public: |
| FirstN(RelExpr * child, |
| Int64 firstNRows, |
| NABoolean isFirstN, |
| ItemExpr * firstNRowsParam = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_FIRST_N, child, NULL, oHeap), |
| firstNRows_(firstNRows), |
| firstNRowsParam_(firstNRowsParam), |
| canExecuteInDp2_(FALSE), |
| isFirstN_(isFirstN) |
| { |
| setNonCacheable(); |
| }; |
| |
| // sets the canExecuteInDp2 flag for the [LAST 1] operator |
| // of an MTS delete and calls the base class implementation of bindNode. |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| |
| // takes care of any ordering requirement on the child |
| virtual Context* createContextForAChild(Context* myContext, |
| PlanWorkSpace* pws, |
| Lng32& childIndex); |
| |
| // |
| // Physical properties implemented in OptPhysRelExpr.cpp |
| // |
| PhysicalProperty *synthPhysicalProperty(const Context* myContext, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| |
| virtual RelExpr * preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| |
| // method to do code generation |
| virtual short codeGen(Generator*); |
| |
| // this is both logical and physical node |
| virtual NABoolean isLogical() const{return TRUE;}; |
| virtual NABoolean isPhysical() const{return TRUE;}; |
| |
| // various PC methods |
| |
| // get the degree of this node |
| virtual Int32 getArity() const{return 1;}; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual const NAString getText() const; |
| |
| void setFirstNRows(Int64 firstNRows) { firstNRows_ = firstNRows; } |
| Int64 getFirstNRows() { return firstNRows_; } |
| |
| void setFirstNRowsParam(ItemExpr *firstNRowsParam) |
| { firstNRowsParam_ = firstNRowsParam; } |
| ItemExpr * getFirstNRowsParam() { return firstNRowsParam_; } |
| |
| void setCanExecuteInDp2(NABoolean flag) { canExecuteInDp2_ = flag; } |
| NABoolean canExecuteInDp2() const { return canExecuteInDp2_; } |
| virtual NABoolean computeRowsAffected() const ; |
| |
| NABoolean isFirstN() { return isFirstN_; } |
| |
| ValueIdList & reqdOrder() { return reqdOrder_; } |
| ValueIdList & reqdOrderInSubquery() { return reqdOrderInSubquery_; } |
| |
| private: |
| // Otherwise, return firstNRows_ at runtime. |
| Int64 firstNRows_; |
| ItemExpr * firstNRowsParam_; |
| NABoolean canExecuteInDp2_; |
| NABoolean isFirstN_; // TRUE if [first n], FALSE if [any n] or [last n] |
| |
| // Optional ORDER BY to force ordering before applying First N; populated |
| // at normalizeNode time. |
| ValueIdList reqdOrder_; |
| ValueIdList reqdOrderInSubquery_; |
| |
| }; // class FirstN |
| |
| |
| // Class Transpose ---------------------------------------------------- |
| // The Transpose RelExpr is a logical RelExpr node used to implement the |
| // TRANSPOSE operator. It is implemented by the physical RelExpr node |
| // PhysTranspose. (It would be possible to develop an implementation rule |
| // which implemented this node as a tree of union nodes.) The data members |
| // of the class are: |
| // |
| // transValsTree_: This ItemExpr tree contains a list of pairs which is |
| // NULL terminated (for ease of processing). Each pair contains in child(0), |
| // a list of transpose items for a given transpose set and in child(1), a |
| // list of ColReferences to the new value columns associated with this |
| // transpose set. A transpose item is a list of value expressions. |
| // This pointer is set to NULL by bindNode. |
| // |
| // keyCol_: Contains the ColReference to the key column. |
| // This data member is constructed by the parser. |
| // This ItemExpr tree is set to NULL in the Binder (Transpose::BindNode()). |
| // |
| // transUnionVector_: This is a vector of ValueIdLists. There is one entry |
| // for each transpose set, plus one entry for the key values. Each entry |
| // contains a list of ValueIdUnion Nodes. The first entry contains a list |
| // with one ValueIdUnion node. This node is for the Const. Values (1 - N) |
| // representing the Key Values. The other entries contain lists of |
| // ValueIdUnion nodes for the Transposed Values. Each of these entries of |
| // the vector represent a transpose set. If the transpose set contains a |
| // list of values, then there will be only one ValueIdUnion node in the |
| // list. If the transpose set contains a list of lists of values, then |
| // there will be as many ValueIdUnion nodes as there are items in the |
| // sublists. (see example below.) |
| // transUnionVector_ is generated in bindNode(). |
| // |
| // transUnionVectorSize_: This is the number of entries in transUnionVector_. |
| // |
| class Transpose : public RelExpr |
| { |
| public: |
| |
| // The constructor |
| // |
| // Inputs: |
| // |
| // transExprs: Contains a list of pairs, each pair contains |
| // in child(0), a list of expressions for a given transpose group |
| // and in child(1), the name associated with this transpose group. |
| // Default value: NULL |
| // |
| // keyCol: Contains the ColReference to the key column. |
| // Default value: NULL |
| // |
| // child: The child RelExpr node of this node. |
| // Default Value NULL |
| // |
| // Constructs a Transpose Node. |
| // |
| // Called by Parser (yyparse()), CreateImplementationRules(), Transpose:: |
| // copyTopNode(), and the PhysTranspose constructor. |
| Transpose(ItemExpr *transExprs = NULL, |
| ItemExpr *keyCol = NULL, |
| RelExpr *child = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| |
| : RelExpr(REL_TRANSPOSE,child,NULL,oHeap), |
| transValsTree_(transExprs), |
| keyCol_(keyCol), |
| transUnionVectorSize_(0), |
| transUnionVector_(0) |
| { |
| setNonCacheable(); |
| } |
| |
| // The destructor |
| // |
| virtual ~Transpose(); |
| |
| // Transpose has one child. |
| // |
| virtual Int32 getArity() const {return 1;}; |
| |
| // Return a pointer to the transpose Values tree. |
| // |
| inline const ItemExpr *transValsTree() const {return transValsTree_;}; |
| |
| // Return a pointer to the transpose Values tree after |
| // setting it to NULL. |
| // |
| const ItemExpr *removeTransValsTree(); |
| |
| // Return a pointer to the keyCol ColReference node. |
| // |
| inline const ItemExpr *keyCol() const {return keyCol_;}; |
| |
| // Return a pointer to the keyCol ColReference node after setting |
| // it to NULL. |
| // |
| const ItemExpr *removeKeyCol(); |
| |
| // return a read/write reference to the transpose Union Vector. |
| // |
| inline ValueIdList *&transUnionVector() |
| { |
| return transUnionVector_; |
| }; |
| |
| // return a read-only reference to the transpose Union Vector. |
| // |
| inline const ValueIdList *transUnionVector() const |
| { |
| return transUnionVector_; |
| }; |
| |
| // return the size of the transpose union vector. |
| // |
| inline CollIndex transUnionVectorSize() const |
| { |
| return transUnionVectorSize_; |
| }; |
| |
| inline void setTransUnionVectorSize(CollIndex size) |
| { |
| transUnionVectorSize_ = size; |
| }; |
| |
| // This method is used in case there are expressions in the Transpose column |
| // list. It traverses through the expression to get the column under them |
| // If it is a unary expression, it gets the column directly below the expression. |
| // If the expression has two children, it goes through both the children |
| // to see which one of them has a higher UEC. It returns the ValueId of that |
| // column. This column is later used to determine the UEC of the final |
| // transpose column. |
| |
| ValueId getSourceColFromExprForUec(ValueId sourceValId, const ColStatDescList & childColStatsList); |
| |
| // a virtual function for performing name binding within the query tree |
| // Transpose::bindNode() generates a list of ValueIdUnion nodes from the |
| // transValsTree constructed by the parser. |
| // |
| RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| // |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| |
| // a method used during subquery transformation for pulling up predicates |
| // towards the root of the transformed subquery tree |
| // |
| // The default implementation is adequate for Transpose |
| //virtual void pullUpPreds(); |
| |
| // a method used for recomputing the outer references (external dataflow |
| // input values) that are still referenced by each operator in the |
| // subquery tree after the predicate pull up is complete. |
| // |
| virtual void recomputeOuterReferences(); |
| |
| // Each operator supports a (virtual) method for rewriting its |
| // value expressions. |
| // |
| virtual void rewriteNode(NormWA & normWARef); |
| |
| // Each operator supports a (virtual) method for performing |
| // predicate pushdown and computing a "minimal" set of |
| // characteristic input and characteristic output values. |
| // |
| // The default implementation is adequate for Transpose |
| //virtual RelExpr * normalizeNode(NormWA & normWARef); |
| |
| // Method to push down predicates from a Transpose node into the |
| // children |
| // |
| virtual |
| void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator, |
| const ValueIdSet & newExternalInputs, |
| ValueIdSet& predOnOperator, |
| const ValueIdSet * nonPredExprOnOperator = NULL, |
| Lng32 childId = (-MAX_REL_ARITY) ); |
| |
| // Return a the set of potential output values of this node. |
| // For transpose, this is the potential outputs of the child, |
| // plus the key column and all the value columns generated by |
| // transpose. |
| // |
| virtual void getPotentialOutputValues(ValueIdSet &vs) const; |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool and Explain) |
| // |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| // Compute a hash value for a chain of derived RelExpr nodes. |
| // Used by the Cascade engine as a quick way to determine if |
| // two nodes are identical. |
| // Can produce false positives, but should not produce false |
| // negatives. |
| // |
| virtual HashValue topHash(); |
| |
| // A more thorough method to compare two RelExpr nodes. |
| // Used by the Cascades engine. |
| // |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| |
| // Copy a chain of derived nodes (Calls RelExpr::copyTopNode). |
| // Needs to copy all relevant fields. |
| // Used by the Cascades engine. |
| // |
| virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap *outHeap = NULL); |
| |
| // synthesize logical properties |
| // |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // get a printable string that identifies the operator |
| // |
| virtual const NAString getText() const {return "TRANSPOSE";}; |
| |
| private: |
| |
| // This ItemExpr tree contains a list of pairs which is |
| // NULL terminated (for ease of processing). Each pair contains in child(0), |
| // a list of transpose items for a given transpose set and in child(1), a |
| // list of ColReferences to the new value columns associated with this |
| // transpose set. A transpose item is a list of value expressions. |
| // This pointer is set to NULL by bindNode. |
| // |
| ItemExpr *transValsTree_; |
| |
| // Contains the ColReference to the key column. |
| // This ItemExpr tree is set to NULL in the Binder (Transpose::BindNode()). |
| // |
| ItemExpr *keyCol_; |
| |
| // This is the number of entries in transUnionVector_ (see below). |
| // |
| CollIndex transUnionVectorSize_; |
| |
| // This is a vector of ValueIdLists. There is one entry |
| // for each transpose set, plus one entry for the key values. Each entry |
| // contains a list of ValueIdUnion Nodes. The first entry contains a list |
| // with one ValueIdUnion node. This node is for the Const. Values (1 - N) |
| // representing the Key Values. The other entries contain lists of |
| // ValueIdUnion nodes for the Transposed Values. Each of these entries of |
| // the vector represent a transpose set. If the transpose set contains a |
| // list of values, then there will be only one ValueIdUnion node in the |
| // list. If the transpose set contains a list of lists of values, then |
| // there will be as many ValueIdUnion nodes as there are items in the |
| // sublists. transUnionVector_ is generated in bindNode(). |
| // |
| ValueIdList *transUnionVector_; |
| |
| }; // class Transpose |
| |
| // Class PhysTranspose ---------------------------------------------------- |
| // The PhysTranspose node replaces the logical Transpose node through the |
| // application of the PhysTransposeRule. This transformation is |
| // designed to present a purely physical verison of this operator |
| // that is both a logical and physical node. The PhysTranspose node |
| // does not add any data members. It adds a few virtual methods. |
| // ----------------------------------------------------------------------- |
| class PhysTranspose : public Transpose |
| { |
| public: |
| |
| // The constructor |
| // |
| PhysTranspose(RelExpr *child = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : Transpose(NULL,NULL,child,oHeap) {}; |
| |
| // The destructor. |
| // |
| virtual ~PhysTranspose(); |
| |
| // methods to do code generation of the physical node. |
| // |
| virtual RelExpr * preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| virtual short codeGen(Generator*); |
| |
| |
| // generate CONTROL QUERY SHAPE fragment for this node. |
| // |
| virtual short generateShape(CollHeap * space, char * buf, NAString * shapeStr = NULL); |
| |
| // Copy a chain of derived nodes (Calls Transpose::copyTopNode). |
| // Needs to copy all relevant fields (in this case no fields |
| // need to be copied) |
| // Used by the Cascades engine. |
| // |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap *outHeap = NULL); |
| |
| // cost functions |
| // |
| virtual PhysicalProperty *synthPhysicalProperty(const Context *context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| virtual CostMethod* costMethod() const; |
| |
| // Redefine these virtual methods to declare this node as a |
| // physical node. |
| // |
| virtual NABoolean isLogical() const {return FALSE;}; |
| virtual NABoolean isPhysical() const {return TRUE;}; |
| |
| }; // class PhysTranspose |
| |
| // ----------------------------------------------------------------------- |
| // The Pack node is used to implement packing of several logical rows into |
| // one physical row on a column by column basis. The no of logical rows |
| // packed into one physical row is determined by the packing factor (pf). |
| // The packed table have the same no of columns as the original table. The |
| // type of the column in the packed table is varchar(len * pf) where len |
| // is the length (in bytes) of the corresponding column in the original |
| // table. For example, if the input table has columns (x int, y int), and |
| // the packing factor is 2 the output table will be (xpacked varchar(8), |
| // ypacked varchar(8)). {x|y}packed will contain the values of {x|y} in 2 |
| // contiguous rows of the original table packed together. |
| // ----------------------------------------------------------------------- |
| class Pack : public RelExpr |
| { |
| public: |
| |
| // --------------------------------------------------------------------- |
| // Constructor/Destructor/Accessors/Mutators. |
| // --------------------------------------------------------------------- |
| |
| // Constructor. |
| Pack(ULng32 packingFactor = 0, |
| RelExpr* child = NULL, |
| ItemExpr* packingExprTree = NULL, |
| CollHeap* oHeap = CmpCommon::statementHeap()); |
| |
| // Destructor. |
| virtual ~Pack(); |
| |
| // No of children. |
| virtual Int32 getArity() const { return 1; } |
| |
| // Returns a (short-lived) r/w ref to packing factor in different forms. |
| ULng32& packingFactorLong() { return packingFactorLong_; } |
| ULng32 packingFactorLong() const { return packingFactorLong_; } |
| inline ValueIdSet& packingFactor() { return packingFactor_; } |
| inline const ValueIdSet& packingFactor() const |
| { return packingFactor_; } |
| |
| // Returns a pointer to the packing factor item expr (& set it to NULL). |
| inline const ItemExpr* packingFactorTree() const |
| { return packingFactorTree_; } |
| ItemExpr* removePackingFactorTree(); |
| |
| // Returns a pointer to the packing expression tree (& set it to NULL). |
| inline const ItemExpr* packingExprTree() const |
| { return packingExprTree_; } |
| ItemExpr* removePackingExprTree(); |
| |
| // Returns a (short-lived) r/w ref to the packing expression. |
| inline ValueIdList& packingExpr() { return packingExpr_; } |
| inline const ValueIdList& packingExpr() const { return packingExpr_; } |
| |
| // --------------------------------------------------------------------- |
| // Some helper methods. |
| // --------------------------------------------------------------------- |
| |
| // Retrieve into vidset the sub-expressions in the packing expression. |
| void getNonPackedExpr(ValueIdSet& vidset); |
| |
| // --------------------------------------------------------------------- |
| // Methods to support Binding. |
| // --------------------------------------------------------------------- |
| |
| // It creates the RETDesc and packingExpr_ to be made of packed columns. |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| |
| // --------------------------------------------------------------------- |
| // Methods to support Transformation. |
| // --------------------------------------------------------------------- |
| |
| // Re-defined to transform the packingExpr_ which might contain a subq. |
| virtual void transformNode(NormWA& normWA, ExprGroupId& locPtrToMe); |
| |
| // Refined to disallow predicates pullup since they are on unpacked col. |
| virtual void pullUpPreds(); |
| |
| // Refined to add in the ConstValue object needed for the packing factor. |
| virtual void recomputeOuterReferences(); |
| |
| // --------------------------------------------------------------------- |
| // Methods to support Normalization. |
| // --------------------------------------------------------------------- |
| |
| // Refined to rewrite sub-expressions in packingExpr_ to VEG if needed. |
| virtual void rewriteNode(NormWA& normWA); |
| |
| virtual Context* createContextForAChild(Context* myContext, |
| PlanWorkSpace* pws, |
| Lng32& childIndex); |
| |
| // Refined to add in the sub-expression for each expr in packingExpr_ to |
| // nonPredExprOnOperator. |
| virtual void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator, |
| const ValueIdSet& newExternalInputs, |
| ValueIdSet& predOnOperator, |
| const ValueIdSet * nonPredExprOnOperator = NULL, |
| Lng32 childId = (-MAX_REL_ARITY)); |
| |
| // Refined to return the packing expression. |
| virtual void getPotentialOutputValues(ValueIdSet& vs) const; |
| |
| // --------------------------------------------------------------------- |
| // Methods to support Optimization. |
| // --------------------------------------------------------------------- |
| |
| // --------------------------------------------------------------------- |
| // Compute hash value for a chain of derived RelExpr nodes. Used by |
| // Cascades as a quick way to determine if two nodes are identical. |
| // --------------------------------------------------------------------- |
| virtual HashValue topHash(); |
| |
| // Exact method for Cascades to decide whether the two operators match. |
| virtual NABoolean duplicateMatch(const RelExpr& other) const; |
| |
| // Used by Cascades to make a deep copy of the node. |
| virtual RelExpr* copyTopNode(RelExpr* derivedNode = NULL, |
| CollHeap* outHeap = NULL); |
| |
| // Logical properties. Not yet handled in this prototype. |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // --------------------------------------------------------------------- |
| // Methods to support GUI/debugging. |
| // --------------------------------------------------------------------- |
| |
| // Refined to display the packing expression. |
| virtual void addLocalExpr(LIST(ExprNode*)& xlist, |
| LIST(NAString)& llist) const; |
| |
| // Refined to return the string describing this Pack node. |
| virtual const NAString getText() const; |
| |
| // Methods for requiredOrder_ |
| inline const ValueIdList & requiredOrder() const { return requiredOrder_; } |
| |
| inline void setRequiredOrder(const ValueIdList &reqOrder) |
| { requiredOrder_ = reqOrder; } |
| |
| protected: |
| |
| inline ValueIdList & requiredOrder() { return requiredOrder_; } |
| |
| private: |
| |
| // --------------------------------------------------------------------- |
| // Packing factor is the no of logical rows which get packed into a |
| // physical row. This member provides a more convenient way of getting |
| // the packing factor (as opposed to through the ItemExpr) when it is |
| // a constant. Not valid when equals zero. |
| // --------------------------------------------------------------------- |
| ULng32 packingFactorLong_; |
| |
| // --------------------------------------------------------------------- |
| // This is the item expression tree for the packing factor. Right now, |
| // the tree must point to a ConstValue. |
| // --------------------------------------------------------------------- |
| ItemExpr* packingFactorTree_; |
| |
| // --------------------------------------------------------------------- |
| // This set contains ValueId for the packing factor tree. It is a set |
| // but not just a ValueId because this facilitates expression rewriting. |
| // --------------------------------------------------------------------- |
| ValueIdSet packingFactor_; |
| |
| // --------------------------------------------------------------------- |
| // The packing expression tree contains a list of values to the packed, |
| // each topped by the packing function (PackFunc). |
| // --------------------------------------------------------------------- |
| ItemExpr* packingExprTree_; |
| |
| // --------------------------------------------------------------------- |
| // ValueId's of the list of values in packingExprTree_. |
| // --------------------------------------------------------------------- |
| ValueIdList packingExpr_; |
| |
| // Return a pointer to the required order tree after |
| // setting it to NULL. |
| // |
| ItemExpr *removeRequiredOrderTree(); |
| |
| // A bound list of columns representing the required sort order |
| // for this node. |
| ValueIdList requiredOrder_; |
| |
| }; // class Pack |
| |
| // ----------------------------------------------------------------------- |
| // An implementation rule changes the logical Pack node into the physical |
| // PhyPack node. |
| // ----------------------------------------------------------------------- |
| class PhyPack : public Pack |
| { |
| public: |
| |
| // Constructor. |
| PhyPack(ULng32 packingFactor = 0, |
| RelExpr* child = NULL, |
| CollHeap* oHeap = CmpCommon::statementHeap()) |
| : Pack(packingFactor,child,NULL,oHeap) {} |
| |
| // Destructor. |
| virtual ~PhyPack(); |
| |
| virtual NABoolean isLogical() const { return FALSE; } |
| virtual NABoolean isPhysical() const { return TRUE; } |
| |
| // --------------------------------------------------------------------- |
| // Methods to support Optimization. |
| // --------------------------------------------------------------------- |
| virtual RelExpr* copyTopNode(RelExpr* derivedNode = NULL, |
| CollHeap* outHeap = NULL); |
| |
| // --------------------------------------------------------------------- |
| // Pre-Code Generation. |
| // --------------------------------------------------------------------- |
| virtual RelExpr* preCodeGen(Generator * generator, |
| const ValueIdSet & externalInputs, |
| ValueIdSet &pulledNewInputs); |
| |
| // generate CONTROL QUERY SHAPE fragment for this node. |
| // |
| virtual short generateShape(CollHeap * space, char * buf, NAString * shapeStr = NULL); |
| |
| // --------------------------------------------------------------------- |
| // Code Generation. |
| // --------------------------------------------------------------------- |
| virtual short codeGen(Generator* generator); |
| |
| // --------------------------------------------------------------------- |
| // Methods on Physical Properties and Costing. |
| // --------------------------------------------------------------------- |
| virtual PhysicalProperty* synthPhysicalProperty(const Context* context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| virtual CostMethod* costMethod() const; |
| |
| }; // class PhyPack |
| |
| class Rowset : public RelExpr |
| { |
| public: |
| |
| // --------------------------------------------------------------------- |
| // Constructor/Destructor/Accessors/Mutators. |
| // --------------------------------------------------------------------- |
| |
| // constructor |
| Rowset(ItemExpr *inputHostvars, |
| ItemExpr *indexExpr = NULL, |
| ItemExpr *sizeExpr = NULL, |
| RelExpr *childExpr = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| virtual ~Rowset(); |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual Int32 getArity () const; |
| virtual const NAString getText() const; |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| // returns the name of the exposed index of the Rowset |
| virtual const NAString getIndexName () const; |
| |
| protected: |
| // an expression with the value of the single tuple |
| ItemExpr *inputHostvars_; // Host variable arrays composing the rowset |
| ItemExpr *indexExpr_; // The exposed index of the Rowset |
| ItemExpr *sizeExpr_; // RowSet size cannot be greater than declared |
| // dimensions of arrays composing rowset. |
| // If NULL, it would take smallest of declared |
| // dimensions |
| RelExpr *transformRelexpr_; // New transformed tree |
| }; // class Rowset |
| |
| class RowsetRowwise : public Rowset |
| { |
| public: |
| |
| // --------------------------------------------------------------------- |
| // Constructor/Destructor/Accessors/Mutators. |
| // --------------------------------------------------------------------- |
| |
| // constructor |
| RowsetRowwise(RelExpr *childExpr = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual const NAString getText() const; |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| virtual Int32 getArity () const; |
| |
| private: |
| }; // class RowsetRowwise |
| |
| class RowsetInto : public RelExpr |
| { |
| public: |
| |
| // --------------------------------------------------------------------- |
| // Constructor/Destructor/Accessors/Mutators. |
| // --------------------------------------------------------------------- |
| |
| // constructor |
| RowsetInto(RelExpr *child, |
| ItemExpr *outputHostvars, |
| ItemExpr *sizeExpr = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| virtual ~RowsetInto(); |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual Int32 getArity () const; |
| virtual const NAString getText() const; |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| |
| inline const ValueIdList & requiredOrder() const { return requiredOrder_; } |
| |
| inline void setRequiredOrder(const ValueIdList &reqOrder) |
| { requiredOrder_ = reqOrder; } |
| |
| inline void setRequiredOrderTree(ItemExpr *reqOrderTree) |
| { requiredOrderTree_ = reqOrderTree; } |
| |
| inline const ItemExpr * requiredOrderTree() const { return requiredOrderTree_; } |
| |
| ItemExpr *getRowsetArrays() {return outputHostvars_;}; |
| |
| protected: |
| |
| inline ValueIdList & requiredOrder() { return requiredOrder_; } |
| |
| |
| private: |
| |
| // Return a pointer to the required order tree after |
| // setting it to NULL. |
| // |
| ItemExpr *removeRequiredOrderTree(); |
| |
| // an expression with the value of the single tuple |
| ItemExpr *outputHostvars_; // Host variable arrays composing the rowset |
| ItemExpr *sizeExpr_; // RowSet size cannot be greater than declared |
| // dimensions of arrays composing rowset. |
| // If NULL, it would take smallest of declared |
| // dimensions |
| RelExpr *transformRelexpr_; // New transformed tree |
| |
| // An ItemExpr list of columns representing the reqired sort order |
| // for this node. |
| // |
| ItemExpr *requiredOrderTree_; |
| |
| // The bound version of requiredOrderTree_. |
| // |
| |
| ValueIdList requiredOrder_; |
| |
| }; // class RowsetInto |
| |
| class RowsetFor : public RelExpr |
| { |
| public: |
| RowsetFor(RelExpr *child, |
| ItemExpr *inputSizeExpr, |
| ItemExpr *outputSizeExpr = NULL, |
| ItemExpr *indexExpr = NULL, |
| ItemExpr *maxSizeExpr = NULL, |
| ItemExpr *maxInputRowlen = NULL, |
| ItemExpr *rwrsBuffer = NULL, |
| ItemExpr *partnNum = NULL, |
| CollHeap *oHeap = CmpCommon::statementHeap()); |
| |
| virtual ~RowsetFor(); |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| virtual Int32 getArity () const; |
| virtual const NAString getText() const; |
| virtual RelExpr* bindNode(BindWA* bindWA); |
| |
| ItemExpr * getInputSize() {return inputSizeExpr_;} |
| ItemExpr * getOutputSize() {return outputSizeExpr_;} |
| ItemExpr * getIndexExpr() {return indexExpr_;} |
| |
| // next fields are for rowwise rowset |
| ItemExpr * getMaxSizeExpr() {return maxSizeExpr_; } |
| ItemExpr * getMaxInputRowlen() { return maxInputRowlen_; } |
| ItemExpr * getRwrsBuffer() {return rwrsBuffer_;} |
| ItemExpr * partnNum() {return partnNum_;} |
| |
| NABoolean &rowwiseRowset() { return rowwiseRowset_; } |
| |
| void setBufferAttributes(NABoolean packedFormat, |
| NABoolean compressed, |
| NABoolean dcompressInMaster, |
| NABoolean compressInMaster, |
| NABoolean partnNumInBuffer) |
| { |
| packedFormat_ = packedFormat; |
| compressed_ = compressed; |
| dcompressInMaster_ = dcompressInMaster; |
| compressInMaster_ = compressInMaster; |
| } |
| void getBufferAttributes(NABoolean &packedFormat, |
| NABoolean &compressed, |
| NABoolean &dcompressInMaster, |
| NABoolean &compressInMaster, |
| NABoolean &partnNumInBuffer) |
| { |
| packedFormat = packedFormat_; |
| compressed = compressed_; |
| dcompressInMaster = dcompressInMaster_; |
| compressInMaster = compressInMaster_; |
| partnNumInBuffer = partnNumInBuffer_; |
| } |
| |
| private: |
| ItemExpr *inputSizeExpr_; // RowSet size cannot be greater than declared |
| // dimensions of arrays composing rowset. |
| // If NULL, it would take smallest of declared |
| // dimensions |
| ItemExpr *outputSizeExpr_; // RowSet size cannot be greater than declared |
| // dimensions of arrays composing rowset. |
| // If NULL, it would take smallest of declared |
| // dimensions |
| ItemExpr *indexExpr_; // The exposed index of the Rowset |
| |
| ItemExpr *maxSizeExpr_; // Input rowwise rowset max size. |
| |
| ItemExpr *maxInputRowlen_; // max length of each input row in the |
| // input rowwise rowset buffer. |
| ItemExpr *rwrsBuffer_; // Contains the address of rowwise-rowset |
| // buffer passed in at runtime to cli. |
| ItemExpr *partnNum_; // partition number where this buffer need |
| // to be shipped to. |
| NABoolean rowwiseRowset_; // layout of input values is rowwise. |
| |
| // rows are packed sql/mp style in the buffer. All columns are packed |
| // next to each other with no fillers or varchar/null optimizations. |
| NABoolean packedFormat_; |
| |
| // input buffer is compressed by caller. |
| NABoolean compressed_; |
| |
| // Next member valid only if compressed_ is TRUE; |
| // if TRUE, dcompress the buffer in master before doing other processing. |
| // if FALSE, ship the compressed buffer to eid and decompress it there. |
| // This option is only valid if partnNum is specified. |
| NABoolean dcompressInMaster_; |
| |
| // Next field is valid if buffer is not compressed_. |
| // Next field is valid only if partnNum is specified. |
| // If TRUE, master exe need to compress the buffer before shipping to eid. |
| NABoolean compressInMaster_; |
| |
| // TRUE, if partition number is sent in at runtime as part of input buffer, |
| // instead of dynamic parameter partnNum_ |
| NABoolean partnNumInBuffer_; |
| }; // class RowsetFor |
| |
| |
| OptSqlTableOpenInfo *setupStoi(OptSqlTableOpenInfo *&optStoi_, |
| BindWA *bindWA, |
| const RelExpr *re, |
| const NATable *naTable, |
| const CorrName &corrName, |
| NABoolean noSecurityCheck = FALSE); |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Suspend, reactivate or cancel a query. |
| // |
| // The Suspend and Activate functions are handled by |
| // ExeUtilSuspend. |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| class ControlRunningQuery : public RelExpr |
| { |
| public: |
| |
| enum Action { |
| Cancel, |
| Suspend, |
| Activate |
| }; |
| |
| enum ForceOption { |
| Safe, |
| Force, |
| CancelOrActivateIsAlwaysSafe |
| }; |
| |
| enum QuerySpec { |
| ControlQid, |
| ControlPname, |
| ControlNidPid |
| }; |
| |
| |
| ControlRunningQuery(NAString &qid_or_pid, |
| QuerySpec qs, |
| Action action, |
| ForceOption forceOption, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_CONTROL_RUNNING_QUERY, NULL, NULL, oHeap), |
| queryId_("") |
| , pname_("") |
| , nid_(-1) |
| , pid_(-1) |
| , action_(action) |
| , forced_(forceOption) |
| , qs_(qs) |
| { |
| switch (qs) |
| { |
| case ControlQid: |
| queryId_ = qid_or_pid; break; |
| case ControlPname: |
| pname_ = qid_or_pid; break; |
| default: |
| CMPASSERT(0); |
| } |
| comment_ = ""; |
| }; |
| |
| ControlRunningQuery(int nid, int pid, |
| QuerySpec qs, |
| Action action, |
| ForceOption forceOption, |
| CollHeap *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_CONTROL_RUNNING_QUERY, NULL, NULL, oHeap), |
| queryId_("") |
| , pname_("") |
| , nid_(nid) |
| , pid_(pid) |
| , action_(action) |
| , forced_(forceOption) |
| , qs_(qs) |
| { |
| CMPASSERT(qs == ControlNidPid); |
| comment_ = ""; |
| }; |
| |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| virtual RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| virtual PhysicalProperty *synthPhysicalProperty(const Context *context, |
| const Lng32 planNumber, |
| PlanWorkSpace *pws); |
| |
| // method to do code generation |
| virtual short codeGen(Generator*); |
| |
| virtual NABoolean isLogical() const; |
| virtual NABoolean isPhysical() const; |
| virtual Int32 getArity() const; |
| virtual const NAString getText() const; |
| virtual ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *, |
| ComTdb *, Generator *); |
| |
| bool isUserAuthorized(BindWA *bindWA); |
| void setComment(NAString &comment); |
| |
| private: |
| NAString queryId_; |
| NAString pname_; |
| int nid_; |
| int pid_; |
| Action action_; |
| ForceOption forced_; |
| QuerySpec qs_; |
| NAString comment_; |
| }; |
| |
| // forward reference |
| class CountedCSEInfo; |
| |
| // Container for the common info about a common subexpression. This is |
| // a helper class for class CommonSubExprRef below. |
| |
| // This class is stored in the CmpStatement object, but it is defined |
| // here because it is closely related to the CommonSubExprRef class |
| // and because it contains ValueIdSet and ValueIdList data members |
| // which should not be used by CmpStatement classes directly. |
| |
| // Note about acronyms: |
| // CTE: Common Table Expression syntax (WITH clause) in SQL |
| // CSE: Common SubExpression (could be WITH clause or |
| // another type of common subexpression) |
| class CSEInfo : public NABasicObject |
| { |
| public: |
| |
| enum CSEAnalysisOutcome |
| { |
| UNKNOWN_ANALYSIS, // analysis not yet done |
| ELIMINATED_IN_BINDER,// single-consumer CSE, eliminated in binder |
| EXPAND, // expand the common subexpression |
| CREATE_TEMP, // materialize CSE as temp, then read the temp |
| TEMP, // read the temp created by someone else |
| ERROR // error occurred, diags are set |
| // possible future analysis outcomes: |
| // - decide outcome in the optimizer |
| // - pipeline results from a single producer to multiple consumers |
| // |
| // Note: Right now, all consumers of a CSE have the same |
| // outcome; that may change in the future, |
| // e.g. we may have 5 consumers that can use sharing |
| // very well and one that isn't suitable for sharing |
| // (maybe because it reads different data). |
| }; |
| |
| enum CSETempTableType |
| { |
| UNKNOWN_TEMP_TABLE, // temp table type not yet determined |
| HIVE_TEMP_TABLE, // use a Hive delimited table |
| VOLATILE_TEMP_TABLE // use a Trafodion volatile table |
| }; |
| |
| CSEInfo(const char *name, |
| NAMemory *mem) : |
| name_(name, mem), |
| cseId_(-1), |
| childCSEs_(mem), |
| consumers_(mem), |
| alternativeConsumers_(mem), |
| numLexicalRefs_(0), |
| neededColumns_(mem), |
| cseTreeKeyColumns_(mem), |
| idOfAnalyzingConsumer_(-1), |
| analysisOutcome_(UNKNOWN_ANALYSIS), |
| tempTableType_(UNKNOWN_TEMP_TABLE), |
| tempTableName_(mem), |
| tempTableDDL_(mem), |
| tempNATable_(NULL), |
| insertIntoTemp_(NULL) |
| {} |
| |
| const NAString &getName() const { return name_; } |
| Int32 getCSEId() const { return cseId_; } |
| const LIST(CountedCSEInfo) &getChildCSEs() const { return childCSEs_; } |
| const CollIndex getNumConsumers() const { return consumers_.entries(); } |
| CommonSubExprRef *getConsumer(CollIndex i) const { return consumers_[i]; } |
| Int32 getNumLexicalRefs() const { return numLexicalRefs_; } |
| Int32 getTotalNumRefs(Int32 restrictToSingleConsumer = -1) const; |
| |
| Int32 getIdOfAnalyzingConsumer() const { return idOfAnalyzingConsumer_; } |
| CSEAnalysisOutcome getAnalysisOutcome(Int32 id) const; |
| NABoolean isShared(Int32 id) const |
| { return analysisOutcome_ == CREATE_TEMP; } |
| NABoolean usesATempTable() const { return insertIntoTemp_ != NULL; } |
| CSETempTableType getTempTableType() const { return tempTableType_; } |
| const NABitVector &getNeededColumns() const { return neededColumns_; } |
| const ValueIdSet &getCommonPredicates() const { return commonPredicates_; } |
| const ValueIdSet &getVEGRefsWithDifferingConstants() const |
| { return vegRefsWithDifferingConstants_; } |
| const ValueIdSet &getVEGRefsWithDifferingInputs() const |
| { return vegRefsWithDifferingInputs_; } |
| const NABitVector &getCSETreeKeyColumns() const |
| { return cseTreeKeyColumns_; } |
| const QualifiedName &getTempTableName() const { return tempTableName_; } |
| const NAString &getTempTableDDL() const { return tempTableDDL_; } |
| const NATable *getTempNATable() const { return tempNATable_; } |
| RelExpr *getInsertIntoTemp() const { return insertIntoTemp_; } |
| |
| void setCSEId(Int32 id) { cseId_ = id; } |
| Int32 addChildCSE(CSEInfo *childInfo, NABoolean addLexicalRef); |
| void addCSERef(CommonSubExprRef *cse); |
| void eliminate() { analysisOutcome_ == ELIMINATED_IN_BINDER; } |
| void registerAnAlternativeConsumer(CommonSubExprRef *c) |
| { alternativeConsumers_.insert(c); } |
| void replaceConsumerWithAnAlternative(CommonSubExprRef *c); |
| void setIdOfAnalyzingConsumer(Int32 id) { idOfAnalyzingConsumer_ = id; } |
| void setAnalysisOutcome(CSEAnalysisOutcome outcome) |
| { analysisOutcome_ = outcome; } |
| void setTempTableType(CSETempTableType t) { tempTableType_ = t; } |
| |
| void setNeededColumns(const NABitVector &v) { neededColumns_ = v; } |
| void setCommonPredicates(const ValueIdSet &s) { commonPredicates_ = s; } |
| void addCommonPredicates(const ValueIdSet &s) { commonPredicates_ += s; } |
| void addVEGRefsWithDifferingConstants(const ValueIdSet &s) |
| { vegRefsWithDifferingConstants_ += s; } |
| void addVEGRefsWithDifferingInputs(const ValueIdSet &s) |
| { vegRefsWithDifferingInputs_ += s; } |
| void addCSEKeyColumn(CollIndex c) { cseTreeKeyColumns_ += c; } |
| void setTempTableName(const QualifiedName &n) { tempTableName_ = n; } |
| void setTempTableDDL(const char *s) { tempTableDDL_ = s; } |
| void setTempNATable(const NATable *nat) { tempNATable_ = nat; } |
| void setInsertIntoTemp(RelExpr *r) {insertIntoTemp_ = r; } |
| |
| private: |
| // name of the Common Subexpression |
| NAString name_; |
| |
| // id of this CSE within the statement |
| Int32 cseId_; |
| |
| // list of other CSEs that are referenced by this one |
| LIST(CountedCSEInfo) childCSEs_; |
| |
| // list of nodes referring to the common |
| // subexpression, their index numbers match |
| // the index in this list |
| LIST(CommonSubExprRef *) consumers_; |
| |
| // We sometimes make copies of a tree, creating alternative |
| // consumers. Some notes on these alternative copies: The analyzing |
| // consumer (see CommonSubExprRef::analyzeAndPrepareForSharing()) |
| // and its ancestors are always in the consumers_ list and do not |
| // change. As we replace a tree with its copy, we may replace other |
| // consumers with their respective copies. The code must be able to |
| // deal with this situation, so be careful when making decisions |
| // based on a particular consumer obtained from this list. |
| LIST(CommonSubExprRef *) alternativeConsumers_; |
| |
| // number of lexical refs in the query for this expression |
| // (how many time does it appear in the query text) |
| Int32 numLexicalRefs_; |
| |
| // a common list of columns and predicate to use used for a |
| // materialized CSE |
| |
| // a list of the actual columns (in terms of the |
| NABitVector neededColumns_; |
| ValueIdSet commonPredicates_; |
| |
| // VEGies with conflicts between the different |
| // consumers |
| ValueIdSet vegRefsWithDifferingConstants_; |
| ValueIdSet vegRefsWithDifferingInputs_; |
| |
| // information for heuristics |
| |
| // "key" columns in the child tree, this could include Hive |
| // partition columns, "tag" constant columns in a union, and also |
| // trailing key columns that may not be significant |
| NABitVector cseTreeKeyColumns_; |
| |
| // information for the materialization of the CSE |
| Int32 idOfAnalyzingConsumer_; |
| CSEAnalysisOutcome analysisOutcome_; |
| CSETempTableType tempTableType_; |
| QualifiedName tempTableName_; |
| NAString tempTableDDL_; |
| const NATable *tempNATable_; |
| RelExpr *insertIntoTemp_; |
| }; |
| |
| // A CSEInfo and a count (of how many references we have to it) |
| class CountedCSEInfo |
| { |
| public: |
| |
| CountedCSEInfo() : info_(NULL), lexicalCount_(-1) {} |
| CountedCSEInfo(CSEInfo *info, Int32 cnt = 0) : |
| info_(info), lexicalCount_(cnt) {} |
| CountedCSEInfo(const CountedCSEInfo &other) : |
| info_(other.info_), lexicalCount_(other.lexicalCount_) {} |
| ~CountedCSEInfo() {} |
| |
| CSEInfo *getInfo() const { return info_; } |
| Int32 getLexicalCount() const { return lexicalCount_; } |
| |
| void incrementLexicalCount() { lexicalCount_++; } |
| |
| private: |
| |
| CSEInfo *info_; |
| Int32 lexicalCount_; |
| }; |
| |
| // ----------------------------------------------------------------------- |
| // The CommonSubExprRef class represents a potential common subexpression |
| // (CSE) in the query tree. The common subexpression has a name, and |
| // multiple CommonSubExprRef nodes in the tree may refer to the same |
| // name. This is a unary operator, the child tree defines the common |
| // subexpression (with a few caveats, see below). Note that in our |
| // current design, we keep multiple copies of the common subexpression |
| // around, in case we don't want to materialize the CSE. This is a |
| // logical operator, it either needs to be removed or it needs to be |
| // replaced with a scan of a temp table. |
| // ----------------------------------------------------------------------- |
| class CommonSubExprRef : public RelExpr |
| { |
| public: |
| |
| // constructor |
| CommonSubExprRef(RelExpr *cse = NULL, |
| const char *internalName = NULL, |
| NAMemory *oHeap = CmpCommon::statementHeap()) |
| : RelExpr(REL_COMMON_SUBEXPR_REF,cse,NULL,oHeap), |
| internalName_(internalName, oHeap), |
| id_(-1), |
| isAnExpansionOf_(NULL), |
| isAnAlternativeOf_(NULL), |
| parentCSEId_(-1), |
| parentRefId_(-1), |
| lexicalRefNumFromParent_(-1), |
| hbAccessOptionsFromCTE_(NULL) |
| {} |
| |
| virtual ~CommonSubExprRef(); |
| |
| // the name used in the CTE or a generated name |
| const NAString &getName() const { return internalName_; } |
| Int32 getId() const { return id_; } |
| Int32 getParentCSEId() const { return parentCSEId_; } |
| Int32 getParentConsumerId() const { return parentRefId_; } |
| Int32 getLexicalRefNumFromParent() const {return lexicalRefNumFromParent_; } |
| NABoolean isAChildOfTheMainQuery() const; |
| |
| virtual Int32 getArity() const; |
| |
| // return a read-only reference to the initial list of columns |
| const ValueIdList & getColumnList() const { return columnList_; } |
| const ValueIdSet & getNonVEGColumns() const { return nonVEGColumns_; } |
| |
| const ValueIdSet &getPushedPredicates() const { return pushedPredicates_; } |
| const EstLogPropSharedPtr &getEstLogProps() const{ return cseEstLogProps_; } |
| |
| void setId(Int32 id) { CMPASSERT(id_ == -1); id_ = id; } |
| |
| // remember HBase access options (if needed) |
| void setHbaseAccessOptions(HbaseAccessOptions *hbo) |
| { hbAccessOptionsFromCTE_ = hbo; } |
| |
| // add this node to the global list of CommonSubExprRefs kept in CmpStatement |
| void addToCmpStatement(NABoolean lexicalRef); |
| |
| // establish a parent/child relationship between two CommonSubExprRefs |
| void addParentRef(CommonSubExprRef *parentRef); |
| |
| // is this the first reference to the common subexpression? |
| NABoolean isFirstReference() const; |
| |
| // CommonSubExprRefs come in different flavors: |
| // |
| // Lexical ref: This is a node that got created in a parser |
| // rule, parsing a reference to a CTE (or, in the |
| // future, something equivalent, like a view reference). |
| // Expanded ref: Since the parser expands CTE references by making a |
| // copy on each reference, if that copied tree contains |
| // child references, an expanded ref is created. |
| // Lexical and expanded refs shouldn't be treated |
| // differently, it is somewhat arbitrary which one |
| // is the lexical one and which ones are expanded. |
| // Original ref: This is the original copy of a lexical or expanded |
| // ref. |
| // Alternative ref: Sometimes we copy a tree after binding, e.g. to |
| // have a fall-back during the SQO phase. Such copies |
| // are alternative refs, and only one of them should |
| // be used in the output of each compilation phase. |
| // Only one of the alternatives is part of the |
| // CSEInfo consumer list, the others are stored in |
| // the alternative consumer list. |
| // |
| // A given CommonSubExprRef is either a lexical or an expanded ref. |
| // The "alternative" flavor is orthogonal to that, both lexical |
| // and expanded refs can either be an original or an alternative. |
| NABoolean isALexicalRef() const { return isAnExpansionOf_ == NULL; } |
| NABoolean isAnExpandedRef() const { return isAnExpansionOf_ != NULL; } |
| NABoolean isAnOriginalRef() const { return isAnAlternativeOf_ == NULL; } |
| NABoolean isAnAlternativeRef() const { return isAnAlternativeOf_ != NULL; } |
| CommonSubExprRef *getLexicalRef() |
| { return isAnExpansionOf_ ? isAnExpansionOf_ : this; } |
| CommonSubExprRef *getOriginalRef() |
| { return isAnAlternativeOf_ ? isAnAlternativeOf_ : this; } |
| |
| // a virtual function for performing name binding within the query tree |
| virtual RelExpr * bindNode(BindWA *bindWAPtr); |
| |
| // normalizer methods |
| virtual void transformNode(NormWA & normWARef, |
| ExprGroupId & locationOfPointerToMe); |
| virtual void pullUpPreds(); |
| virtual void pushdownCoveredExpr( |
| const ValueIdSet & outputExprOnOperator, |
| const ValueIdSet & newExternalInputs, |
| ValueIdSet& predOnOperator, |
| const ValueIdSet * nonPredNonOutputExprOnOperator = NULL, |
| Lng32 childId = (-MAX_REL_ARITY)); |
| virtual void rewriteNode(NormWA & normWARef); |
| virtual RelExpr * semanticQueryOptimizeNode(NormWA & normWARef); |
| virtual NABoolean prepareMeForCSESharing( |
| const ValueIdSet &outputsToAdd, |
| const ValueIdSet &predicatesToRemove, |
| const ValueIdSet &commonPredicatesToAdd, |
| const ValueIdSet &inputsToRemove, |
| ValueIdSet &valuesForVEGRewrite, |
| ValueIdSet &keyColumns, |
| CSEInfo *info); |
| |
| // add all the expressions that are local to this |
| // node to an existing list of expressions (used by GUI tool) |
| virtual void addLocalExpr(LIST(ExprNode *) &xlist, |
| LIST(NAString) &llist) const; |
| |
| virtual HashValue topHash(); |
| virtual NABoolean duplicateMatch(const RelExpr & other) const; |
| virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // synthesize logical properties |
| virtual void synthLogProp(NormWA * normWAPtr = NULL); |
| virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp); |
| |
| // get a printable string that identifies the operator |
| virtual const NAString getText() const; |
| |
| void emitCSEDiagnostics(const char *message, |
| NABoolean forceError = FALSE); |
| |
| // for use by the root node for inlining |
| static Union *makeUnion(RelExpr *lc, RelExpr *rc, NABoolean blocked); |
| |
| static void makeValueIdListFromBitVector(ValueIdList &tgt, |
| const ValueIdList &src, |
| const NABitVector &vec); |
| |
| // for debugging |
| void display(); |
| static void displayAll(const char *optionalId = NULL); |
| |
| private: |
| |
| // private methods |
| // --------------- |
| |
| // Methods used in the transformation of a plan with CSEs into |
| // one that creates a temp table, populates it, then replaces the |
| // CommonSubExprRef nodes with scans of the temp table. These methods |
| // are meant to be used in the SQO phase and/or in optimizer rules. |
| |
| // - Find a list of columns that satisfies all the CSE consumers, |
| // - Find a set of pushed-down predicates common to all consumers |
| // - Based on the remaining predicates, determine a STORE BY or |
| // PRIMARY KEY of the temp table |
| // - Get an estimate for rows and bytes accessed for each of |
| // the scan nodes |
| // - Heuristically decide whether to share the data in a temp table |
| CSEInfo::CSEAnalysisOutcome analyzeAndPrepareForSharing(CSEInfo &info); |
| |
| // decide which type of temp table to use, store the result in info |
| void determineTempTableType(CSEInfo &info); |
| |
| // Based on the information obtained in analyzeSharing(), create |
| // a volatile table to hold the result of the common subexpression. |
| // Note that this table is created at compile time. If the user |
| // compiled this statement in a user-defined transaction, the |
| // temp table will be created in that transaction. If the user was |
| // not in a transaction when this statement was compiled, we |
| // will use a separate transaction that will be committed before |
| // returning back to the user. |
| NABoolean createTempTable(CSEInfo &info); |
| |
| RelExpr * createInsertIntoTemp(CSEInfo &info, NormWA & normWARef); |
| |
| // Create a scan on the temp table, which can replace this |
| // CommonSubExprRef node when we choose to materialize the common |
| // subexpression |
| RelExpr * createTempScan(CSEInfo &info, NormWA & normWARef); |
| RelExpr * getTempScan() const { return tempScan_; } |
| |
| // data members |
| // ------------ |
| |
| // The name of the CTE (Common Table Expression) in internal |
| // format, if the operator was generated from a reference to |
| // a CTE. Otherwise, this could be some made-up name. |
| NAString internalName_; |
| |
| // One or more CommonSubExprRef operators may refer to the same |
| // common subexprssion. These references are numbered 0, 1, ... |
| Int32 id_; |
| |
| // indicate different flavors of CommonSubExprRef nodes and point |
| // back to the original node(s), if any |
| CommonSubExprRef *isAnExpansionOf_; |
| CommonSubExprRef *isAnAlternativeOf_; |
| |
| // There are three ids that describe our predecessor in the |
| // RelExpr tree and in the lexical directed multigraph of the |
| // CSEs: |
| // Parent CSE id: |
| // This is the the parent CSE or main query that directly |
| // contains the reference. In the RelExpr tree, this is our |
| // closest ancestor CommonSubExprRef node or the root node |
| // of the tree. It is stored as the integer CSE id here, |
| // we could also store the name. A special id is used for |
| // the main query: CmpStatement::getCSEIdForMainQuery(). |
| // |
| // Parent Ref id: |
| // This is the consumer id of the parent CommonSubExprRef |
| // (or 0 if the ref originates from the main query). |
| // |
| // Lexical ref num from parent: |
| // This indicates which reference from the parent CSE we |
| // are looking at. The main query or a CSE may refer to |
| // the same child multiple times, and this is the number |
| // indicating this (0...n-1). The id_ data member counts |
| // the total number of references to a CSE; the lexical |
| // ref num from parent counts only the lexical number |
| // of references and only from a particular parent CSE |
| // (or the main query). |
| // |
| Int32 parentCSEId_; |
| Int32 parentRefId_; |
| Int32 lexicalRefNumFromParent_; |
| |
| // The list of columns produced by the common subexpression. |
| // We keep the full list here, even when the characteristic |
| // outputs get reduced during the normalization phase. This |
| // is a list, since different consumers of the CSE will use |
| // different value ids, so the only way to equate columns |
| // of different consumers is by position in this list. |
| ValueIdList columnList_; |
| |
| // Same columns without making VEGRefs. This is needed |
| // in preCodeGen. It also includes other potential VEG |
| // members if this is the analyzing consumer. |
| ValueIdSet nonVEGColumns_; |
| |
| // The common inputs (typically parameters). Pushing down |
| // new predicates may create additional characteristic |
| // inputs for this RelExpr, those are not reflected here. |
| // These common inputs should have the same value ids for |
| // all consumers. |
| ValueIdSet commonInputs_; |
| |
| // Predicates that got pulled up during normalization. |
| // Usually those should get pushed down again. |
| // ValueIdSet pulledPredicates_; |
| |
| // Predicates that got pushed into the child tree. These |
| // modify our copy of the common subexpression. If we want |
| // to use a temp table, we may need to pull out those predicates |
| // that are not common between all the users of the CSE |
| ValueIdSet pushedPredicates_; |
| |
| // Predicates that are not common predicates, pushed into the |
| // common temp table. These need to be applied to the temp |
| // table, if we decide to read from a temp table. |
| ValueIdSet nonSharedPredicates_; |
| |
| // We allow hints and access options on references to CTEs. |
| // Those are ignored when we expand the CTE, but they can |
| // be applied to the scan of the temp node, if we decide to |
| // create a temp table for the resulting CSE. |
| HbaseAccessOptions *hbAccessOptionsFromCTE_; |
| |
| // the estimated logical properties of this common subexpression, |
| // set in the analyzing consumer only, since they should be the same |
| // for all consumers |
| EstLogPropSharedPtr cseEstLogProps_; |
| |
| // the temp scan to replace this node after the SQO phase |
| RelExpr *tempScan_; |
| |
| }; // class CommonSubExprRef |
| |
| |
| #endif /* RELMISC_H */ |