/**********************************************************************
// @@@ 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 RELUPDATE_H
#define RELUPDATE_H
/* -*-C++-*-
******************************************************************************
*
* File:         RelUpdate.h
* Description:  Relational insert, update, delete, and their generic
*               superclass (both physical and logical operators)
* Created:      4/28/94
* Language:     C++
*
*
*
*
******************************************************************************
*/


#include "ComTransInfo.h"
#include "OptUtilIncludes.h"
#include "ObjectNames.h"
#include "RelExpr.h"
#include "SearchKey.h"
#include "RelJoin.h"
#include "RelScan.h"

// -----------------------------------------------------------------------
// contents of this file
// -----------------------------------------------------------------------

// The following are logical operators
class GenericUpdate;
class Insert;
class LeafInsert;
class Update;
class MergeUpdate;
class Delete;
class MergeDelete;
class LeafDelete;
class HbaseDelete;
class HiveInsert;
class HbaseInsert;
class HBaseBulkLoadPrep;


// The following are physical operators
class InsertCursor;
class UpdateCursor;
class HbaseUpdate;
class DeleteCursor;

// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class BindWA;
class ColReference;
class LogicalProperty;
class ModifiedFieldMap;
class NormWA;
class TableDesc;
class TriggerList;
class UpdateColumns;
class TriggersTempTable;
class BeforeAndAfterTriggers;
class MVInfoForDML;

// -----------------------------------------------------------------------
// generic update operation (insert, update, or delete)
// -----------------------------------------------------------------------

class GenericUpdate : public RelExpr
{
public:

  enum RowsAffected { DEFAULT_ROWSAFFECTED,             // indeterminate/off
                      COMPUTE_ROWSAFFECTED,             // definitely compute
                      DO_NOT_COMPUTE_ROWSAFFECTED };    // ruled out/off

  enum NoLogType { NORMAL_LOGGING = FALSE,
		   CONSISTENT_NOLOG,
		   INCONSISTENT_NOLOG };

 
GenericUpdate(const CorrName &name, 
                TableDesc *tabId,
                OperatorTypeEnum otype,
                RelExpr *child,
		ItemExpr *newRecExpr,
		ItemExpr *currOfCursorName,
		CollHeap *oHeap)

  : RelExpr(otype,child,NULL,oHeap),
    updatedTableName_(name, oHeap),
    tabId_(tabId),
    executorPredTree_(NULL),
    newRecExprTree_(newRecExpr),
    scanIndexDesc_(NULL),
    indexDesc_(NULL),
    indexNumberArray_(oHeap),
    indexNewRecExprArrays_(oHeap),
    indexBeginKeyPredArray_(oHeap),
    indexEndKeyPredArray_(oHeap),
    pathKeys_(NULL),
    partKeys_(NULL),
    currOfCursorName_(currOfCursorName),
    rowsAffected_(DEFAULT_ROWSAFFECTED),
    stoi_(NULL),
    isNoLogOperation_(NORMAL_LOGGING),
    noFlow_(FALSE),
    avoidHalloweenR2_(0),
    avoidHalloween_(FALSE),
    halloweenCannotUseDP2Locks_(FALSE),
    mtsStatement_(FALSE),
    noRollback_(FALSE),
    isMergeUpdate_(FALSE),
    isMergeDelete_(FALSE),
    subqInUpdateAssign_(NULL),
    updateCKorUniqueIndexKey_(FALSE),
    isIgnoreTriggers_(FALSE),
    hbaseOper_(FALSE),
    uniqueHbaseOper_(FALSE),
    cursorHbaseOper_(FALSE),
    uniqueRowsetHbaseOper_(FALSE),
    canDoCheckAndUpdel_(FALSE),
    noDTMxn_(FALSE),
    useRegionXn_(FALSE),
    noCheck_(FALSE),
    noIMneeded_(FALSE),
    useMVCC_(FALSE),
    useSSCC_(FALSE),
    preconditionTree_(NULL)
  {}

  // copy ctor
  GenericUpdate (const GenericUpdate & orig, CollHeap * h=0) ; // not written

  // virtual destructor
  virtual ~GenericUpdate();

  // append an ascii-version of GenericUpdate 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);

  // get the degree of this node (it is a unary op).
  virtual Int32 getArity() const;

  // accessor and mutator functions
  const CorrName &getTableName() const         { return updatedTableName_; }
  CorrName &getTableName()                     { return updatedTableName_; }
  const CorrName *getPtrToTableName() const   { return &updatedTableName_; }
  TableDesc     *getTableDesc() const                     { return tabId_; }
  void          setTableDesc(TableDesc *newId)           { tabId_ = newId; }
  const         IndexDesc *getIndexDesc() const       { return indexDesc_; }
  void          setIndexDesc(const IndexDesc *id)       { indexDesc_ = id; }

  // get and set the update/key expression
  ItemExpr      *&recExprTree()
                { return newRecExprTree_; }
  void          addNewRecExprTree(ItemExpr *expr);
  ItemExpr      *removeNewRecExprTree();

  ValueIdSet    &newRecExpr()                   { return newRecExpr_; }
  ValueIdArray  &newRecExprArray()                  { return newRecExprArray_; }

  // QSTUFF
  ValueIdSet    &newRecBeforeExpr()             { return newRecBeforeExpr_; }
  ValueIdArray  &newRecBeforeExprArray()        { return newRecBeforeExprArray_; }
  // QSTUFF

  void          addKeyExprTree(ItemExpr *expr);
  ItemExpr      *removeKeyExprTree();

  ValueIdList &beginKeyPred()                    { return beginKeyPred_; }
  ValueIdList &endKeyPred()                      { return endKeyPred_;   }

  const ValueIdList &getBeginKeyPred() const     { return beginKeyPred_; }
  const ValueIdList &getEndKeyPred() const         { return endKeyPred_; }

  ValueIdSet &executorPred()                     { return executorPred_; }
  ItemExpr *getExecutorPredTree()            { return executorPredTree_; }
  void setExecutorPredTree(ItemExpr *ept)     { executorPredTree_ = ept; }

  SearchKey *getSearchKey() const                    { return pathKeys_; }
  SearchKey *getPartKey() const                      { return partKeys_; }
  void setSearchKey(SearchKey *pathKey)           { pathKeys_ = pathKey; }
  void setPartKey(SearchKey *partKey)             { partKeys_ = partKey; }

  ValueIdSet    &usedColumns()                    { return usedColumns_; }

  NABoolean isMerge() const { return (isMergeUpdate_ || isMergeDelete_); }

  NABoolean isMergeUpdate() const { return isMergeUpdate_; }
  void setIsMergeUpdate(NABoolean v) { isMergeUpdate_ = v; }

  NABoolean isMergeDelete() const { return isMergeDelete_; }
  void setIsMergeDelete(NABoolean v) { isMergeDelete_ = v; }

  // MVs --
  // was the NOLOG option specified?
  void setNoLogOperation(NABoolean isConsistent = FALSE)
  { isNoLogOperation_ = isConsistent ? CONSISTENT_NOLOG : INCONSISTENT_NOLOG; }
  NoLogType isNoLogOperation() const	     { return isNoLogOperation_; }
  void setNoLogOp(NoLogType val)
  { isNoLogOperation_ = val; }

  // triggers
  void setIgnoreTriggers (NABoolean ignoreTriggers = FALSE)
     {isIgnoreTriggers_ = ignoreTriggers; }
  NABoolean isIgnoreTriggers() const         { return isIgnoreTriggers_; }

  // Accessor for the noFlow flag.
  NABoolean getNoFlow() const { return noFlow_; }
  // Mutator for the noFlow flag.
  void setNoFlow(NABoolean noFlow)
    { noFlow_ = noFlow;  }

  //MTS - Multi Transaction Support
  NABoolean isMtsStatement() const
                         { return mtsStatement_; }
  void setMtsStatement(NABoolean lastRow)
                         { mtsStatement_ = lastRow; }

  //No rollback - Transaction Type support
  NABoolean isNoRollback() const
                         { return noRollback_; }
  void setNoRollbackOperation(NABoolean flag = TRUE)
                         { noRollback_ = flag; }

  NABoolean getUpdateCKorUniqueIndexKey() const
                         { return updateCKorUniqueIndexKey_; }
  void setUpdateCKorUniqueIndexKey(NABoolean val)
                         { updateCKorUniqueIndexKey_ = val; }

  // Index maintenance helpers
  //
  // Records mapping between index and index number used by binder -- needed
  // to index into the various other index arrays in the generator.
  // ##IM: IM_GENERATOR scheme only, to be REMOVED soon!
  //
  ARRAY(IndexDesc *) &indexNumberArray()     { return indexNumberArray_; }

  // Set of assign nodes for each index -- used for insert.
  //
  ARRAY(ValueIdArray)  &indexNewRecExprArrays()
                                        { return indexNewRecExprArrays_; }

