/***********************************************************************
// @@@ 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_; }

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_;

}; // 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 */
