blob: fc3e486eb45e9afb45abfb8690b08a836bd1f2d3 [file] [log] [blame]
/**********************************************************************
// @@@ 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 RELGRBY_H
#define RELGRBY_H
/* -*-C++-*-
******************************************************************************
*
* File: RelGrby.h
* Description: Relational aggregates and group by
* (both physical and logical operators)
* Created: 4/28/94
* Language: C++
*
*
*
*
******************************************************************************
*/
// -----------------------------------------------------------------------
#include "ObjectNames.h"
#include "RelExpr.h"
// -----------------------------------------------------------------------
// contents of this file
// -----------------------------------------------------------------------
class GroupByAgg;
class SortGroupBy;
class ShortCutGroupBy;
class PhysShortCutGroupBy;
class HashGroupBy;
// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class BindWA;
class NormWA;
class Generator;
class PartitioningFunction;
class RequirementGenerator;
class ex_expr;
class ExpTupleDesc;
class ComTdb;
////////////////////
class QueryAnalysis;
class GBAnalysis;
class CANodeIdSet;
class JBBSubsetAnalysis;
////////////////////
// -----------------------------------------------------------------------
// The GroubByAgg operator has three additional expressions. The first
// one, called grouping expression, is used to split its child rows into
// groups. Each group of child rows has the same value for the grouping
// expression.
// The second expression, the aggregate expression, can reference the
// result of the grouping expression and it can reference the columns of
// the child table by means of aggregate functions.
// The third expression, if present, specifies a single result row
// that is produced when the GROUPBY operator has no child rows. This
// can be used to implement ANSI style aggregates that have a special
// return value (NULL or 0) for an empty set. This is called the empty
// child result expression. If the expression is not present, then
// no result is produced if the child of the operator is empty.
//
// If the operator type is REL_GROUPBY then the third expression must
// not be present.
// -----------------------------------------------------------------------
class GroupByAgg : public RelExpr
{
public:
// constructor
GroupByAgg(RelExpr *child,
OperatorTypeEnum otype = REL_GROUPBY,
ItemExpr *groupExpr = NULL,
ItemExpr *aggregateExpr = NULL,
CollHeap *oHeap = CmpCommon::statementHeap())
: RelExpr(otype, child, NULL, oHeap),
groupExprTree_(groupExpr),
aggregateExprTree_(aggregateExpr),
gbAggPushedBelowTSJ_(FALSE),
formEnum_(FULL_GROUPBY),
gbAnalysis_(NULL),
selIndexInHaving_(FALSE),
requiresMoveUp_(FALSE),
containsNullRejectingPredicates_(FALSE),
parentRootSelectList_(NULL),
isMarkedForElimination_(FALSE),
aggDistElimRuleCreates_(FALSE),
groupByOnJoinRuleCreates_(FALSE),
extraGrpOrderby_(NULL),
isRollup_(FALSE)
{}
// constructor
GroupByAgg(RelExpr *child, const ValueIdSet & aggregateExpr)
: RelExpr(REL_GROUPBY, child),
groupExprTree_(NULL), aggregateExprTree_(NULL),
aggregateExpr_(aggregateExpr),
gbAggPushedBelowTSJ_(FALSE),
formEnum_(FULL_GROUPBY),
gbAnalysis_(NULL),
selIndexInHaving_(FALSE),
requiresMoveUp_(FALSE),
containsNullRejectingPredicates_(FALSE),
parentRootSelectList_(NULL),
isMarkedForElimination_(FALSE),
aggDistElimRuleCreates_(FALSE),
groupByOnJoinRuleCreates_(FALSE),
extraGrpOrderby_(NULL),
isRollup_(FALSE)
{}
// virtual destructor
virtual ~GroupByAgg();
// get the degree of this node (it is a unary op).
virtual Int32 getArity() const;
// get and set the grouping and aggregate expressions as parse trees
ItemExpr * getGroupExprTree() const { return groupExprTree_; }
void addGroupExprTree(ItemExpr *groupExpr);
ItemExpr * removeGroupExprTree();
void addAggregateExprTree(ItemExpr *aggrExpr);
ItemExpr * removeAggregateExprTree();
// return a (short-lived) read/write reference to the item expressions
inline ValueIdSet & groupExpr() { return groupExpr_; }
inline const ValueIdSet & groupExpr() const { return groupExpr_; }
inline void setGroupExpr(ValueIdSet &expr) { groupExpr_ = expr;}
inline void addGroupExpr(ValueIdSet &expr) { groupExpr_ += expr;}
inline void setExtraOrderExpr(const ValueIdList &newExtraOrder) { extraOrderExpr_ = newExtraOrder; }
inline const ValueIdList & extraOrderExpr() const { return extraOrderExpr_; }
void normalizeExtraOrderExpr( NormWA & normWARef ) { extraOrderExpr_.normalizeNode(normWARef); }
ValueIdList & rollupGroupExprList() { return rollupGroupExprList_; }
const ValueIdList & rollupGroupExprList() const { return rollupGroupExprList_; }
void setRollupGroupExprList(ValueIdList &expr) { rollupGroupExprList_ = expr;}
// return a (short-lived) read/write reference to the item expressions
inline ValueIdSet & leftUniqueExpr() { return leftUniqueExpr_; }
inline const ValueIdSet & leftUniqueExpr() const { return leftUniqueExpr_; }
inline void setLeftUniqueExpr(ValueIdSet &expr) { leftUniqueExpr_ = expr;}
inline ValueIdSet & aggregateExpr() { return aggregateExpr_; }
inline const ValueIdSet & aggregateExpr() const { return aggregateExpr_; }
inline void setAggregateExpr(ValueIdSet &expr) { aggregateExpr_ = expr;}
// Mutator method to change the gb pushed below TSJ flag
inline NABoolean & gbAggPushedBelowTSJ()
{ return gbAggPushedBelowTSJ_; }
// Accessor method to access the gb pushed below TSJ flag
inline NABoolean gbAggPushedBelowTSJ() const
{ return gbAggPushedBelowTSJ_; }
// Get the values that are needed for evaluating the aggregate.
void getValuesRequiredForEvaluatingAggregate(ValueIdSet& relevantValues);
// a virtual function for performing name binding within the query tree
virtual RelExpr * bindNode(BindWA *bindWAPtr);
// MV --
NABoolean virtual isIncrementalMV() { return TRUE; }
void virtual collectMVInformation(MVInfoForDDL *mvInfo,
NABoolean isNormalized);
// 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);
virtual RelExpr * semanticQueryOptimizeNode(NormWA & normWARef);
virtual void checkForCascadedGroupBy(NormWA &normWaRef);
virtual void eliminateCascadedGroupBy(NormWA &normWaRef);
virtual NABoolean prepareMeForCSESharing(
const ValueIdSet &outputsToAdd,
const ValueIdSet &predicatesToRemove,
const ValueIdSet &commonPredicatesToAdd,
const ValueIdSet &inputsToRemove,
ValueIdSet &valuesForVEGRewrite,
ValueIdSet &keyColumns,
CSEInfo *info);
// flows compRefOpt constraints up the query tree.
virtual void processCompRefOptConstraints(NormWA * normWAPtr) ;
// Method to push down predicates from a groupby 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;
// 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);
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);
// Helper method for the above synthEstLogProp() method
void handleIndirectDepInGroupingcols(ValueIdSet & workGroup,
ValueIdSet & interestingColSet,
ValueIdSet & updatedColumnsToRemove,
ValueIdSet & probableRedundantColSet,
const ColStatDescList & groupStatDescList);
// ---------------------------------------------------------------------
// The following method examines the aggregate functions that are
// members of the aggrExpr(). If any aggregate function cannot be
// computed using a two-step process, a partial aggregation followed
// by finalization, it returns FALSE. A typical aggregate that
// cannot be computed using such a two-step process is the one row
// aggregate that is introduced by the transformation of a scalar/row
// subquery to a Join-Aggregate form.
// ---------------------------------------------------------------------
NABoolean aggregateEvaluationCanBeStaged() const;
// ---------------------------------------------------------------------
//
// The optimizer views a GroupByAgg to be in one of four forms:
//
// 1) A "full" groupby, i.e., it is not a partial groupby.
//
// The parser creates a group by of this form. A groupby of this
// form is seen by all the phases of processing from name binding
// through code generation.
//
// The method isNotAPartialGroupBy() returns TRUE for a "full"
// groupby and false for all other forms.
//
// 2) Partial groupby operators.
//
// Partial groupby operators can appear in the solution for a
// group by because they are created by the application of the
// transformation rule, the GroupBySplitRule. The GroupBySplitRule
// fires once for a "full" groupby and can fire once more for a
// partial groupby that is a leaf. The rule replaces
// GB(X) with GB(GB(X))
// Partial groupby operators are only seen by the optimizer, the
// pre code generator and the code generator.
//
// When the GroupBySplitRule fires on a "full" groupby it produces
// the following pairs of groupbys
//
// a) Root of the partial groupby subtree
//
// The root of the partial groupby consolidates the partial groups
// that are formed by one or more groupbys that independently
// compute partial groups.
//
// The method isAPartialGroupByRoot() returns TRUE only for such
// a partial groupby.
//
// b) 1st Leaf of the partial groupby subtree.
//
// The 1st leaf of the partial groupby subtree is a simply the
// the lowermost partial groupby created when the GroupBySplitRule
// fires on a "full" groupby. The term "leaf" is convenient for
// naming the partial groupby operators that are contained in the
// substitute. The reader should realize that, in reality, the
// GroupByAgg is a unary operator; the partial groupby will always
// posses a child, regardless of whether it is called a "leaf"!
//
// The method isAPartialGroupByLeaf1() returns TRUE only for such
// a partial groupby.
//
// The GroupBySplitRule can fire on the 1st leaf to produce another
// pair of parital groupby operators called the non-leaf partial
// groupby together with the 2nd leaf.
//
// c) Non-leaf partial groupby
//
// A plan can contain three partial groupbys that span two
// levels of the tree, the root, a non-leaf and a leaf.
// The non-leaf partially consolidates partial groups
// that are formed by the 2nd leaf of the partial groupby
// subtree. It adds one more operator to the pipeline but
// increases the degree of parallelism for the leaves.
//
// The method isAPartialGroupByNonLeaf() returns TRUE only for such
// a partial groupby.
//
// d) 2nd Leaf of the partial groupby subtree.
//
// The 2nd leaf of the partial groupby subtree is a simply the
// the lowermost partial groupby created when the GroupBySplitRule
// fires on a partial groupby that is a 1st leaf.
//
// The method isAPartialGroupByLeaf2() returns TRUE only for such
// a partial groupby.
//
// The distinction between the 1st leaf and the 2nd leaf is made purely to
// aid costing in the optimizer. The code generator processes both
// the forms of the leafs in an identical manner. The method
// isAPartialGroupByLeaf() is defined to permit the code generator
// to identify a leaf, independent of its form.
//
// A GroupByAgg operator in any one of the above forms uses the same
// implementation for grouping the data at run time. This means,
// regardless of its form, a GroupByAgg will either use the hash
// grouping or sorted grouping implementation at run time.
//
// ---------------------------------------------------------------------
NABoolean isNotAPartialGroupBy() const
{ return (formEnum_ == FULL_GROUPBY); }
NABoolean isAPartialGroupByRoot() const
{ return (formEnum_ == PARTIAL_GROUPBY_ROOT); }
NABoolean isAPartialGroupByNonLeaf() const
{ return (formEnum_ == PARTIAL_GROUPBY_NON_LEAF); }
NABoolean isAPartialGroupByLeaf() const
{ return (isAPartialGroupByLeaf1() OR isAPartialGroupByLeaf2()); }
NABoolean isAPartialGroupByLeaf1() const
{ return (formEnum_ == PARTIAL_GROUPBY_LEAF1); }
NABoolean isAPartialGroupByLeaf2() const
{ return (formEnum_ == PARTIAL_GROUPBY_LEAF2); }
void markAsPartialGroupByRoot() { formEnum_ = PARTIAL_GROUPBY_ROOT; }
void markAsPartialGroupByNonLeaf()
{ formEnum_ = PARTIAL_GROUPBY_NON_LEAF; }
void markAsPartialGroupByLeaf1() { formEnum_ = PARTIAL_GROUPBY_LEAF1; }
void markAsPartialGroupByLeaf2()
{ formEnum_ = PARTIAL_GROUPBY_LEAF2; }
// ---------------------------------------------------------------------
// The following method is used for marking a copy of this GroupByAgg
// as being in the same form as the original.
// ---------------------------------------------------------------------
void assignForm(const GroupByAgg& other)
{ formEnum_ = other.formEnum_; }
// ---------------------------------------------------------------------
// Common implementation for testing the eligibility of this
// GroupByAgg to form a plan using the given required physical
// properties.
// This method is called by various implementations of the
// method ...GroupByRule::topMatch().
// ---------------------------------------------------------------------
NABoolean rppAreCompatibleWithOperator
(const ReqdPhysicalProperty* const rppForGrby) const;
virtual Context* createContextForAChild(Context* myContext,
PlanWorkSpace* pws,
Lng32& childIndex);
virtual void addArrangementAndOrderRequirements(RequirementGenerator &rg);
virtual RelExpr * preCodeGen(Generator *generator,
const ValueIdSet &externalInputs,
ValueIdSet &pulledNewInputs);
NABoolean executeInDP2() const;
// generates aggregate and groupby expressions. Called by
// SortGroupBy::codeGen.
// Defined in file GenRelGrby.C
short genAggrGrbyExpr(Generator * generator,
ValueIdSet &aggregateExpr,
ValueIdSet &groupExpr,
ValueIdList &rollupGroupExprList,
ValueIdSet &selectionPred,
Int32 workAtp, Int32 workAtpIndex,
short returnedAtpIndex,
ex_expr ** aggr_expr, ex_expr ** grby_expr,
ex_expr ** move_expr, ex_expr ** having_expr,
ComTdb ** child_tdb, ExpTupleDesc ** tuple_desc);
// get a printable string that identifies the operator
virtual const NAString getText() const;
// adds information about this node to the Explain tree
ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
ComTdb * tdb,
Generator *generator);
// method to do code generation
virtual short codeGen(Generator*);
// append an ascii-version of GroupByAgg into cachewa.qryText_
virtual void generateCacheKey(CacheWA& cwa) const;
// is this entire expression cacheable after this phase?
virtual NABoolean isCacheableExpr(CacheWA& cwa);
NABoolean selIndexInHaving() { return selIndexInHaving_; }
void setSelIndexInHaving(NABoolean v) { selIndexInHaving_ = v; }
//////////////////////////////////////////////////////
virtual NABoolean pilotAnalysis(QueryAnalysis* qa);
virtual void jbbAnalysis(QueryAnalysis* qa);
JBBSubsetAnalysis* getJBBSubsetAnalysis();
virtual void primeGroupAnalysis();
virtual RelExpr * generateLogicalExpr(CANodeIdSet &, CANodeIdSet &);
virtual RelExpr * generateMatchingExpr(CANodeIdSet &, CANodeIdSet &,
RelExpr *);
inline GBAnalysis* getGBAnalysis()
{
return gbAnalysis_;
}
inline void setGBAnalysis(GBAnalysis* gbAnalysis)
{
gbAnalysis_ = gbAnalysis;
}
inline NABoolean requiresMoveUp() { return requiresMoveUp_ ;}
inline void setRequiresMoveUp(NABoolean val)
{ requiresMoveUp_ = val ;}
inline NABoolean containsNullRejectingPredicates()
{ return containsNullRejectingPredicates_ ;}
inline void setContainsNullRejectingPredicates(NABoolean val)
{ containsNullRejectingPredicates_ = val ;}
ItemExpr * getParentRootSelectList() const { return parentRootSelectList_; }
void setParentRootSelectList(ItemExpr *selectList)
{parentRootSelectList_ = selectList;};
void removeParentRootSelectList()
{parentRootSelectList_ = NULL;};
inline NABoolean aggDistElimRuleCreates()
{ return aggDistElimRuleCreates_ ;}
inline void setAggDistElimRuleCreates(NABoolean val)
{ aggDistElimRuleCreates_ = val ;}
inline NABoolean groupByOnJoinRuleCreates()
{ return groupByOnJoinRuleCreates_; }
inline void setGroupByOnJoinRuleCreates (NABoolean val)
{ groupByOnJoinRuleCreates_ = val ;}
// SQO methods
// used to refine the group expresiion of a GroupBy
// as the node is moved/pulled up during subquery unnesting.
void computeGroupExpr(const ValueIdSet& seed,
ValueIdSet& superSet,
NormWA& normWARef);
// performs post processing for subquery unnesting after
// the two main transformations (pullUp and moveUp GroupBy)
// have been applied. Returns FALSE if an error is encountered.
NABoolean subqueryUnnestFinalize(ValueIdSet& newGrbyGroupExpr,
NormWA& normWARef);
// a method that creates a MapValueId node that can be used
// to map between regular column references through instantiateNull
// references back to column references again. This is used by the
// unnesting code when a join is transformed from a Join to a LeftJoin.
// Since we are past the binder state, and LeftJoins can only produce
// instantiateNull outputs, we need to map between those outputs and the
// regular base column outputs the nodes above the GroupBy expects the
// child to produce as outputs...
MapValueIds * buildMapValueIdNode(ValueIdMap *map);
// used by subquery unnesting as an additional step to the pullUpGroupBy
// transformation, if left joins are needed.
RelExpr* nullPreservingTransformation(GroupByAgg* oldGB,
NormWA& normWARef);
// used by subquery unnesting as an additional step to the pullUpGroupBy
// moveUpGroupBy transformation, to rewrite the groupby's expression
// in case we need to put it on top of a Left Join.
RelExpr* nullPreserveMyExprs( NormWA& normWARef);
NABoolean isMarkedForElimination()
{ return isMarkedForElimination_; }
void setIsMarkedForElimination(NABoolean val)
{ isMarkedForElimination_ = TRUE; }
inline ValueIdSet & aggrExprsToBeDeleted() { return aggrExprsToBeDeleted_; }
NABoolean tryToPullUpPredicatesInPreCodeGen(
const ValueIdSet &valuesAvailableInParent, // pull preds that are covered by these
ValueIdSet &pulledPredicates, // return the pulled-up preds
ValueIdMap *optionalMap); // optional map to rewrite preds
void setIsRollup(NABoolean v) { isRollup_ = v; }
NABoolean isRollup() { return isRollup_; }
const NABoolean isRollup() const { return isRollup_; }
ItemExpr * getExtraGrpOrderby() { return extraGrpOrderby_; }
void setExtraGrpOrderby(ItemExpr *ie) { extraGrpOrderby_ = ie; }
//////////////////////////////////////////////////////
private:
// ---------------------------------------------------------------------
// An enumerated type that indicates the form for this GroupByAgg.
// ---------------------------------------------------------------------
enum GroupByAggFormEnum { FULL_GROUPBY,
PARTIAL_GROUPBY_ROOT,
PARTIAL_GROUPBY_NON_LEAF,
PARTIAL_GROUPBY_LEAF1,
PARTIAL_GROUPBY_LEAF2
};
// ---------------------------------------------------------------------
// Its form (see description above.)
// ---------------------------------------------------------------------
GroupByAggFormEnum formEnum_;
// ---------------------------------------------------------------------
// The expression specifying the group by columns/expressions
// ---------------------------------------------------------------------
ItemExpr * groupExprTree_;
ValueIdSet groupExpr_;
ItemExpr * extraGrpOrderby_;
ValueIdList extraOrderExpr_;
// --------------------------------------
// used for processing groupby rollup
// --------------------------------------
ValueIdList rollupGroupExprList_;
// ---------------------------------------------------------------------
// The expression specifying the aggregates to be generated
// ---------------------------------------------------------------------
ItemExpr * aggregateExprTree_;
ValueIdSet aggregateExpr_;
// ---------------------------------------------------------------------
// Indicates if this partial GB node has been pushed below a TSJ
// ---------------------------------------------------------------------
NABoolean gbAggPushedBelowTSJ_;
// ---------------------------------------------------------------------
// GBAnalysis defines the relation between this GroupBy and its JBB
// ---------------------------------------------------------------------
GBAnalysis * gbAnalysis_;
// indicates if there are any select list indices or renamed cols
// used in the having clause.
NABoolean selIndexInHaving_;
// ---------------------------------------------------------------------
// Flag used by subquery unnesting to determine if a GroupBy needs to move
// up more than 1 level above a parent tsj.
// ---------------------------------------------------------------------
NABoolean requiresMoveUp_ ;
// ---------------------------------------------------------------------
// Flag used to determine is this Group By needs a seperate VEGRegion,
// if the groupExpr is empty (i.e. this is a scalar aggregate). Scalar
// aggregates that contain a null rejecting predicates do not need a
// seperate VEGRegion. This is similar to logic used to determine if a
//left join can be converted to an inner join.
// ---------------------------------------------------------------------
NABoolean containsNullRejectingPredicates_ ;
// ---------------------------------------------------------------------
// Used by subquery unnesting only. During the SQO phase this member is
// set to a list of values that gurantee uniqueness from the left side
// of the join/tsj that is being unnested. Later this value will be used
// during the MoveUpGroupBy transformation (part of SQO subpahse) as the
// groupExpr is adjusted to reflect the new position of this node in the
// query tree. The groupExpr_ must always contains the columns listed in
// this member.
// ---------------------------------------------------------------------
ValueIdSet leftUniqueExpr_ ;
// ---------------------------------------------------------------------
// Used by "MVQR GroupBy Rewrite Rule" only. During GroupByAgg MVQR rewrite,
// this flag will be used to not to fire MVQR GroupBy Rewrite Rule.
// MV candidates are saved in gbAnalysis of GroupBy RelExpr and it will
// be referenced by all applicables Rules in that CascadeGroup.
// Two such rules are AggrDistinctEliminationRule and GroupByOnJoinRule,
// which creates a new GroupByAgg expresion and puts that in a new CascadeGroup.
// When optimizer tries to optimize the new group, GroupByMVQRRule is also
// fired since this new expression references MVCandidates from the original
// groupBy expression of previous CascadeGroup, but this should be avoided.
// When this flag is set TRUE, "MVQR GroupBy Rewrite Rule" will not be
// fired.
// ---------------------------------------------------------------------
NABoolean aggDistElimRuleCreates_ ;
NABoolean groupByOnJoinRuleCreates_;
// ---------------------------------------------------------------------
// Used by the Group By Ordinal feature, when renamed columns are
// present in groupby or having clauses. A ptr to the the select list of
// the parent root is saved here so that the select index can be
// interpreted locally in the groupby without accessing the parent root.
// After use in GroupByAgg::bindNode, this datamember is set to NULL.
// ---------------------------------------------------------------------
ItemExpr * parentRootSelectList_;
NABoolean isMarkedForElimination_;
ValueIdSet aggrExprsToBeDeleted_;
NABoolean isRollup_;
};
class SortGroupBy : public GroupByAgg
{
public:
// constructor
SortGroupBy(RelExpr *child,
OperatorTypeEnum otype = REL_ORDERED_GROUPBY,
ItemExpr *groupExpr = NULL,
ItemExpr *aggregateExpr = NULL,
CollHeap *oHeap = CmpCommon::statementHeap())
: GroupByAgg(child,otype,groupExpr,aggregateExpr, oHeap) {}
virtual ~SortGroupBy();
virtual NABoolean isLogical () const;
virtual NABoolean isPhysical() const;
// get a printable string that identifies the operator
virtual const NAString getText() const;
virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
CollHeap* outHeap = 0);
// context generation
virtual void addArrangementAndOrderRequirements(RequirementGenerator &rg);
// cost and physical property functions
virtual CostMethod* costMethod() const;
virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
const Lng32 planNumber,
PlanWorkSpace *pws);
virtual PlanPriority computeOperatorPriority
(const Context* context,
PlanWorkSpace *pws=NULL,
Lng32 planNumber=0);
}; // class SortGroupBy
// Logical Short Cut Group By
class ShortCutGroupBy : public GroupByAgg
{
public:
// constructor
ShortCutGroupBy(RelExpr *child,
OperatorTypeEnum otype = REL_SHORTCUT_GROUPBY,
ItemExpr *groupExpr = NULL,
ItemExpr *aggregateExpr = NULL,
CollHeap *oHeap = CmpCommon::statementHeap())
: GroupByAgg(child,otype,groupExpr,aggregateExpr, oHeap) {}
virtual ~ShortCutGroupBy() {};
virtual NABoolean isLogical () const { return TRUE; };
virtual NABoolean isPhysical() const { return FALSE; };
// get a printable string that identifies the operator
virtual const NAString getText() const;
virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
CollHeap* outHeap = 0);
// can we apply MDAM-like access for the anytrue expression?
inline NABoolean canApplyMdam() { return FALSE; }
// accessor functions
inline void setOptForMax (NABoolean value) { opt_for_max_ = value; }
inline void setOptForMin (NABoolean value) { opt_for_min_ = value; }
inline void setIsNullable (NABoolean value) { isnullable_ = value; }
inline void set_lhs (ItemExpr * ptr) { lhs_anytrue_ = ptr; }
inline void set_rhs (ItemExpr * ptr) { rhs_anytrue_ = ptr; }
inline NABoolean isOptForMax() { return opt_for_max_;}
inline NABoolean isOptForMin() { return opt_for_min_;}
inline NABoolean isNullable() { return isnullable_;}
virtual PlanPriority computeOperatorPriority
(const Context* context,
PlanWorkSpace *pws=NULL,
Lng32 planNumber=0);
protected:
NABoolean opt_for_max_; // anytrue lhs <, <= rhs
NABoolean opt_for_min_; // anytrue lhs >, >= rhs
NABoolean isnullable_; // true if anytrue expression contains nullable
// columns
ItemExpr * lhs_anytrue_; // -> lhs
ItemExpr * rhs_anytrue_; // -> rhs
}; // class ShortCutGroupBy
// Physical Short Cut Group By
class PhysShortCutGroupBy : public ShortCutGroupBy
{
public:
// constructor
PhysShortCutGroupBy(RelExpr *child,
OperatorTypeEnum otype = REL_SHORTCUT_GROUPBY,
ItemExpr *groupExpr = NULL,
ItemExpr *aggregateExpr = NULL,
CollHeap *oHeap = CmpCommon::statementHeap())
: ShortCutGroupBy(child,otype,groupExpr,aggregateExpr, oHeap) {}
virtual ~PhysShortCutGroupBy() {};
virtual NABoolean isLogical () const { return FALSE; };
virtual NABoolean isPhysical() const { return TRUE; };
virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
CollHeap* outHeap = 0);
// context generation
virtual void addArrangementAndOrderRequirements(RequirementGenerator &rg);
// cost and physical property functions
virtual CostMethod* costMethod() const;
virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
const Lng32 planNumber,
PlanWorkSpace *pws);
}; // class PhysShortCutGroupBy
class HashGroupBy : public GroupByAgg
{
public:
// constructor
HashGroupBy(RelExpr *child,
OperatorTypeEnum otype = REL_HASHED_GROUPBY,
ItemExpr *groupExpr = NULL,
ItemExpr *aggregateExpr = NULL,
CollHeap *oHeap = CmpCommon::statementHeap())
: GroupByAgg(child,otype,groupExpr,aggregateExpr,oHeap) {}
virtual ~HashGroupBy();
virtual NABoolean isLogical () const;
virtual NABoolean isPhysical() const;
// get a printable string that identifies the operator
virtual const NAString getText() const;
virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
CollHeap* outHeap = 0);
// cost and physical property functions
virtual CostMethod* costMethod() const;
virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
const Lng32 planNumber,
PlanWorkSpace *pws);
virtual RelExpr * preCodeGen(Generator *generator,
const ValueIdSet &externalInputs,
ValueIdSet &pulledNewInputs);
// method to do code generation
virtual short codeGen(Generator*);
// The method gets refined since HGB may be a BMO depending on its inputs.
virtual NABoolean isBigMemoryOperator(const PlanWorkSpace* pws,
const Lng32 planNumber);
virtual CostScalar getEstimatedRunTimeMemoryUsage(Generator *generator, NABoolean perNode, Lng32 *numStreams = NULL);
virtual PlanPriority computeOperatorPriority
(const Context* context,
PlanWorkSpace *pws=NULL,
Lng32 planNumber=0);
ExpTupleDesc::TupleDataFormat determineInternalFormat( const ValueIdList & valIdList,
RelExpr * relExpr,
NABoolean & resizeCifRecord,
Generator * generator,
NABoolean bmo_affinity,
NABoolean & considerBufferDefrag);
}; // class HashGroupBy
#endif /* RELGRBY_H */