  // Expressions for begin and end key for each index
  //
  ARRAY(ValueIdList) &indexBeginKeyPredArray()
                                       { return indexBeginKeyPredArray_; }
  ARRAY(ValueIdList) &indexEndKeyPredArray()
                                         { return indexEndKeyPredArray_; }

  void setNoIMneeded(NABoolean v)
  {
    noIMneeded_ = v;
  }
  NABoolean noIMneeded()
  {
    return noIMneeded_;
  }

  // The generator needs a reference to the original scan columns
  // ##IM: not needed any more (?) -- REMOVE the scanIndexDesc_ member! (?)
  //
  const IndexDesc *getScanIndexDesc() const     { return scanIndexDesc_; }
  void setScanIndexDesc(const IndexDesc *id)      { scanIndexDesc_ = id; }

  // Methods that operate on the check constraints.
  const ValueIdList &getCheckConstraints() const
                                             { return checkConstraints_; }
  ValueIdList &checkConstraints()            { return checkConstraints_; }

  // Initialize the characteristic outputs
  void initCharacteristicOutputs() const;

  // 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.
  // should never be called on an update
  virtual void recomputeOuterReferences();

  // The set of values that I can potentially produce as output.
  virtual void getPotentialOutputValues(ValueIdSet &vs) const;
  void setPotentialOutputValues(const ValueIdSet &vs)
                                        { potentialOutputs_ = vs; }
  void setPotentialOutputValues(const ValueIdList &vl)
                                        { potentialOutputs_.clear();
                                          potentialOutputs_.insertList(vl);
                                        }
  void addPotentialOutputValues(const ValueIdList &vl)
                                        {
                                          potentialOutputs_.insertList(vl);
                                        }
  //++MV - returns the GenericUpdateOutputFunction's that are in the
  // characteristic outputs
  NABoolean getOutputFunctionsForMV(ValueId &epochValueId, 
                                    OperatorTypeEnum opType) const;

  NABoolean producesOutputs() const     { return !potentialOutputs_.isEmpty(); }

  virtual void getInputValuesFromParentAndChildren(ValueIdSet &vs) const;

  // a virtual function for performing name binding within the query tree
  RelExpr *bindNode(BindWA *bindWA);

  // Index Maintenance in the Binder
  RelExpr *createIMTree(BindWA *bindWA,
                        UpdateColumns *updatedColumns,
                        NABoolean useInternalSyskey);
  RelExpr *createIMNodes(BindWA *bindWA,
                         NABoolean useInternalSyskey,
                         IndexDesc *index,
                         const ValueId &mergeIUDIndicator);
  RelExpr *createUndoTree(BindWA *bindWA,
                          UpdateColumns *updatedColumns,
                          NABoolean useInternalSyskey,
                          NABoolean isImOrRiPresent,
                          NABoolean isOrMvPresent,
                          TriggersTempTable *tempTableObj);
  RelExpr *createUndoNodes(BindWA *bindWA,
                           NABoolean useInternalSyskey,
                           IndexDesc *index);
  
  RelExpr *createUndoIUDLog(BindWA *bindWA) ;
  RelExpr *createUndoTempTable(TriggersTempTable *tempTableObj,
                               BindWA *bindWA);
  void nonvirtual_placeholder_func1();
  void nonvirtual_placeholder_func2();

  // Each operator supports a (virtual) method for transforming its
  // scalar expressions to a canonical form
  virtual void transformNode(NormWA &normWARef,
                             ExprGroupId &locationOfPointerToMe);

  // Each operator supports a (virtual) method for rewriting its
  // value expressions.
  virtual void rewriteNode(NormWA &normWARef);
  
  virtual void pushdownCoveredExpr
			  (const ValueIdSet & outputExprOnOperator,
                           const ValueIdSet & newExternalInputs,
                           ValueIdSet & predicatesOnParent,
			   const ValueIdSet * nonPredExprOnOperator = NULL,
			   Lng32 childIndex = (-MAX_REL_ARITY));

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

  // compute the columns that are actually referenced by the operation
  void computeUsedCols();

  virtual HashValue topHash();
  virtual NABoolean duplicateMatch(const RelExpr &other) const;
  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // synthesize logical properties
  virtual void synthLogProp(NormWA * normWAPtr = NULL);

  // finish synthesis of logical properties by setting the cardinality
  // attributes
  virtual void finishSynthEstLogProp();

  virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp);

  // Generate the write access set.
  virtual SubTreeAccessSet * calcAccessSets(CollHeap *heap);

  // 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 a printable string that describes this operator
  virtual const NAString getText() const;
  const NAString getUpdTableNameText() const;

  StmtLevelAccessOptions &accessOptions()       { return accessOptions_; }

  // adds information about this node to the Explain tree
  virtual ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
					      ComTdb * tdb,
					      Generator *generator);

  short addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
			       ComTdb * tdb,
			       Generator *generator,
			       NAString &description);


  NABoolean updateCurrentOf();
  ItemExpr *&currOfCursorName()                 { return currOfCursorName_; }

  RowsAffected &rowsAffected()                  { return rowsAffected_; }
  void finalizeRowsAffected(const GenericUpdate *before)
  {
    rowsAffected_ = (before->rowsAffected_ == DO_NOT_COMPUTE_ROWSAFFECTED)
                    ? DO_NOT_COMPUTE_ROWSAFFECTED : COMPUTE_ROWSAFFECTED;
    // (thus a before value of DEFAULT_ROWSAFFECTED becomes COMPUTE_ ...)
  }

  OptSqlTableOpenInfo *&getRefToStoi()             { return stoi_; }
  OptSqlTableOpenInfo *getOptStoi() const             { return stoi_; }
  void setOptStoi(OptSqlTableOpenInfo *stoi)          { stoi_ = stoi; }

  // access to value id map between updated and selected columns
  ValueIdMap &updateToSelectMap()  { return updateToSelectMap_; }

  virtual NABoolean okToAttemptESPParallelism (
            const Context* myContext, /*IN*/
            PlanWorkSpace* pws, /*IN*/
            Lng32& numOfESPs, /*OUT*/
            float& allowedDeviation, /*OUT*/
            NABoolean& numOfESPsForced /*OUT*/) ;


  // QSTUFF
  // --------------------------------------------------------------------
  // This routine checks whether a table is both read and updated
  // --------------------------------------------------------------------
  virtual rwErrorStatus checkReadWriteConflicts(NormWA & normWARef);

    // access to value id map between updated and selected columns
  ValueIdMap &oldToNewMap()  { return oldToNewMap_; }

  // this method binds both, the set clauses applied to the after
  // image as well as the set clauses applied to the before image
  // the new set on rollback clause allows an application to modify
  // the before image.
  // delete from tab set on rollback x = 1;
  // update tab set x = 1 set on rollback x = 2;

  void bindUpdateExpr(BindWA	    *bindWA,
                      ItemExpr	    *recExpr,
                      ItemExprList  &RecExpr,
                                          RelExpr       *boundView,
                                          Scan          *scanNode,
                                          SET(short)    &stoiColumnSet,
                                          NABoolean     onRollback = FALSE);

  ItemExpr * subqInUpdateAssign() { return subqInUpdateAssign_; }
  void setSubqInUpdateAssign(ItemExpr * re) { subqInUpdateAssign_ = re; }

  ValueIdSet    &mergeInsertRecExpr()       { return mergeInsertRecExpr_; }
  ValueIdArray  &mergeInsertRecExprArray()  { return mergeInsertRecExprArray_;}
  ValueIdSet    &mergeUpdatePred()          { return mergeUpdatePred_; }

  // QSTUFF
  void setTransactionRequired(Generator *generator,
                              NABoolean isNeededForAllFragments = FALSE);

  // Handle the inlining of Triggers, RI and IM.
  RelExpr *handleInlining(BindWA *bindWA, RelExpr *boundExpr);

  // Returns TRUE if need for logging or marking inconsistent.
  NABoolean isMvLoggingRequired();

  virtual PlanPriority computeOperatorPriority
    (const Context* context,
     PlanWorkSpace *pws=NULL,
     Lng32 planNumber=0);

  virtual NABoolean computeRowsAffected() const;

  inline NABoolean avoidHalloween() const
  { return avoidHalloween_; }

  inline void setAvoidHalloween(NABoolean h)
  { avoidHalloween_ = h; }

  inline void setHalloweenCannotUseDP2Locks(NABoolean h)
  { halloweenCannotUseDP2Locks_ = h; }

  inline NABoolean getHalloweenCannotUseDP2Locks() const
  { return halloweenCannotUseDP2Locks_; }

  // Following methods compatible with Neo R2.
  inline NABoolean avoidHalloweenR2() const 
  { return avoidHalloweenR2_ > 0; }

  inline void setAvoidHalloweenR2(UInt32 numHalloweenR2)
  { avoidHalloweenR2_ = numHalloweenR2; }

  inline void resetAvoidHalloweenR2() 
  {
    avoidHalloweenR2_--;
    CMPASSERT(avoidHalloweenR2_ != 0);
  }

  void configTSJforHalloween( Join* j, OperatorTypeEnum o, CostScalar c);

  // Override the RelExpr method 
  virtual RelExpr *normalizeNode(NormWA & normWARef);

  NABoolean checkForMergeRestrictions(BindWA *bindWA);

  //////////////////////////////////////////////////////
  virtual NABoolean pilotAnalysis(QueryAnalysis* qa);
  //////////////////////////////////////////////////////

  NABoolean &hbaseOper() { return hbaseOper_; }
  NABoolean &uniqueHbaseOper() { return uniqueHbaseOper_; }
  NABoolean &cursorHbaseOper() { return cursorHbaseOper_; }
  NABoolean &uniqueRowsetHbaseOper() { return uniqueRowsetHbaseOper_; }
  const NABoolean &uniqueRowsetHbaseOper() const { return uniqueRowsetHbaseOper_; }
  NABoolean &canDoCheckAndUpdel() { return canDoCheckAndUpdel_; }

  NABoolean &noDTMxn() { return noDTMxn_; }
  NABoolean &useRegionXn() { return useRegionXn_; }

  NABoolean noCheck() { return noCheck_; }
  void setNoCheck(NABoolean v) { noCheck_ = v; }

  NABoolean &useMVCC() { return useMVCC_; }

  NABoolean &useSSCC() { return useSSCC_; }
 
  NABoolean useMVCCorSSCC() { if (useSSCC_ || useMVCC_)
                                return TRUE;
                               else
                                 return FALSE; 
                            }

  inline ItemExpr * getPreconditionTree() const { return preconditionTree_; }
  inline const ValueIdSet getPrecondition() const { return precondition_; }
  inline void setPreconditionTree(ItemExpr *pc) { preconditionTree_ = pc; }
  inline void setPrecondition(const ValueIdSet pc)
           { precondition_ = pc; exprsInDerivedClasses_ += precondition_; }
  inline const ValueId & getProducedMergeIUDIndicator() const
                                     { return producedMergeIUDIndicator_; }
  inline void setProducedMergeIUDIndicator(const ValueId &v)
                                        { producedMergeIUDIndicator_ = v; }
  inline const ValueId & getReferencedMergeIUDIndicator() const
                                   { return referencedMergeIUDIndicator_; }
  inline void setReferencedMergeIUDIndicator(const ValueId &v)
                                      { referencedMergeIUDIndicator_ = v; }

  virtual ItemExpr * insertValues() { return NULL;}

protected:

  // Here, derived classes can register expressions that are used by
  // them, so that the computation of characteristic inputs can make
  // sure these expressions get the inputs they need.
  ValueIdSet exprsInDerivedClasses_;
  
private:

  // ---------------------------------------------------------------------
  // Triggers --
  // Methods for inlining triggers, RI and IM.
  // ---------------------------------------------------------------------

  // This method is better known as setRETDescForTSJTree()
  RETDesc * createOldAndNewCorrelationNames(BindWA *bindWA,
                                       NABoolean createRETDescOnly=FALSE);


  // helper function to method handleInlining use to check some currently
  // unsupported uses of triggers
  NABoolean checkNonSupportedTriggersUse(BindWA *bindWA, QualifiedName &subjectTable,
                                         ComOperation op, BeforeAndAfterTriggers *allTriggers);

  // Add a "virtual" column to this GenericUpdate node.
  ValueId addVirtualColumn(BindWA *bindWA, ItemExpr *colExpr, const char *colName, CollHeap *heap);

  // Inline IndexMaintainance.
  NABoolean isIMNeeded(UpdateColumns *updatedColumns);
  RelExpr *inlineIM(RelExpr *topNode,
		    BindWA *bindWA,
		    NABoolean isLastTSJ,
		    UpdateColumns *updatedColumns,
		    CollHeap *heap,
		    NABoolean useInternalSyskey,
		    NABoolean rowTriggersPresent);

  // Handle inlining of RI, row triggers and the temp insert.
  RelExpr *inlinePipelinedActions(RelExpr *topNode, BindWA *bindWA,
				  TriggerList *rowTriggers,
				  RefConstraintList *riList,
				  CollHeap *heap);

  // Create the sub-tree that inserts the affected set into the temporary table.
  RelExpr *inlineTempInsert(RelExpr *topNode,
			    BindWA *bindWA,
			    TriggersTempTable& tempTableObj,
			    NABoolean isDrivenByBeforeTriggers,
			    NABoolean isTopMostTSJ,
			    CollHeap *heap);

  // Create the sub-tree that deletes the affected set from the temp table.
  RelExpr *inlineTempDelete(BindWA *bindWA, RelExpr *topNode, TriggersTempTable& tempTableObj, CollHeap *heap);

  // Fix the NEW@ cols according to Update/Insert expressions.
  void fixTentativeRETDesc(BindWA *bindWA, CollHeap *heap);

  // For Update nodes, add the predicate: OLD@.<ci> = NEW@.<ci>
  void addPredicateOnClusteringKey(BindWA *bindWA, RelExpr *tentativeNode, CollHeap *heap);

  // This method replaces the GenericUpdate node with a temporary Rename node
  // that functions as the tentative execution node, and goes away during Transfomation.
  // The actual changes to the subject table are done elsewhere (see inlineEffectiveGU() below).
  RelExpr *createTentativeGU(BindWA *bindWA, CollHeap *heap);

  // Create the left sub-tree of the inlining backbone, when before triggers exist.
  RelExpr *createTentativeSubTree(BindWA *bindWA, TriggerList *triggers, UpdateColumns *updatedColumns, TriggersTempTable& tempTableObj, CollHeap *heap);

  // Inline the GenericUpdate node that affects the base table following
  // the inlining of before triggers. The first method is a pure virtual method
  // implemented by the sub-classes: Insert, Delete and Update.
  // The second method uses the first method in building the EffectiveGU sub-tree.
  virtual RelExpr *createEffectiveGU(BindWA *bindWA,
                                     CollHeap *heap,
				     TriggersTempTable& tempTableObj,
				     GenericUpdate **effectiveGUNode,
				     UpdateColumns *colsToSet=NULL);

  // When the binding gets to the effective GU, don't inline triggers
  // recursively, but generate the NEW@ and OLD@ values if needed.
  RelExpr *bindEffectiveGU(BindWA *bindWA);

  void removeRedundantInputsFromTempInsertTree(BindWA  *bindWA,
                                               RelExpr *tentativeSubtree);

  RelExpr *inlineAfterOnlyBackbone(BindWA *bindWA,
				   TriggersTempTable& tempTableObj,
				   TriggerList *rowTriggers,
				   TriggerList *stmtTriggers,
				   RefConstraintList *riConstraints,
				   NABoolean needIM,
                                   NABoolean isMVLoggingRequired,
  				   UpdateColumns *updatedColumns,
				   CollHeap *heap);
  RelExpr *inlineAfterOnlyBackboneForUndo(BindWA *bindWA,
				   TriggersTempTable& tempTableObj,
				   TriggerList *rowTriggers,
				   TriggerList *stmtTriggers,
				   RefConstraintList *riConstraints,
				   NABoolean needIM,
                                   NABoolean isMVLoggingRequired,
  				   UpdateColumns *updatedColumns,
				   CollHeap *heap);

  RelExpr *inlineBeforeAndAfterBackbone(BindWA *bindWA,
					RelExpr *tentativeSubtree,
					TriggersTempTable& tempTableObj,
					TriggerList *rowTriggers,
					TriggerList *stmtTriggers,
					RefConstraintList *riConstraints,
					NABoolean needIM,
                                        NABoolean isMVLoggingRequired,
					UpdateColumns *updatedColumns,
					CollHeap *heap);

  // Is this backbone cascaded from a row after trigger?
  NABoolean shouldForbidMaterializeNodeHere(BindWA *bindWA);

  // Private functions RI support.
  RelExpr *createRISubtree(BindWA *bindWA,
			   const NATable *naTable,
			   const RefConstraint& refConstraint,
			   CollHeap *heap);

  // Inline Referential Integrity constraints
  RelExpr *inlineRI (BindWA *bindWA,
		     const RefConstraintList *refConstraints,
		     CollHeap *heap);

  // Get the list of referential integrity constraints.
  RefConstraintList *getRIs(BindWA *bindWA, const NATable *naTable);

  // Add to the RETDesc the virtual columns needed for MV logging.
  void prepareForMvLogging(BindWA *bindWA,
			   CollHeap *heap);

  // Create the subtree for inserting rows into the MV log table.
  RelExpr *createMvLogInsert(BindWA *bindWA,
			     CollHeap *heap,
			     UpdateColumns *updatedColumns,
			     NABoolean projectMidRangeRows);

  RelExpr *inlineOnlyRIandIMandMVLogging(BindWA *bindWA,
					 RelExpr *topNode,
					 NABoolean needIM,
					 RefConstraintList *riConstraints,
					 NABoolean isMVLoggingRequired,
					 UpdateColumns *columns,
					 CollHeap *heap);

  // Finish the inlining procedure.
  void InliningFinale(BindWA *bindWA, RelExpr *topNode, RETDesc *origRETDesc);


  // MV
  // Add all the ON STATEMENT MVs that should be refreshed as a result of the
  // current IUD action to the list of triggers
  BeforeAndAfterTriggers *getTriggeredMvs(BindWA *bindWA,
					  BeforeAndAfterTriggers *list,
					  UpdateColumns *columns);

  // MV
  // The actual insertion of the ON STATEMENT MVs to the list of triggers.
  // This method is NOT implemented for GenericUpdate, but do implemented
  // for the derived classes (Insert Update and Delete).
  virtual void insertMvToTriggerList(BeforeAndAfterTriggers *list,
				     BindWA *bindWA,
				     CollHeap *heap,
				     const QualifiedName &mvName,
				     MVInfoForDML *mvInfo,
				     const QualifiedName &subjectTable,
				     UpdateColumns *updateCols = NULL);

  // If we are reading from the same table we are updating, check to
  // see if we can support this potential halloween problem
  //
  NABoolean checkForHalloweenR2(Int32 numScansToFind);

  NABoolean checkForNotAtomicStatement(BindWA *bindWA, Lng32 sqlcode, NAString objname, NAString tabname);

  // name of the table affected by the operation
  CorrName updatedTableName_;

  // a unique identifer for the updated table
  TableDesc *tabId_;

  // a value id map to map key columns from the above TableDesc to
  // the key columns of the select part of the update
  ValueIdMap updateToSelectMap_;

  // the index descriptor of the updated table (for physical nodes only)
  const IndexDesc *indexDesc_;

  // Expressions to compute the inserted/updated record from the child record.
  //
  // The newRecExpr_ is assumed to be a set of Assign item expressions.
  // It is used for insert and update operations, by Optimizer.
  // It contains values for columns to insert/update.
  //
  // The newRecExprArray_ is an array of Assigns ordered by column position:
  // used for insert and update, by Generator.
  // For an Insert, it will contain Assigns for *all* columns of the target
  // (if not all cols were specified in the insert stmt, the binder will
  // have filled in default vals).  Also, in certain cases, it contains
  // Assigns for syskey columns -- see Binder for details.
  //
  // The usedColumns_ set indicates which columns are needed to
  // perform the operation, this is mainly to support physical operations.
  ItemExpr     *newRecExprTree_;
  ValueIdSet    newRecExpr_;
  ValueIdArray  newRecExprArray_;
  ValueIdSet    usedColumns_;

  // QSTUFF
  ValueIdSet    newRecBeforeExpr_;
  ValueIdArray  newRecBeforeExprArray_;
  ValueIdSet    usedBeforeColumns_;
  // QSTUFF

  ValueIdSet    potentialOutputs_;

  // Index Maintenance in the Generator (old scheme)  ##IM: TO BE REMOVED...
  //
  // Vector Mapping indexDesc to index number -- this is used to index into
  // the various arrays of expressions related to the indexes.
  // ##IM: IM_GENERATOR scheme only, to be REMOVED soon!
  //
  ARRAY(IndexDesc *) indexNumberArray_;

  // The ValueIdSets for the indexes
  //
  ARRAY(ValueIdArray) indexNewRecExprArrays_;

  // Begin and End Key Predicates for the indexes
  //
  ARRAY(ValueIdList) indexBeginKeyPredArray_;
  ARRAY(ValueIdList) indexEndKeyPredArray_;

  // The descriptor for the original scan table.
  //
  const IndexDesc *scanIndexDesc_;      // ##IM: REMOVE?

  // Begin and end key expression trees. Both are used for subset and
  // range update/deletes.
  // For inserts and unique updates/deletes, only beginKeyExpr_ is set.
  ValueIdList beginKeyPred_;
  ValueIdList endKeyPred_;

  // Key objects for the clustering key and the partitioning key
  SearchKey  *pathKeys_;
  SearchKey  *partKeys_;

  // executor predicates
  ValueIdSet executorPred_;
  ItemExpr  *executorPredTree_;

  // SQL/MP check constraints on the table to be updated.
  ValueIdList checkConstraints_;

  // Contains user specified STABLE or REPEATABLE access type
  StmtLevelAccessOptions accessOptions_;

  // The next field containing information to process the 'where current of'
  // clause in an update/delete statement.

  // Name of the cursor or a hostvar which will contain the cursor
  // name at runtime. Set to a non-null value if the 'where current of'
  // clause is specified in the update/delete stmt.
  ItemExpr  *currOfCursorName_;

  // This flag, if COMPUTE_ROWSAFFECTED, indicates that affected rows
  // (inserted, updated, or deleted) are to be computed for this node
  // at runtime.  A flag is needed so that we compute the rows
  // affected for base table ins/upd/del only and not for indexes.
  RowsAffected rowsAffected_;

  // tables open information which is necessary during the open of a sql table.
  OptSqlTableOpenInfo *stoi_;

  // MVs --
  // Is MV logging disabled, and should the table be marked as inconsistent.
  NoLogType isNoLogOperation_;

  // triggers
  NABoolean isIgnoreTriggers_;

  NABoolean noFlow_;

  // QSTUFF
  // this indicates that a on rollback clause was specified in a delete or update
  // statement and that the operator causes updates a before image
  NABoolean updateOnRollback_;

  ValueIdMap oldToNewMap_;

  //MTS - Multi Transaction Support
  // this indicates that the update is part of an MTS query
  // and that only the last row that got updated needs to be returned.
  // However currently the embedded insert for MTS returns all
  // rows, so this flag is used to decide when to set potential outputs
  // and return the appropriate RETDesc.
  NABoolean mtsStatement_;

  //Transaction Type Support
  // this indicates that this IUD is of no Rollback transaction type
  // Allowed only when autocommit is ON and there are no dependent objects
  NABoolean noRollback_;

  // Note that the following comments document the handling of the 
  // Halloween probem as it was implemented .
  // Some restrictions in the R2 implementation have been removed for
  // Neo R2.2.  However, a CQD, R2_HALLOWEEN_SUPPORT can be used to
  // get the old R2 behavior, hence the suffix "R2" on the accessor
  // and mutator methods and the class member variable.

  // If greater than 0, then this Generic Update could potentially run
  // into the Halloween problem.  The source contains a reference to
  // the target. We check for this in binder and issue an error in
  // many cases, but in some cases we allow it and set this flag to
  // TRUE.  If this flag is set, then we must generate a safe plan WRT
  // the Halloween problem.  For the Generic Update operator, this
  // means that the plan should have a SORT operator on the LHS of the
  // Tuple Flow.  This causes the source to be blocked.
  //
  UInt32 avoidHalloweenR2_;

  // Starting with Neo R2.2, a simple boolean is set in the bindNode
  // method.  It is read when configTSJforHalloween is called by 
  // the topMatch methods of TSJFlowRule and TSJRule.  If it is 
  // set to true, configTSJforHalloween will decide whether to protect
  // from Halloween by using the DP2 locks method.
  
  NABoolean avoidHalloween_;

  // Also used in the Neo R2.2 scheme, the next attribute is set to 
  // indicate that the self-referenced table is being access in 
  // modes incompatible with DP2 locks, i.e., SERIALIZABLE or
  // READ UNCOMMITTED ACCESS, or TABLELOCK is requests (the latter
  // is tbd.)  Then is it used in configTSJforHalloween.
  NABoolean halloweenCannotUseDP2Locks_;

  NABoolean isMergeUpdate_;
  NABoolean isMergeDelete_;

  ItemExpr * subqInUpdateAssign_;

  ValueIdSet    mergeInsertRecExpr_;
  ValueIdArray  mergeInsertRecExprArray_;
  ValueIdSet    mergeUpdatePred_;

  // flag to indicate if an insert or delete node is being used implement 
  // part of an update that changes a clustering key or unique index key.
  NABoolean updateCKorUniqueIndexKey_;

  NABoolean hbaseOper_;
  NABoolean uniqueHbaseOper_;
  NABoolean cursorHbaseOper_;
  NABoolean uniqueRowsetHbaseOper_;
  NABoolean canDoCheckAndUpdel_;

  // if set to ON, then this operator is not run as part of an enclosing DTM transaction 
  // nor is a transaction needed to execute it.
  // It is executed using underlying hbase single row transaction consistency.
  NABoolean noDTMxn_;

  // if set to ON, then query is run as part of localized region transaction.
  // No external transaction is started to run it.
  NABoolean useRegionXn_;

  // If set, then for seabase tables, no check of rows existence or non-existence
  // is done during an insert or delete operation. 
  // For insert, row overwrites an existing row, dup error is not returned. (upsert)
  // For delete, rows are deleted if they exist. Caller doesn't get an indication if
  // a row existed or not.
  NABoolean noCheck_;

  // curently used by Delete and Bulk Load Insert only. Other operators
  // have different schemes to avoid IM
  NABoolean noIMneeded_;

  // if set to ON, then this statement will run under MVCC mode
  NABoolean useMVCC_;

  // if set to ON, then this statement will run under SSCC mode
  NABoolean useSSCC_;

  // predicate evaluated before doing the LeafInsert(unique IM)
  // LeafDelete (IM). Only insert/delete if TRUE
  ItemExpr *preconditionTree_;
  ValueIdSet precondition_;

  // For upsert or merge we need an indicator whether the
  // action for a particular row is an insert, update or
  // delete. This ValueId is either NULL_VALUE_ID (meaning
  // no merge or upsert) or it is an expression evaluating
  // to a CHAR(1) CHARACTER SET ISO88591 with these values:
  //   I  this row is being inserted
  //   U  this row is being updated
  //   D  this row is being deleted
  // When we inline index maintenance operations, we generate
  // a tree for an update. This indicator can be used at
  // runtime to suppress index deletion for inserts and to
  // suppress index inserts for deletion. Similar actions
  // can be taken for other inlined code like RI constraints,
  // triggers or MVs (once supported).
  ValueId producedMergeIUDIndicator_;

  // the above variable is used at the producer side, the
  // actual MERGE or Upsert statement. However, we also need
  // to remember it on the consumer side, like an IM insert
  // or delete, this is done here:
  ValueId referencedMergeIUDIndicator_;

};

// -----------------------------------------------------------------------
// The INSERT operator can be used to represent two types of inserts:
//  1) insert specifying a list of constants (use Tuple class as child)
//  2) insert specifying a selection expression (any query as child)
//
// The Insert operator will for each row of its child apply the selection
// predicate (from RelExpr), then calculate a new row by applying
// GenericUpdate::newRecExprArray(), and then insert the result into the
// target table identified by (name,tabId).
// -----------------------------------------------------------------------
class Insert : public GenericUpdate
{
public:

  enum InsertType
  {
    SIMPLE_INSERT,       // One row inserted at a time, data is not buffered.
    VSBB_INSERT_SYSTEM,  // "Smart range lock" - DP2 decides when to turn on
                         // VSBB inserts, and what range to lock.
    VSBB_INSERT_USER,    // "Dumb range lock" - The entire range from the first
                         // row inserted until the next physical row in the
			 // partition is locked.
    VSBB_LOAD,           // SideTree Insert - Buffered inserts into an empty
                         // non-audited key sequenced table. Used with
                         // Load or Create Index queries.
    VSBB_LOAD_AUDITED,   // SideTree Insert - Buffered inserts into an empty
                         // audited key sequenced table. Used with
                         // "insert using load" queries.
    VSBB_LOAD_APPEND,    // Buffered inserts into a non-empty audited key-seq
                         // table
    VSBB_LOAD_NO_DUP_KEY_CHECK, // same as VSBB_LOAD but DP2 doesn't check for
                                // duplicate keys. Used when oneis SURE that
                                // source will not have a duplicate key,
                                // like when loading from a key seq
                                // table to another key seq table
                                // with the same key value.
    VSBB_LOAD_APPEND_NO_DUP_KEY_CHECK,

    VSBB_INSERT_ANYWHERE, // The data is buffered, but does not need to be
                         // sequential, ordered or very large. No range lock
			 // used during the insert operation.
    UPSERT_INSERT,
    UPSERT_LOAD
  };


  Insert(const CorrName &name,
         TableDesc *tabId,
         OperatorTypeEnum otype = REL_UNARY_INSERT,
         RelExpr *child = NULL,
         ItemExpr *insertCols = NULL,
         ItemExpr *orderBy = NULL,
         CollHeap *oHeap = CmpCommon::statementHeap(),
         InsertType insertType = SIMPLE_INSERT,
         NABoolean createUstatSample = FALSE);

  // copy ctor
  Insert (const Insert &) ; // not written

  // virtual destructor
  virtual ~Insert();

  // accessor functions
  void          addInsertColTree(ItemExpr *expr);
  ItemExpr      *removeInsertColTree();
  ItemExpr      *getInsertColTree();
  void          addOrderByTree(ItemExpr *expr);
  ValueIdList   &reqdOrder()            { return reqdOrder_; }

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  // Override the GenericUpdate method to transform an Insert-Tuple pair
  // to a LeafInsert node.
  virtual RelExpr *normalizeNode(NormWA & normWARef);

  // method to do code generation
  virtual short codeGen(Generator *);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // For round-robin partitioned tables, it is necessary to
  // communicate information between bindNode() and codeGen()
  // regarding the expression that computes the storage key for a new
  // row being inserted, and inputs to this expression (partition
  // number, row position, and total number of partitions).  The value
  // id of each of these is stored in the insert node, accessed by the
  // following functions.
  //
  ValueId &rrKeyExpr()          { return rrKeyExpr_; }
  ValueId &partNumInput()       { return partNumInput_; }
  ValueId &rowPosInput()        { return rowPosInput_; }
  ValueId &totalNumPartsInput() { return totalNumPartsInput_; }

  NABoolean &bufferedInsertsAllowed()     { return bufferedInsertsAllowed_; }

  InsertType &getInsertType() { return insertType_; }
  const InsertType &getInsertType() const { return insertType_; }
  void setInsertType(const InsertType &insType) 
  {
    if ((insType == UPSERT_INSERT) ||
	(insType == UPSERT_LOAD) ||
	(noCheck()))
      {
	if (insType == UPSERT_LOAD)
	  insertType_ = insType;

        isUpsert_ = TRUE;
      }
    else
      insertType_ = insType; 
  }

  NABoolean isInsertSelectQuery() { return insertSelectQuery_; }
  void setInsertSelectQuery(NABoolean v) { insertSelectQuery_ = v; }

  void setTargetUserColPosList(CollIndexList &colPos)
  {
    targetUserColPosList_ = &colPos;
  }
  void setTargetUserColPosList()
  {
    targetUserColPosList_ = NULL;
  }
  NABoolean canBindDefaultSpecification() const
  {
    return (targetUserColPosList_ != NULL);
  }
  const char *getColDefaultValue(BindWA *bindWA,
                                 CollIndex positionInTheColPosList) const;

  NABoolean& insertATuple() { return insert_a_tuple_; };

  // append an ascii-version of Insert 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);

  void setNoBeginCommitSTInsert(NABoolean noBeginSTI, NABoolean noCommitSTI);

  NABoolean noBeginSTInsert()  { return noBeginSTInsert_;  }
  NABoolean noCommitSTInsert() { return noCommitSTInsert_; }

  NABoolean &enableTransformToSTI() { return enableTransformToSTI_;}
  NABoolean &enableAqrWnrEmpty()    { return enableAqrWnrEmpty_; }

  NABoolean systemGeneratesIdentityValue()  const
  { return systemGeneratesIdentityValue_;};

  void setSystemGeneratesIdentityValue(NABoolean value) 
  { systemGeneratesIdentityValue_ = value; };

  // Test whether sidetree insert can be performed.
  NABoolean isSideTreeInsertFeasible();

  RelExpr * getBoundView() {return boundView_ ;}
  void setBoundView(RelExpr * val) {boundView_ = val;}

  NABoolean isDataSorted(Insert *bef, const Context *context);

  NABoolean getOverwriteHiveTable()
  {
    return overwriteHiveTable_;
  }
  void setOverwriteHiveTable(NABoolean v)
  {
    overwriteHiveTable_ = v;
  }

  NABoolean isSequenceFile()
  {
    return isSequenceFile_;
  }
  void setSequenceFile(NABoolean sf)
  {
    isSequenceFile_ = sf;
  }

  const NABoolean isUpsert() const { return isUpsert_; }
  void setIsUpsert(NABoolean v) { isUpsert_ = v; }

  const NABoolean isUpsertLoad() const { return (isUpsert_ && (getInsertType() == UPSERT_LOAD)); }

  NABoolean getIsTrafLoadPrep() const
  {
    return isTrafLoadPrep_;
  }

  void setIsTrafLoadPrep(NABoolean isTrafLoadPrep)
  {
    isTrafLoadPrep_ = isTrafLoadPrep;
  }

  NABoolean getCreateUstatSample() const
  {
    return createUstatSample_;
  }

  void setCreateUstatSample(NABoolean val)
  {
    createUstatSample_ = val;
  }

  const ItemExprList &baseColRefs() const       { return *baseColRefs_; }

  void setBaseColRefs(ItemExprList * val) {
    baseColRefs_ = val;
  }

  NABoolean xformedEffUpsert() const
  {
    return xformedEffUpsert_;
  }
  void setXformedEffUpsert(NABoolean x)
  {
    xformedEffUpsert_ = TRUE;
  }
  NABoolean isUpsertThatNeedsTransformation(NABoolean isAlignedRowFormat, NABoolean omittedDefaultCols,NABoolean omittedCurrentDefaultCols, NABoolean &toMerge) const;
  RelExpr* xformUpsertToMerge(BindWA *bindWA) ;
  RelExpr* xformUpsertToEfficientTree(BindWA *bindWA) ;
protected:

  InsertType       insertType_;

  // -- Triggers
  // Create a new Insert node that inserts the affected set into the subject table. Used for Before Triggers.
  virtual RelExpr *createEffectiveGU(BindWA *bindWA,
                                     CollHeap *heap,
				     TriggersTempTable& tempTableObj,
				     GenericUpdate **effectiveGUNode,
				     UpdateColumns *colsToSet=NULL);

  // MV
  // The actual insertion of the ON STATEMENT Mv to the list of triggers
  virtual void insertMvToTriggerList(BeforeAndAfterTriggers *list,
				     BindWA *bindWA,
				     CollHeap *heap,
				     const QualifiedName &mvName,
				     MVInfoForDML *mvInfo,
				     const QualifiedName &subjectTable,
				     UpdateColumns *updateCols = NULL);

  //////////////////////////////////////////////////////
  virtual NABoolean pilotAnalysis(QueryAnalysis* qa);
  //////////////////////////////////////////////////////

  // if true, then this node could be used to insert using sidetree.
  NABoolean enableTransformToSTI_;
  // if true, query will undo a failed insert to an empty table
  // by using purgedata, so that it can AQR.
  NABoolean enableAqrWnrEmpty_;

private:

  ItemExpr        *insertColTree_;
  ItemExpr        *orderByTree_;
  ValueIdList      reqdOrder_;                  // ORDER BY list

  CollIndexList   *targetUserColPosList_;       // used by Binder only, for
                                                // VALUES(..,DEFAULT,..) binding
  NABoolean        bufferedInsertsAllowed_;
  ValueId          rrKeyExpr_;
  ValueId          partNumInput_;
  ValueId          rowPosInput_;
  ValueId          totalNumPartsInput_;

  // used by executing-in-dp2 CS.
  NABoolean insert_a_tuple_;

  // used to indicate if a sidetree insert operation should be
  // initiated and/or committed at runtime.
  // Used to implement multiple sidetree inserts/loads into the same
  // partition where one process begins the sidetree insert operation,
  // others just do inserts and another process commits it.
  // These 3 types of processes could overlap, that is, one process could
  // begin, insert & commit, and others could just insert.
  NABoolean noBeginSTInsert_;
  NABoolean noCommitSTInsert_;

  // identifies if insert-select query. This flag is set in insert::BindNode.
  // The following sample queries will set/not set this flag.
  // insert into t1 values (1,2) ; -- not insert-select
  // insert into t1 values (1,2),(2,3),(4,5); -- not insert-select
  // Insert into t1 select * from (values (1,2)) as T; -- insert-select
  // insert into t1 values((select * from t)); not insert-select
  // Insert into t1 values (?[10],?[10]); ---> not insert-select
  // Insert into t1 select * from (select T1.a, T2.a from (values(1,2)) T1(a,b), (values(2,2)) T2(a,b) where T1.b = T2.b)TT(a,b) ; -- insert-select
  NABoolean  insertSelectQuery_;

  ItemExpr *removeOrderByTree() {
    ItemExpr * result = orderByTree_;
    orderByTree_ = NULL;
    return result;
  }

  // This flag is set when the system generates the value
  // for the IDENTITY column. This flag is set
  // to false if the user specifies a value for 
  // the IDENTITY column.
  NABoolean systemGeneratesIdentityValue_;

  // RelExpr that represents the view definition after binding
  // The view text is bound twice for inserts. This RelExpr is the
  // contains the version after the second call to bindNode. It is 
  // used to set information in the viewStoi about which view columns 
  // are accessed in the insert statmement. For updates boundView is
  // passed in through bindUpdateExpr method. For Insert since the 
  // relevant information is in Insert::bindNode we are including
  // this RelExpr as a datamember. It is set to NULL after use to
  // avoid any deep copy issue in post binder phases.
  RelExpr * boundView_ ;

  NABoolean overwriteHiveTable_;
  NABoolean isSequenceFile_;

  // for hbase tables. Silently insert duplicate rows. Creates multiple versions
  // within hbase
  NABoolean isUpsert_;

  NABoolean isTrafLoadPrep_;

  // If this is TRUE, a sample table will be created during the bulk load for
  // use by Update Statistics.
  NABoolean createUstatSample_;
  NABoolean xformedEffUpsert_;
  // ColReference list of the base table columns used in creating the
  // newRecExprArray_ during bindNode(). Used only for index maintenance.
  ItemExprList *baseColRefs_;
};

// -----------------------------------------------------------------------
// A logical insert operator of arity 0, used for index maintenance
// -----------------------------------------------------------------------
class LeafInsert : public Insert
{
public:
  LeafInsert(const CorrName &name,
             TableDesc *tabId,
             ItemExprList *afterColumns,
             OperatorTypeEnum otype = REL_LEAF_INSERT,
	     ItemExpr *preconditionTree = NULL,
             CollHeap *oHeap = CmpCommon::statementHeap())
  : Insert(name, tabId, otype, NULL, NULL, NULL, oHeap)
  {setBaseColRefs(afterColumns);setPreconditionTree(preconditionTree);}

  // copy ctor
  LeafInsert (const LeafInsert &) ; // not written

  // virtual destructor
  virtual ~LeafInsert() {}

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

};

// -----------------------------------------------------------------------
// Update (for each row of the child table, which contains a key of
// the updated table), replace the row in the updated table by a new
// row, calculated by applying newRecExpr on the child row.
// -----------------------------------------------------------------------
class Update : public GenericUpdate
{
public:

  Update(const CorrName &name,
         TableDesc *tabId,
         OperatorTypeEnum otype = REL_UNARY_UPDATE,
         RelExpr *child = NULL,
         ItemExpr *newRecExpr = NULL,
         ItemExpr *currOfCursorName = NULL,
         CollHeap *oHeap = CmpCommon::statementHeap());

  // copy ctor
  Update (const Update &) ; // not written

  // virtual destructor
  virtual ~Update();

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);

  // method to do code generation
  virtual short codeGen(Generator *);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // -- Triggers
  // Create a new Update node that updates the affected set into the subject table. Used for Before Triggers.
  virtual RelExpr *createEffectiveGU(BindWA *bindWA,
                                     CollHeap *heap,
				     TriggersTempTable& tempTableObj,
				     GenericUpdate **effectiveGUNode,
				     UpdateColumns *colsToSet=NULL);

  // MV
  // The actual insertion of the ON STATEMENT Mv to the list of triggers
  virtual void insertMvToTriggerList(BeforeAndAfterTriggers *list,
				     BindWA *bindWA,
				     CollHeap *heap,
				     const QualifiedName &mvName,
				     MVInfoForDML *mvInfo,
				     const QualifiedName &subjectTable,
				     UpdateColumns *updatedCols = NULL);

  virtual NABoolean isCacheableExpr(CacheWA& cwa);

  inline const CostScalar getEstRowsAccessed() const
  { return estRowsAccessed_; }

private:

  typedef enum {
    IRELEVANT = 0,
    DIRECT,
    INDIRECT
  } MvUpdateType;

  // MV
  // checks the type of the update needed on the ON STATEMENT MV.
  MvUpdateType checkUpdateType(MVInfoForDML *mvInfo,
			       const QualifiedName &subjectTable,
			       UpdateColumns *updatedCols) const;

  // checks if any of the columns being updated either
  // (a) are part of the clustering key of the base table or
  // (b) are part of an unique index
  // this method also raises an error for some unsupported cases.
  NABoolean updatesClusteringKeyOrUniqueIndexKey(BindWA *bindWA);

  // If the previous methof returns TRUE, then this method is called
  // This method changes an Update node into Insert->Root->Delete
  // and calls bindnode on this new sequence of nodes (which also does 
  // inlining for the new insert and delete nodes)
  RelExpr *transformUpdatePrimaryKey(BindWA *bindWA);

  inline void setEstRowsAccessed(CostScalar r)  { estRowsAccessed_ = r; }

  // Estimated number of rows accessed by Update operator.
  CostScalar estRowsAccessed_;

};

// -----------------------------------------------------------------------
// To implement UPSERT functionality. MERGE is the ansi syntax for that.
// Update, if found. Insert, if not found.
// Syntax:
//  MERGE INTO <table> ON <on-expr> [ USING <sel-query> ] 
//    WHEN MATCHED THEN UPDATE SET <colname> = <value>
//    WHEN NOT MATCHED THEN INSERT (<colname>, ...) VALUES (<values), ...)
// -----------------------------------------------------------------------
class MergeUpdate : public Update
{
public:

  MergeUpdate(const CorrName &name,
	      TableDesc *tabId,
              // This is a problem, we shouldn't have two classes
              // that share the same OperatorTypeEnum value, but
              // REL_UNARY_UPDATE is also used by the Update class
              // above.
	      OperatorTypeEnum otype = REL_UNARY_UPDATE,
	      RelExpr *child = NULL,
	      ItemExpr *setExpr = NULL,
	      ItemExpr *insertCols = NULL,
	      ItemExpr *insertValues = NULL,
	      CollHeap *oHeap = CmpCommon::statementHeap(),
	      ItemExpr *where = NULL);
  
  // copy ctor
  MergeUpdate (const MergeUpdate &) ; // not written

  // virtual destructor
  virtual ~MergeUpdate();

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);

  // method to do code generation
  virtual short codeGen(Generator *);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // append an ascii-version of Insert 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);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  ItemExpr * insertCols() {return insertCols_;}
  virtual ItemExpr * insertValues() { return insertValues_;}

  NABoolean xformedUpsert() {return xformedUpsert_;}
  void setXformedUpsert() {xformedUpsert_ = TRUE;}

  NABoolean needsBindScope() const { return needsBindScope_; }
  void setNeedsBindScope(NABoolean b) { needsBindScope_ = b; }

private:
  ItemExpr *insertCols_;
  ItemExpr *insertValues_;
  ItemExpr *where_;
  NABoolean xformedUpsert_;
  NABoolean needsBindScope_;
};


// -----------------------------------------------------------------------
// The Delete operator reads its child, which contains a key of the table
// (name,tabId) to delete from and performs the deletes.
// -----------------------------------------------------------------------
class Delete : public GenericUpdate
{
public:

  Delete(const CorrName &name,
         TableDesc *tabId,
         OperatorTypeEnum otype = REL_UNARY_DELETE,
         RelExpr *child = NULL,
         ItemExpr *newRecExpr = NULL,
         ItemExpr *currOfCursorName = NULL,
	 ConstStringList * csl = NULL,
         CollHeap *oHeap = CmpCommon::statementHeap());

  // copy ctor
  Delete (const Delete &) ; // not written

  // virtual destructor
  virtual ~Delete();

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);

  // method to do code generation
  virtual short codeGen(Generator *);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // is this entire expression cacheable after this phase?
  virtual NABoolean isCacheableExpr(CacheWA& cwa);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // -- Triggers
  // Create a new Delete node that deletes the affected set from the subject table. Used for Before Triggers.
  virtual RelExpr *createEffectiveGU(BindWA *bindWA,
                                     CollHeap *heap,
				     TriggersTempTable& tempTableObj,
				     GenericUpdate **effectiveGUNode,
				     UpdateColumns *colsToSet=NULL);

  // MV
  // The actual insertion of the ON STATEMENT Mv to the list of triggers
  virtual void insertMvToTriggerList(BeforeAndAfterTriggers *list,
				     BindWA *bindWA,
				     CollHeap *heap,
				     const QualifiedName &mvName,
				     MVInfoForDML *mvInfo,
				     const QualifiedName &subjectTable,
				     UpdateColumns *updateCols = NULL);

  void setIsFastDelete(NABoolean v)
  {
    isFastDelete_ = v;
  }
  NABoolean isFastDelete()
  {
    return isFastDelete_;
  }
  
  // ValueIdList    &lobDeleteExpr()          { return lobDeleteExpr_; }

  ConstStringList* &csl() { return csl_; }

  inline const CostScalar getEstRowsAccessed() const
  { return estRowsAccessed_; }

  inline void setEstRowsAccessed(CostScalar r)  { estRowsAccessed_ = r; }

private:
  NABoolean isFastDelete_;

  // ValueIdList  lobDeleteExpr_;

  ConstStringList * csl_;
  // Estimated number of rows accessed by Delete operator.
  CostScalar estRowsAccessed_;
};

// -----------------------------------------------------------------------
// To implement UPSERT functionality. MERGE is the ansi syntax for that.
// Delete, if found. Insert, if not found.
// Syntax:
//  MERGE INTO <table> ON <on-expr> [ USING <sel-query> ] 
//    WHEN MATCHED THEN DELETE
//    WHEN NOT MATCHED THEN INSERT (<colname>, ...) VALUES (<values), ...)
// -----------------------------------------------------------------------
class MergeDelete : public Delete
{
public:

  MergeDelete(const CorrName &name,
	      TableDesc *tabId,
              // This is a problem, we shouldn't have two classes
              // that share the same OperatorTypeEnum value, but
              // REL_UNARY_DELETE is also used by the Delete class
              // above.
	      OperatorTypeEnum otype = REL_UNARY_DELETE,
	      RelExpr *child = NULL,
	      ItemExpr *insertCols = NULL,
	      ItemExpr *insertValues = NULL,
	      CollHeap *oHeap = CmpCommon::statementHeap());
  
  // copy ctor
  MergeDelete (const MergeDelete &) ; // not written

  // virtual destructor
  virtual ~MergeDelete();

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);

  // method to do code generation
  virtual short codeGen(Generator *);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  // append an ascii-version of Insert 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);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  ItemExpr * insertCols() {return insertCols_;}
  virtual ItemExpr * insertValues() { return insertValues_;}
private:
  ItemExpr *insertCols_;
  ItemExpr *insertValues_;
};

// -----------------------------------------------------------------------
// A logical delete operator of arity 0, used for index maintenance
// -----------------------------------------------------------------------
class LeafDelete : public Delete
{
public:
  LeafDelete(const CorrName &name,
             TableDesc *tabId,
             ItemExprList *beforeColumns,
	     NABoolean isUndoUniqueIndex = FALSE,
             OperatorTypeEnum otype = REL_LEAF_DELETE,
             ItemExpr *preconditionTree = NULL,
             CollHeap *oHeap = CmpCommon::statementHeap())
    : Delete(name, tabId, otype, NULL, NULL, NULL, NULL, oHeap),
    baseColRefs_(beforeColumns),
    isUndoUniqueIndex_(isUndoUniqueIndex)
    
  {trigTemp_ = NULL; setPreconditionTree(preconditionTree); }

  // copy ctor
  LeafDelete (const LeafDelete &) ; // not written

  // virtual destructor
  virtual ~LeafDelete() {}

  // a virtual function for performing name binding within the query tree
  virtual RelExpr *bindNode(BindWA *bindWA);

  const ItemExprList &baseColRefs() const       { return *baseColRefs_; }
 NABoolean isUndoUniqueIndex() {return isUndoUniqueIndex_;}
  void setUndoUniqueIndex() { isUndoUniqueIndex_ = TRUE;}

  TriggersTempTable *getTrigTemp() {return trigTemp_;}
  void setTrigTemp(TriggersTempTable *tt) { trigTemp_ = tt;}
  void setUpExecPredForUndoUniqueIndex(BindWA *bindWA);
  void setUpExecPredForUndoTempTable(BindWA *bindWA);

private:
  // ColReference list of the old(before) columns used in creating the
  // beginKeyPred during bindNode().
  ItemExprList *baseColRefs_;
  NABoolean isUndoUniqueIndex_;
  TriggersTempTable *trigTemp_;

};

class HbaseDelete : public Delete
{
public:
  HbaseDelete(CorrName &corrName,
	      RelExpr *child = NULL,
	      CollHeap *oHeap = CmpCommon::statementHeap());

  HbaseDelete(CorrName &corrName,
	      TableDesc *tableDesc,
	      CollHeap *oHeap = CmpCommon::statementHeap());
 
 HbaseDelete(CollHeap *oHeap = CmpCommon::statementHeap());
  
  virtual ~HbaseDelete();

  virtual RelExpr *bindNode(BindWA *bindWAPtr);

  // The set of values that I can potentially produce as output.
  virtual void getPotentialOutputValues(ValueIdSet &vs) const;

  // acessors
  //! getVirtualTableName method
  //  returns a const char pointer to the name of the virtual Table
  // should return a CorrName?##
  virtual const char *getVirtualTableName()
  {
    return corrName_.getQualifiedNameObj().getObjectName().data();
  }

  virtual const CorrName &getCorrName() { return corrName_;}

  // get the degree of this node (it is a leaf op).
  virtual Int32 getArity() const;

  virtual NABoolean isLogical() const { return FALSE; };
  virtual NABoolean isPhysical() const { return TRUE; };

  //! preCodeGen method 
  //  method to do preCode generation
  virtual RelExpr * preCodeGen(Generator * generator,
                               const ValueIdSet & externalInputs,
                               ValueIdSet &pulledNewInputs);

  //! codeGen method
  // virtual method used by the generator to generate the node
  virtual short codeGen(Generator*);

  //! copyTopNode
  //  used to create an Almost complete copy of the node
  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
                                CollHeap* outHeap = 0);

  //! synthPhysicalProperty
  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32     planNumber,
                                                  PlanWorkSpace  *pws);

  virtual CostMethod * costMethod() const;

  //! getText method
  //  used to display the name of the node.
  virtual const NAString getText() const;

  NAList<HbaseSearchKey*>& getHbaseSearchKeys() { return listOfSearchKeys_; };
  void addSearchKey(HbaseSearchKey* sk)
    { listOfSearchKeys_.insertAt(listOfSearchKeys_.entries(), sk); };


 ExplainTuple *
   addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
                                    ComTdb * tdb,
                                    Generator *generator);


 virtual void getInputValuesFromParentAndChildren(ValueIdSet &vs) const;

 protected:

  ListOfUniqueRows listOfDelUniqueRows_;
  ListOfRangeRows  listOfDelSubsetRows_;
  //NAList<HbaseRangeRows> listOfDelSubsetRows_;

  CorrName corrName_;

  // The search keys built during optimization.
  NAList<HbaseSearchKey*> listOfSearchKeys_;

  // set of columns that need to be retrieved from hbase. These are used
  // in executor preds, update/merge expressions or returned back as output
  // values.
  ValueIdSet retColRefSet_;

}; // class HbaseDelete

// -----------------------------------------------------------------------
// generic physical insert operator
// -----------------------------------------------------------------------
class InsertCursor : public Insert
{
public:

  InsertCursor(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_INSERT_CURSOR,
               RelExpr *child = NULL,
               CollHeap *oHeap = CmpCommon::statementHeap(),
               InsertType insertType = SIMPLE_INSERT)
  : Insert(name,tabId,otype,child,NULL,NULL,oHeap, insertType) {}

  // copy ctor
  InsertCursor (const InsertCursor &) ; // not written

  // virtual destructor
  virtual ~InsertCursor();

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const;
  virtual NABoolean isPhysical() const;

  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // get a printable string that identifies the operator
  const NAString getText() const;

private:

};

// physical Hive Insert
class HiveInsert: public Insert
{
public:
  HiveInsert(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_HIVE_INSERT,
               RelExpr *child = NULL,
               CollHeap *oHeap = CmpCommon::statementHeap(),
               InsertType insertType = SIMPLE_INSERT)
  : Insert(name,tabId,otype,child,NULL,NULL,oHeap, insertType) {};

  // copy ctor
  HiveInsert(const HiveInsert&) ; // not written

  // virtual destructor
  virtual ~HiveInsert() {};

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
                               CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const { return FALSE; };
  virtual NABoolean isPhysical() const { return TRUE; };

  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // get a printable string that identifies the operator
  const NAString getText() const;

  // method to do code generation
  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);
  virtual short codeGen(Generator *);

private:

};

// physical Hbase Insert
class HbaseInsert: public Insert
{
public:
  HbaseInsert(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_HBASE_INSERT,
               RelExpr *child = NULL,
               CollHeap *oHeap = CmpCommon::statementHeap(),
               InsertType insertType = SIMPLE_INSERT)
       : Insert(name,tabId,otype,child,NULL,NULL,oHeap, insertType),
         returnRow_(FALSE),
         vsbbInsert_(FALSE)
       {};

  // copy ctor
  HbaseInsert(const HbaseInsert&) ; // not written

  // virtual destructor
  virtual ~HbaseInsert() {};

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
                               CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const { return FALSE; };
  virtual NABoolean isPhysical() const { return TRUE; };

  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // optimizer functions
  virtual CostMethod* costMethod() const;

  // get a printable string that identifies the operator
  const NAString getText() const;

  void setReturnRow(NABoolean val) {returnRow_ = val;}
  NABoolean isReturnRow() {return returnRow_;}

  void setVsbbInsert(NABoolean val) { vsbbInsert_ = val; }
  NABoolean vsbbInsert() const { return vsbbInsert_; } 

  // method to do code generation
  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);
  virtual short codeGen(Generator *);

  ValueIdList &lobLoadExpr()                    { return lobLoadExpr_; }

private:

  // used when lob colums are being loaded. Set in GenPreCode.
  ValueIdList lobLoadExpr_;
  NABoolean returnRow_ ; // currently used only for bulk load incremental IM
  NABoolean vsbbInsert_ ;

};


class HBaseBulkLoadPrep: public Insert
{
public:
  HBaseBulkLoadPrep(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_HBASE_BULK_LOAD,
               RelExpr *child = NULL,
               NABoolean createUstatSample = FALSE,
               CollHeap *oHeap = CmpCommon::statementHeap(),
               InsertType insertType = SIMPLE_INSERT)
  : Insert(name,tabId,REL_UNARY_INSERT,child,NULL,NULL,oHeap, insertType, createUstatSample)
    {};

  // copy ctor
  HBaseBulkLoadPrep(const HBaseBulkLoadPrep&) ;

  // virtual destructor
  virtual ~HBaseBulkLoadPrep() {};

  virtual RelExpr * bindNode(BindWA *bindWA);

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
                               CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const { return TRUE; };
  virtual NABoolean isPhysical() const { return FALSE; };

private:

};
// -----------------------------------------------------------------------
// Update with a cursor
// -----------------------------------------------------------------------
class UpdateCursor : public Update
{
public:

  UpdateCursor(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_UPDATE_CURSOR,
               RelExpr *child = NULL,
               CollHeap *oHeap = CmpCommon::statementHeap())
  : Update(name,tabId,otype,child,NULL,NULL,oHeap) {}

  // copy ctor
  UpdateCursor (const UpdateCursor &) ; // not written

  // virtual destructor
  virtual ~UpdateCursor();

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const;
  virtual NABoolean isPhysical() const;

  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // method to do code generation
  virtual RelExpr *preCodeGen(Generator * generator,
                              const ValueIdSet & externalInputs,
                              ValueIdSet &pulledNewInputs);
  virtual short codeGen(Generator *);

  // get a printable string that identifies the operator
  const NAString getText() const;

private:

};

class HbaseUpdate : public UpdateCursor
{
public:
  HbaseUpdate(CorrName &corrName,
	      RelExpr *child = NULL,
	      CollHeap *oHeap = CmpCommon::statementHeap());

  HbaseUpdate(CorrName &corrName,
	      TableDesc *tableDesc,
	      CollHeap *oHeap = CmpCommon::statementHeap());
 
 HbaseUpdate(CollHeap *oHeap = CmpCommon::statementHeap());
  
  virtual ~HbaseUpdate();

  virtual RelExpr *bindNode(BindWA *bindWAPtr);

  // The set of values that I can potentially produce as output.
  virtual void getPotentialOutputValues(ValueIdSet &vs) const;

  // acessors
  //! getVirtualTableName method
  //  returns a const char pointer to the name of the virtual Table
  // should return a CorrName?##
  virtual const char *getVirtualTableName()
  {
    return corrName_.getQualifiedNameObj().getObjectName().data();
  }

  virtual const CorrName &getCorrName() { return corrName_;}

  // get the degree of this node (it is a leaf op).
  virtual Int32 getArity() const;

  virtual NABoolean isLogical() const { return FALSE; };
  virtual NABoolean isPhysical() const { return TRUE; };

  //! preCodeGen method 
  //  method to do preCode generation
  virtual RelExpr * preCodeGen(Generator * generator,
                               const ValueIdSet & externalInputs,
                               ValueIdSet &pulledNewInputs);

  //! codeGen method
  // virtual method used by the generator to generate the node
  virtual short codeGen(Generator*);

  //! copyTopNode
  //  used to create an Almost complete copy of the node
  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
                                CollHeap* outHeap = 0);

  //! synthPhysicalProperty
  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32     planNumber,
                                                  PlanWorkSpace  *pws);

  virtual CostMethod * costMethod() const;

  //! getText method
  //  used to display the name of the node.
  virtual const NAString getText() const;

  NAList<HbaseSearchKey*>& getHbaseSearchKeys() { return listOfSearchKeys_; };
  void addSearchKey(HbaseSearchKey* sk)
    { listOfSearchKeys_.insertAt(listOfSearchKeys_.entries(), sk); };


 ExplainTuple *
   addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
                                    ComTdb * tdb,
                                    Generator *generator);


 protected:

  ListOfUniqueRows listOfUpdUniqueRows_;
  ListOfRangeRows  listOfUpdSubsetRows_;

  CorrName corrName_;

  // The search keys built during optimization.
  NAList<HbaseSearchKey*> listOfSearchKeys_;

  // set of columns that need to be retrieved from hbase. These are used
  // in executor preds, update/merge expressions or returned back as output
  // values.
  ValueIdSet retColRefSet_;

}; // class HbaseUpdate

// -----------------------------------------------------------------------
// delete with a cursor
// -----------------------------------------------------------------------
class DeleteCursor : public Delete
{
public:

  DeleteCursor(const CorrName &name,
               TableDesc *tabId,
               OperatorTypeEnum otype = REL_DELETE_CURSOR,
               RelExpr *child = NULL,
               CollHeap *oHeap = CmpCommon::statementHeap())
    : Delete(name,tabId,otype,child,NULL,NULL,NULL,oHeap) {}

  // copy ctor
  DeleteCursor (const DeleteCursor &) ; // not written

  // virtual destructor
  virtual ~DeleteCursor();

  virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
			       CollHeap *outHeap = CmpCommon::statementHeap());

  virtual NABoolean isLogical() const;
  virtual NABoolean isPhysical() const;

  // cost functions
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // method to do code generation
  virtual short codeGen(Generator *);

  // get a printable string that identifies the operator
  const NAString getText() const;

private:

};

#endif /* RELUPDATE_H */
