/**********************************************************************
// @@@ 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 @@@
**********************************************************************/
/* -*-C++-*-
******************************************************************************
*
* File:         Inlining.cpp
* Description:  Methods for the inlining of triggers.
*
* Created:      6/23/98
* Language:     C++
* Status:       $State: Exp $
*
*/ 

#define INITIALIZE_OLD_AND_NEW_NAMES  // used in Triggers.h
#define  SQLPARSERGLOBALS_FLAGS	   // must precede all #include's
#define  SQLPARSERGLOBALS_CONTEXT_AND_DIAGS

#include "Sqlcomp.h"
#include "AllItemExpr.h"
#include "AllRelExpr.h"
#include "BindWA.h"
#include "GroupAttr.h"
#include "parser.h"
#include "StmtNode.h"
#include "Inlining.h"
#include "ex_error.h"
#include "Triggers.h"
#include "TriggerDB.h"
#include "TriggerEnable.h"
#include "StmtDDLCreateTrigger.h"
#include "MVInfo.h"
#include "Refresh.h"
#include "ChangesTable.h"
#include "MvRefreshBuilder.h"
#include "MjvBuilder.h"
#include "ItmFlowControlFunction.h"
#include <CmpMain.h>
#include "RelSequence.h"

#ifdef NA_DEBUG_GUI
	#include "ComSqlcmpdbg.h"
#endif

#include "SqlParserGlobals.h"		// must be last #include

#define DISABLE_TRIGGERS 0
#define DISABLE_RI       0

extern THREAD_P NABoolean GU_DEBUG;

static const char NEWTable [] = "NEW";    // QSTUFF:  corr for embedded d/u
static const char OLDTable [] = "OLD";    // QSTUFF:  corr for embedded d/u

/*******************************************************************************
****  Independant Utility Functions
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// Create a CorrName to the temp table from the subject table name.
//////////////////////////////////////////////////////////////////////////////
/*static CorrName *calcTempTableName(const CorrName &theTable, CollHeap *heap) 
{
  const QualifiedName &tableName = theTable.getQualifiedNameObj();

  CorrName *result = new(heap) 
    CorrName(subjectNameToTrigTemp(tableName.getObjectName()),
	     heap,
	     tableName.getSchemaName(),
	     tableName.getCatalogName());

  // Specify the trigger temporary table namespace.
  result->setSpecialType(ExtendedQualName::TRIGTEMP_TABLE); 
  return result;
}

//////////////////////////////////////////////////////////////////////////////
// Does this column name start with NEW_COLUMN_PREFIX?
//////////////////////////////////////////////////////////////////////////////
static NABoolean isNewCol(const NAString& colName)
{
  if (colName.length() < sizeof(NEW_COLUMN_PREFIX))
    return FALSE;
  
  return (colName(0,sizeof(NEW_COLUMN_PREFIX)-1) == NEW_COLUMN_PREFIX);
}

//////////////////////////////////////////////////////////////////////////////
// Does this column name start with OLD_COLUMN_PREFIX?
//////////////////////////////////////////////////////////////////////////////
static NABoolean isOldCol(const NAString& colName) 
{
  if (colName.length() < sizeof(OLD_COLUMN_PREFIX))
    return FALSE;

  return (colName(0,sizeof(OLD_COLUMN_PREFIX)-1) == OLD_COLUMN_PREFIX);
}

//////////////////////////////////////////////////////////////////////////////
// Remove the temp table column name prefix.
//////////////////////////////////////////////////////////////////////////////
static void FixTempColName(NAString *colName)
{
  CMPASSERT (sizeof(OLD_COLUMN_PREFIX) == sizeof(NEW_COLUMN_PREFIX));

  colName->remove(0,sizeof(OLD_COLUMN_PREFIX)-1); // remove the prefix
} 

//////////////////////////////////////////////////////////////////////////////
// Does this column name from the temp table contain the @ sign? 
// If so  - it must be either a NEW@ or an OLD@ column.
// If not - it must be part of either the primary or clustering keys.
//////////////////////////////////////////////////////////////////////////////
static NABoolean isSingleCopyColumn(const NAString& colName)
{
  return !colName.contains(NON_SQL_TEXT_CHAR);
}*/

//////////////////////////////////////////////////////////////////////////////
// Utility function used by the fixTentativeRETDesc() method below.
// Creates a Cast ItemExpr around the parameter, so it stays the same but
// gets a new ValueId.
//////////////////////////////////////////////////////////////////////////////
static ValueId wrapWithCastExpr(BindWA *bindWA, ValueId col, CollHeap *heap)
{
  ItemExpr *expr = col.getItemExpr(); 
  ItemExpr *cast = new(heap) Cast(expr, col.getType().newCopy(heap));
  cast->bindNode(bindWA);
  return cast->getValueId();
}
    
/*****************************************************************************
******************************************************************************
****  Inlining functions of classes other than GenericUpdate
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// Is this CorrName using a name of a trigger transition table (from the
// REFERENCING clause)?
// Find if we are in the scope of a trigger action, and if the names match.
// onlyNew has a default value of FALSE, which is overridden only for DDL 
// semantic checks of before triggers.
//////////////////////////////////////////////////////////////////////////////
NABoolean CorrName::isATriggerTransitionName(BindWA *bindWA, NABoolean onlyNew) const
{
  BindScope *scope = bindWA->findNextScopeWithTriggerInfo();

  if ((scope==NULL) || (scope->context()->triggerObj() == NULL))
    return FALSE;

  const NAString& objName = getQualifiedNameObj().getObjectName();
  if (onlyNew)
    return scope->context()->triggerObj()->isNewTransitionName(objName);
  else
    return scope->context()->triggerObj()->isTransitionName(objName);
}

//////////////////////////////////////////////////////////////////////////////
// This is a Scan on a temp table inside the action of a statement trigger.
// Add the uniqifier WHERE expression for it.
// Put a RelRoot node with a select list on top of it, to select only the 
// needed columns. Above the RelRoot, put a RenameTable node to change the
// scanned temp-table to the corrlation name used in the trigger action.
//////////////////////////////////////////////////////////////////////////////
RelExpr *Scan::buildTriggerTransitionTableView(BindWA *bindWA)
{
  BindScope *scope = bindWA->findNextScopeWithTriggerInfo();

  CMPASSERT((scope!=NULL) && (scope->context()->triggerObj() != NULL));

  StmtDDLCreateTrigger *createTriggerNode = 
    scope->context()->triggerObj();

  if (!createTriggerNode->isStatement())
  {
    // 11019 Only statement triggers can select from the transition table.
    *CmpCommon::diags() << DgSqlCode(-11019);
    bindWA->setErrStatus();
    return this;
  }

  // The transition table name must not have catalog/schema.
  QualifiedName& objName = userTableName_.getQualifiedNameObj();
  if  (objName.getSchemaName() != "")
  {
    // *** 4057 Correlation name MYNEW conflicts with qualified identifier of table CAT.SCHM.MYNEW.
    *CmpCommon::diags() << DgSqlCode(-4057)
	<< DgString0(objName.getObjectName())
	<< DgTableName(objName.getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
    return this;
  }

  if (bindWA->inDDL())
  {
    // This bind is for DDL semantic checks during a CREATE TRIGGER statement.
    // When the first trigger is created, the temp table does not yet exist,
    // so we replace the scan on the temp table by a scan on the subject
    // table. This is actually simpler since the column names stay the same.

    // Set the name of the table to be scanned to be the fully qualified 
    // subject table.
    if (userTableName_.getCorrNameAsString() == "")
      userTableName_.setCorrName(objName.getObjectName());
    objName = createTriggerNode->getTableNameObject();

    // Don't fix the name in the LocList.
    userTableName_.getQualifiedNameObj().setNamePosition(0);

    // Use the RI flag to skip incrementing the NATable reference counter.
    NABoolean inRIFlag = bindWA->getCurrentScope()->context()->inRIConstraint();
    bindWA->getCurrentScope()->context()->inRIConstraint() = TRUE;

    RelExpr *boundNode = bindNode(bindWA);
    if (bindWA->errStatus()) 
      return this;

    // Remove the SYSKEY column from the current RETDesc. It is illegal 
    // for a trigger action to select the SYSKEY from the transition table.
    ColRefName syskeyName("SYSKEY");
    bindWA->getCurrentScope()->getRETDesc()->delColumn(bindWA, syskeyName, SYSTEM_COLUMN);	

    // Restore the previous BindWA state.
    bindWA->getCurrentScope()->context()->inRIConstraint() = inRIFlag;

    return boundNode;
  }
  else
  {
    // OK - this is DML time - build the select list for the root and rename.

    QualifiedName& thisTable = userTableName_.getQualifiedNameObj();

    ChangesTable::RowsType scanType;
    if (createTriggerNode->isOldTransitionName(thisTable.getObjectName()))
    {
      scanType = ChangesTable::DELETED_ROWS;
    }
    else
    {
      CMPASSERT(createTriggerNode->isNewTransitionName(thisTable.getObjectName()));
      scanType = ChangesTable::INSERTED_ROWS;
    }

    CorrName subjectTable = createTriggerNode->getTableNameObject();
    subjectTable.setCorrName(userTableName_.getExposedNameAsString());

    TriggersTempTable tempTableObj(subjectTable, this, scanType, bindWA);

    RelExpr *transformedScan = tempTableObj.transformScan();

    return transformedScan->bindNode(bindWA);    // Bind the result
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method does the insertion of a MVImmediate trigger in order to
// refresh the specified ON STATEMENT MJV after an insert operation.
//
// The refresh action is by default implemented as a statement after trigger.
// This implies that the trigger is always driven by a scan from the
// temp-table. The overhead of inserting into the temp-table, scanning it, and
// deleting from it afterwards is relatively high when the number of rows is
// quite small. So, when the insert is driven by a Tuple or TupleList node
// (with up to a certain number of tuples in it), we implement the refresh
// action as a row after trigger, and thus avoid using the temp-table at whole.
// When before triggers exist we don't consider the optimization, since the
// values in the Tuple (TupleList) are not the actual values inserted into the
// table (they are modified by the before trigger).
// 
//////////////////////////////////////////////////////////////////////////////
void Insert::insertMvToTriggerList(BeforeAndAfterTriggers *list,
				   BindWA                 *bindWA,
				   CollHeap               *heap,
				   const QualifiedName    &mvName,
				   MVInfoForDML           *mvInfo,
				   const QualifiedName    &subjectTable,
				   UpdateColumns          *updatedCols)
{
  CMPASSERT(getOperatorType() == REL_UNARY_INSERT);

  CorrName mvCorrName(mvName, heap);
  // The namespace is set in order to allow special update directly on the MV
  mvCorrName.setSpecialType(ExtendedQualName::MV_TABLE);

  // Instansiate the apprpriate builder
  MjvImmInsertBuilder *triggerBuilder = new(heap)
    MjvImmInsertBuilder(mvCorrName, mvInfo, this, bindWA);

  // By default, the refresh is implemented as an after statement trigger
  ComGranularity granularity = COM_STATEMENT;

  // If MV_AS_ROW_TRIGGER default value is ON or if we deal with insert of only
  // 1 row (i.e. the child is REL_TUPLE), generate the optimized refresh tree,
  // in which case the refresh is implemented as a row after trigger.
  if (child(0)->getOperatorType() == REL_TUPLE ||
      CmpCommon::getDefault(MV_AS_ROW_TRIGGER) == DF_ON)
  {
    // build the optimized version of the tree as requested
    granularity = COM_ROW;
    triggerBuilder->optimizeForFewRows();
  }

  // Instansiate the MVImmediate trigger
  MVImmediate *mvTrigger = new(heap) MVImmediate(bindWA,
						 triggerBuilder,
						 mvName,
						 subjectTable,
						 COM_INSERT,
						 granularity,
						 updatedCols);

  // Register the trigger in the general list of triggers

  if (granularity == COM_STATEMENT)
  {
    list->addNewAfterStatementTrigger(mvTrigger);
  }
  else
  {
    list->addNewAfterRowTrigger(mvTrigger);
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method does the insertion of a MVImmediate trigger in order to
// refresh the specified ON STATEMENT MJV after an update operation.
//
// The update operation may be one of two types:
//
// 1. NONE of the updated columns participate in the clustering index of
//    the table and/or join predicate of the MJV. This is called direct update.
// 2. Some of the above columns are updated. This is called indirect update.
//
//    For direct update, a single row trigger that directly updates the
//    appropriate columns is sufficient to refresh the MJV.
//
//    For indirect update, we should have two MVImmediate triggers defined:
// 1) a row after trigger that deletes each row in the MJV that corresponds to
//    the updated ones.
// 2) a statement after trigger that inserts all the rows that result from
//    applying the join expression of the MJV between the delta on the subject
//    table (the updated rows sotred in the temp-table) and the other tables
//    participating in the MJV (the ones that were not changed).
//
//////////////////////////////////////////////////////////////////////////////
void Update::insertMvToTriggerList(BeforeAndAfterTriggers *list,
				   BindWA                 *bindWA,
				   CollHeap               *heap,
				   const QualifiedName    &mvName,
				   MVInfoForDML           *mvInfo,
				   const QualifiedName    &subjectTable,
				   UpdateColumns          *updatedCols)
{
  CMPASSERT(getOperatorType() == REL_UNARY_UPDATE);

  CorrName mvCorrName(mvName, heap);
  // The namespace is set in order to allow special update directly on the MV
  mvCorrName.setSpecialType(ExtendedQualName::MV_TABLE);

  switch(checkUpdateType(mvInfo, subjectTable, updatedCols))
  {
  case DIRECT:
    {
    /////////////////////////////////////////////////////////
    // adding a row trigger to directly update rows in the MV
    /////////////////////////////////////////////////////////

    // Instansiate the apprpriate builder
    MvRefreshBuilder *triggerBuilder = new(heap)
      MjvImmDirectUpdateBuilder(mvCorrName, mvInfo, this, bindWA);

    // Instansiate the MVImmediate trigger
    MVImmediate *mvTrigger = new(heap) MVImmediate(bindWA,
						   triggerBuilder,
						   mvName,
						   subjectTable,
						   COM_UPDATE,
						   COM_ROW,
						   updatedCols);

    // Register the trigger in the general list of triggers
    list->addNewAfterRowTrigger(mvTrigger);
    break;
    }
  case INDIRECT:
    {
    ///////////////////////////////////////////////////////////////////
    // PART I: adding a row trigger to delete updated rows from the MJV
    ///////////////////////////////////////////////////////////////////

    // Instansiate the apprpriate builder
    MvRefreshBuilder *rowTriggerBuilder = new(heap)
      MjvImmDeleteBuilder(mvCorrName, mvInfo, this, bindWA);

    // Instansiate the MVImmediate trigger
    MVImmediate *mvRowTrigger = new(heap) MVImmediate(bindWA,
						      rowTriggerBuilder,
						      mvName,
						      subjectTable,
						      COM_DELETE,
						      COM_ROW,
						      updatedCols);

    // Register the trigger in the general list of triggers
    list->addNewAfterRowTrigger(mvRowTrigger);

    //////////////////////////////////////////////////////////////////////////
    // PART II: adding a statement trigger to insert the new rows into the MJV
    //////////////////////////////////////////////////////////////////////////

    // Instansiate the apprpriate builder
    MvRefreshBuilder *stmtTriggerBuilder = new(heap)
      MjvImmInsertBuilder(mvCorrName, mvInfo, this, bindWA);

    // Instansiate the MVImmediate trigger
    MVImmediate *mvStmtTrigger = new(heap) MVImmediate(bindWA,
						       stmtTriggerBuilder,
						       mvName,
						       subjectTable,
						       COM_INSERT,
						       COM_STATEMENT,
						       updatedCols);

    // Register the trigger in the general list of triggers
    list->addNewAfterStatementTrigger(mvStmtTrigger);
    break;
    }
  default:
    break; // update is IRELEVANT - nothing to do
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method checks which type of update is it:
// IRELEVANT, DIRECT or INDIRECT.
// 
// An update is considered as IRELEVANT until proven otherwise. The list of
// columns of the subject table that are in use by the MJV is scanned. For
// each column we check if it is updated in the current update operation. If
// so, the update is not IRELEVANT anymore, and is considered DIRECT until
// proven otherwise. Once we find an indirect-update column that is updated
// in the current operation, the update is considered INDIRECT and the loop
// is stopped at once. MJV columns of type complex cause INDIRECT update also.
//
//////////////////////////////////////////////////////////////////////////////
Update::MvUpdateType Update::checkUpdateType(MVInfoForDML *mvInfo,
					     const QualifiedName &subjectTable,
					     UpdateColumns *updatedCols) const
{
  MvUpdateType updateType = IRELEVANT;
  mvInfo->initUsedObjectsHash(); // initialization for the searching
  const MVUsedObjectInfo *mvUseInfo = mvInfo->findUsedInfoForTable(subjectTable);
  const LIST (Lng32) &colsUsedByMv = mvUseInfo->getUsedColumnList();
  for (CollIndex i = 0; i < colsUsedByMv.entries(); i++ )
  {
    // Check whether the column was updated in the current update operation.
    // If so, this update is not IRELEVANT anymore. Otherwise, skip this column.
    if (updatedCols->contains(colsUsedByMv[i]))
    {
      updateType = DIRECT;
    }
    else
    {
      continue;
    }

    // Check whether the column is an indirect-update column in the MJV, which
    // means that updating it may not only affect the corresponding row in the
    // MJV, but also affect other rows in it.
    if (mvUseInfo->isIndirectUpdateCol(colsUsedByMv[i]))
    {
      updateType = INDIRECT;
      break; // no further search is needed
    }
  }

  return updateType;
}

//////////////////////////////////////////////////////////////////////////////
// This method does the insertion of a MVImmediate trigger in order to
// refresh the specified ON STATEMENT MJV after a delete operation.
//
// The refresh action is implemented as a row after trigger.
//
//////////////////////////////////////////////////////////////////////////////
void Delete::insertMvToTriggerList(BeforeAndAfterTriggers *list,
				   BindWA                 *bindWA,
				   CollHeap               *heap,
				   const QualifiedName    &mvName,
				   MVInfoForDML           *mvInfo,
				   const QualifiedName    &subjectTable,
				   UpdateColumns          *updatedCols)
{
  CMPASSERT(getOperatorType() == REL_UNARY_DELETE);

  CorrName mvCorrName(mvName, heap);
  // The namespace is set in order to allow special update directly on the MV
  mvCorrName.setSpecialType(ExtendedQualName::MV_TABLE);

  // Instansiate the apprpriate builder
  MvRefreshBuilder *triggerBuilder = new(heap)
    MjvImmDeleteBuilder(mvCorrName, mvInfo, this, bindWA);

  // Instansiate the MVImmediate trigger
  MVImmediate *mvTrigger = new(heap) MVImmediate(bindWA,
						 triggerBuilder,
						 mvName,
						 subjectTable,
						 COM_DELETE,
						 COM_ROW,
						 updatedCols);

  // Register the trigger in the general list of triggers
  list->addNewAfterRowTrigger(mvTrigger);
}

/*****************************************************************************
******************************************************************************
****  Inlining methods of the GenericUpdate class
******************************************************************************
*****************************************************************************/

// This method was originaly called 
// setRETDescForTSJTree().
//
// For GenericUpdate Referential Integrity, Index Maintenance and Triggers
// (for IM, compare the createIM*() functions).
//
// Note that, if a RETDesc needs to be created, correlation names of
// "OLD@" and/or "NEW@" are given to the tables and columns.
// These names are safe to use because they contain a special non-Ansi
// character (the "@"), which is only accepted by Parser if a special
// "internal-only" flag is set as described for RI below.
//
// (Without the "@", the names "OLD" and "NEW" would NOT be safe to use:
// although they are in ReservedWords.h's PotentialAnsiReservedWords list,
// RI and IM could have a name collision ambiguity or misbinding due to a
// user table or index named "OLD" or "NEW" as a *delimited identifier*.
// Note also that since RI does need to use the Parser, we can't use
// CorrName::isFabricated()...)
//
// This function always sets gu's RETDesc to *non-empty*, signifying that
// this GenericUpdate produces outputs.  This RETDesc is also context
// for our being called multiple times.
//
// Concatenate **internal** correlation names (used by Binder)
// and **external** Ansi delimited-identifier names (used by Parser only).
//
// RI will use the latter set of names when building parseable predicate text;
// i.e. it should pass them to RefConstraint::getPredicateText().
//

RETDesc *GenericUpdate::createOldAndNewCorrelationNames(BindWA *bindWA, NABoolean createRETDescOnly)
{
  CMPASSERT(getOperatorType() == REL_UNARY_INSERT ||
            getOperatorType() == REL_UNARY_UPDATE ||
	    getOperatorType() == REL_UNARY_DELETE);

  CMPASSERT(getRETDesc());
  CMPASSERT(getRETDesc()->isEmpty());	

  RETDesc *rd;

  if (getOperatorType() != REL_UNARY_DELETE) 
  {
    // INSERT or UPDATE --
    // GenericUpdate::bindNode has previously set its TableDesc to the
    // desc whose column valueid's represent the new/source/after values.
    // Put these into a new RETDesc with columns all named "NEW@.<colname>"
    //
    CorrName corrName(getTableDesc()->getCorrNameObj().getQualifiedNameObj(),
	bindWA->wHeap(),
	NEWCorr);
    rd = new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc(), &corrName);

    // IM: Add all columns in rd as local reference to current scope.
    // This is needed if the current scope describes a view which selects
    // a proper subset of all the basetable columns -- here we say that
    // yes, this view can produce *all* the b.t.cols as outputs...
    //
    ValueIdList vidList;
    rd->getValueIdList(vidList,  USER_AND_SYSTEM_COLUMNS);
    for (CollIndex i = 0; i < vidList.entries(); i++)
      bindWA->getCurrentScope()->addLocalRef(vidList[i]);

    // ##IM:## Having done the above for local refs, oughtn't we also now
    // ##recompute inputs?
    // ##  bindWA->getCurrentScope()->mergeOuterRefs(bindWA->getCurrentScope()->getOuterRefs());
    // ##  gu->getGroupAttr()->addCharacteristicInputs(bindWA->getCurrentScope()->getOuterRefs());
  }
  else
  {
    // DELETE -- init an empty RETDesc, and next merge in "OLD@.<col>"'s
    rd = new (bindWA->wHeap()) RETDesc(bindWA);
  }

  
  if ((getOperatorType() != REL_UNARY_INSERT) || 
      getUpdateCKorUniqueIndexKey() ||
      ((getOperatorType() == REL_UNARY_INSERT) &&((Insert *)this)->isMerge()) ||
      ((getOperatorType() == REL_UNARY_INSERT) &&((Insert *)this)->xformedEffUpsert()))
  {
    // DELETE or UPDATE --
    // Now merge the old/target/before valueid's (the Scan child RETDesc)
    // into this RETDesc such that these cols are all named "OLD@.<col>"
    //
    Scan *scan ;
    if (getOperatorType() != REL_UNARY_INSERT)
      scan = getScanNode();
    else 
      scan = getLeftmostScanNode();
   
    if ((getOperatorType() == REL_UNARY_INSERT) &&((Insert *)this)->xformedEffUpsert())
      {
	RelSequence *olapChild = getOlapChild();
	CorrName corrName(getTableDesc()->getCorrNameObj().getQualifiedNameObj(), 
			  bindWA->wHeap(),
			  OLDCorr);

	for (short i = 0; i< olapChild->getRETDesc()->getDegree();i++)
	  {
	    // we remembered if the original columns was from the right side of
	    // this olap node so add those to the RetDesc since those are the 
	    //ones we want to delete from the dependent indexes.
	    if ((olapChild->getRETDesc()->getValueId(i)).getItemExpr()->origOpType() == ITM_INSTANTIATE_NULL)
	      {		    
		rd->addColumn(bindWA, 
			      ColRefName(olapChild->getRETDesc()->getColRefNameObj(i).getColName(), corrName),
			      olapChild->getRETDesc()->getValueId(i),
			      USER_COLUMN,
			      olapChild->getRETDesc()->getHeading(i));
		    
	      }	    
	  }
	rd->addColumns(bindWA, *olapChild->getRETDesc()->getSystemColumnList(),  SYSTEM_COLUMN,&corrName);
	

      }	
    
    else
      {
	CMPASSERT(scan);
	CorrName corrName(scan->getTableDesc()->getCorrNameObj().getQualifiedNameObj(), 
			  bindWA->wHeap(),
			  OLDCorr);

	rd->addColumns(bindWA, *scan->getRETDesc(), &corrName);
      }
  }
   

  Set_SqlParser_Flags(ALLOW_FUNNY_IDENTIFIER);	// allow "@" processing
  Set_SqlParser_Flags(DELAYED_RESET); // allow multiple parser calls.

  CMPASSERT(!rd->isEmpty());

  // we only need the RETDesc to use it later for the transformation. Don't change the
  // RETDesc of the current operator or the current bind scope.
  if (!createRETDescOnly)
  {
    delete getRETDesc();			// safe because empty
    setRETDesc(rd);
    bindWA->getCurrentScope()->setRETDesc(rd);
  }

  return rd;

} // GenericUpdate::createOldAndNewCorrelationNames()

//////////////////////////////////////////////////////////////////////////////
// Add a virtual column to the RETDesc of this GenericUpdate node.
// Currently used for the Unique Execute ID column (before triggers),
// and for MV logging: the current Epoch, row type and row count.
//////////////////////////////////////////////////////////////////////////////
ValueId GenericUpdate::addVirtualColumn(BindWA     *bindWA, 
				        ItemExpr   *colExpr, 
				        const char *colName,
				        CollHeap   *heap)
{
  RETDesc *retDesc = getRETDesc();

  colExpr->bindNode(bindWA);
  ValueId exprValueId = wrapWithCastExpr(bindWA, colExpr->getValueId(), heap);
  ColRefName virtualColName(colName);
  retDesc->addColumn(bindWA, virtualColName, exprValueId);
  return exprValueId;
}

//////////////////////////////////////////////////////////////////////////////
// Inline the temp insert sub-tree directly into the backbone.
// The resulting tree looks like this:
//          TSJ
//         /  \
//   topNode   RelRoot
//               |
//             LeafInsert
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineTempInsert(RelExpr  *topNode, 
					 BindWA   *bindWA, 
					 TriggersTempTable& tempTableObj, 
					 NABoolean isDrivenByBeforeTriggers, 
					 NABoolean isTopMostTSJ,
					 CollHeap *heap)
{
  // The new top node should be a left TSJ for after triggers,
  // and a normal TSJ for before triggers.
  OperatorTypeEnum JoinType = 
    (  (isDrivenByBeforeTriggers || isTopMostTSJ)
       ? REL_TSJ
       : REL_LEFT_TSJ);
  
  if (isDrivenByBeforeTriggers)
    tempTableObj.setBeforeTriggersExist();

  RelExpr *insertNode = tempTableObj.buildInsert(!isDrivenByBeforeTriggers);
  if (bindWA->errStatus()) 
    return NULL;

  RelRoot *rootNode = new (heap) RelRoot(insertNode);
  rootNode->setRootFlag(FALSE);
  rootNode->setEmptySelectList();

  topNode = new(heap) Join(topNode, rootNode, JoinType);
  topNode->getInliningInfo().setFlags(II_DrivingTempInsert | 
                                      II_SingleExecutionForTriggersTSJ |
				      II_AccessSetNeeded);
  // Indicate to the Normalizer that this TSJ cannot be optimized away,
  // and that if the write operation is implemented via a cursor then 
  // it cannot be a "flow" cursor operation - i.e. it cannot utilize
  // a TSJFlow node.
  // Genesis case #10-990116-7164
  ((Join *)topNode)->setTSJForWrite(TRUE);
  if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError())
    {
      ((Join *)topNode)->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      ((Join *)topNode)->setTSJForSetNFError(TRUE);
    }
  return topNode;
}

//////////////////////////////////////////////////////////////////////////////
// Do we need Index Maintenance on this GenericUpdate node?
// We do if there are indexes except the clustering index. In case this is 
// an Update, at least one such index must match ant of the columns actually 
// being updated.
//////////////////////////////////////////////////////////////////////////////
NABoolean GenericUpdate::isIMNeeded(UpdateColumns *updatedColumns)
{
  NABoolean imNeeded = FALSE;

  if (!getTableDesc()->hasSecondaryIndexes()) 
    return FALSE;

  const LIST(IndexDesc *) indexList = getTableDesc()->getIndexes();
  for (CollIndex i=0; (i<indexList.entries()) && !imNeeded; i++) 
  {
    IndexDesc *index = indexList[i];

    // The base table itself is an index (the clustering index);
    // obviously IM need not deal with it.
    if (index->isClusteringIndex())
      continue;
 
    // An index always needs maintenance on an Insert or Delete...
    if((getOperatorType() != REL_UNARY_UPDATE) ||
       (isMerge()))
      imNeeded = TRUE;
    else
    {
      // This is Update - check if columns match.
      CMPASSERT(updatedColumns!=NULL);
      const ValueIdList &indexColumns = index->getIndexColumns();
      for (CollIndex j=0; j < indexColumns.entries() && !imNeeded; j++)
      {
	Lng32 indexCol = indexColumns[j].getNAColumn()->getPosition();
	if (updatedColumns->contains(indexCol))
	{
	  imNeeded = TRUE;
	  break;
	}
      } // for k
    } // else
  } // for j

  return imNeeded;
}

//////////////////////////////////////////////////////////////////////////////
// Inline Index Maintainance.
// We get here only if isIMNeeded() returned TRUE.
// The result looks like this:
//          TSJ
//         /   \
//   topNode    IM
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineIM(RelExpr   *topNode, 
				 BindWA    *bindWA, 
				 NABoolean isLastTSJ,
				 UpdateColumns *updatedColumns,
				 CollHeap  *heap,
				 NABoolean useInternalSyskey,
				 NABoolean rowTriggersPresents)
{
  // Create the tree that handles Index Maintainance.
  RelExpr *imTree = createIMTree(bindWA, updatedColumns, useInternalSyskey);

  // If no IM tree was created than we have a bug!
  CMPASSERT(imTree != NULL);

  if (bindWA->isTrafLoadPrep())
    return imTree;

  // Drive IM and RI trees using a TSJ on top of the GenericUpdate node.
  topNode = new(bindWA->wHeap()) 
    Join(topNode, 
	 imTree, 
	 (isLastTSJ ? REL_TSJ : REL_LEFT_TSJ));
  topNode->getInliningInfo().setFlags(II_DrivingIM | II_AccessSetNeeded);
  if (rowTriggersPresents)
     topNode->getInliningInfo().setFlags(II_SingleExecutionForTriggersTSJ);
  // Indicate to the Normalizer that this TSJ cannot be optimized away,
  // and that if the write operation is implemented via a cursor then 
  // it cannot be a "flow" cursor operation - i.e. it cannot utilize
  // a TSJFlow node.
  // Genesis case #10-990116-7164
  ((Join *)topNode)->setTSJForWrite(TRUE);

  return topNode;
}

//////////////////////////////////////////////////////////////////////////////
// Add to a trigger WHEN clause, the check if the trigger is enabled.
// Result condition ItemExpr tree looks like this:
//
//                           AND
//                          /   \
//              GetBitValueAt    WHEN clause
//	             /         \
// GetTriggerStatus       TriggerIndex
//
//////////////////////////////////////////////////////////////////////////////
static ItemExpr *addCheckForTriggerEnabled(BindWA    *bindWA,
					   ItemExpr  *whenClause, 
					   Trigger   *triggerObj,
					   CollHeap  *heap)
{
  // Register the trigger timestamp in the list managed by bindWA. The
  // returned value is the index into the trigger array for this RelExpr
  CollIndex triggerIndex = bindWA->addTrigger(triggerObj->getTimeStamp());

  CollIndex MaxTriggersPerStatement = MAX_TRIGGERS_PER_STATEMENT;
  
// debugging for coverage
#ifndef NDEBUG
  char* env = getenv("TESTING_MAX_TRIGGERS_PER_STATEMENT");
  if (env)
  {
     MaxTriggersPerStatement = atol(env);
  }
#endif

  if (triggerIndex >= MaxTriggersPerStatement)
  {
    // There are more than 256 triggers in this statement
    *CmpCommon::diags() << DgSqlCode(-11001);
    bindWA->setErrStatus();
    return NULL;
  }

  ItemExpr *enableCheck = new(heap) 
    GetBitValueAt(new(heap) GetTriggersStatus(), 
		  new(heap) ConstValue(triggerIndex) );

  // Check if whenClause is empty or TRUE
  if (whenClause == NULL || whenClause->getOperatorType() == ITM_RETURN_TRUE)
    return enableCheck;
  else {

    /*
    * for proper typing and transformation use correct AND subtree as follows:
    * (AND (AND (NOT_NULL GBVA) (NOT_EQUALS GBVA 0)) whenClause)
    * Here enableCheck is GBVA (GetBitValueAt) 
    */

    ItemExpr *notNullNode = new(heap) UnLogic (ITM_IS_NOT_NULL, enableCheck);
    
    ItemExpr *constZeroNode = new(heap) ConstValue(0);
    
    ItemExpr *notZeroNode = new(heap) BiRelat(ITM_NOT_EQUAL, enableCheck, constZeroNode);

    enableCheck = new(heap) BiLogic(ITM_AND, notNullNode, notZeroNode);
    
    return new(heap) BiLogic(ITM_AND, enableCheck, whenClause);
  }
}


// auxiliary function that reutrns an expression that wraps a RaiseError
// built-in function.
static ItemExpr *addTrigActionExcept (Trigger *trigObj, CollHeap *heap)
{
  ItemExpr *trigActionExceptExprPred =
     new (heap) RaiseError(ComDiags_TrigActionExceptionSQLCODE, 
                   trigObj->getTriggerName(),
                   trigObj->getSubjectTableName());
 
  return trigActionExceptExprPred;
}

//////////////////////////////////////////////////////////////////////////////
// This function is only called for row triggers. Look for all update 
// nodes in the action of the trigger and flag them as being in the action
// of a row trigger
//////////////////////////////////////////////////////////////////////////////
static void flagUpdateAsRowTrigger(RelExpr  *topNode)
{
   if (topNode)
   {
      if (topNode->getOperatorType() == REL_UNARY_UPDATE)
      {
         topNode->getInliningInfo().setFlags(II_InActionOfRowTrigger);
      }

      flagUpdateAsRowTrigger((RelExpr *)topNode->child(0));
      flagUpdateAsRowTrigger((RelExpr *)topNode->child(1));
   }
}

//////////////////////////////////////////////////////////////////////////////
// Statement triggers are blocked by an ordered union node, but then 
// driven to execute in parallel, by connecting them using a left linear tree
// of union nodes. Row triggers are similarly attached to each other, but are
// connected to the trigger backbone as part of the "Pipelined actions".
// The result looks like this for three triggers:
// The trigger transformation code expects this trigger group to be 
// in a left linear tree structure.
//
// Statement triggers:        Row triggers:
//          OU
//         /  \
//   topNode   U                   U
//            / \                 / \
//           U   ST3             U   RT3
//          / \                 / \
//        ST1  ST2            RT1  RT2
//////////////////////////////////////////////////////////////////////////////
static RelExpr *inlineTriggerGroup(RelExpr	     *topNode, 
				   const TriggerList *triggers, 
				   NABoolean	     isRow, 
				   CollHeap	     *heap,
				   BindWA	     *bindWA)
{
  RelExpr *topUnion = NULL;

  if ((triggers == NULL) || (triggers->entries() == 0))
    return topNode;

  // Now do the rest, and connect them with Union nodes.
  for (CollIndex i=0; i<triggers->entries(); i++)
  {
    // Get the Trigger object.
    Trigger *current = (*triggers)[i]; 
    // Get the trigger action tree.
    RelExpr *triggerTree = current->getParsedTrigger(bindWA);
    if (bindWA->errStatus())
      return NULL;

    triggerTree->getInliningInfo().setFlags(II_TriggerRoot);
    triggerTree->getInliningInfo().setTriggerObject(current);

    // The check whether the trigger is enabled is applicable only for regular
    // triggers. ON STATEMENT MVs (MVImmediate triggers) are always enabled.
    if ( !(current->isMVImmediate()) )
    {
      Union *triggerRoot = (Union *)triggerTree->getChild(0);  // Get past the RelRoot
      if (isRow)
        triggerRoot = (Union *)triggerRoot->getChild(0); // Get past the RenameReference
      if (triggerRoot != NULL && triggerRoot->getOperatorType() == REL_UNION)
      {
        // mark the update nodes as being in the action of a row trigger
        // so IM can be set appropriately of this case to avoid a data 
        // corruption - refer to method createIMNodes for more info on this issue
        flagUpdateAsRowTrigger((RelExpr *)triggerRoot->getChild(0));
        ItemExpr *whenClause = triggerRoot->removeCondExprTree();
        triggerRoot->addCondExprTree(
	  addCheckForTriggerEnabled(bindWA, whenClause, current, heap));
        triggerRoot->addTrigExceptExprTree(
	  addTrigActionExcept(current, heap));

	// if we are in a not atomic statement, set a flag in the unary_union node
	// this flag will passed to the executor through the union tdb. During execution
	// if condExpr() evaluates to truw and this flag is set, then error -30029 is raised.
	if (bindWA->getHostArraysArea() && 
	      bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
	{
	  triggerRoot->setInNotAtomicStatement();
	}
      }
    }

    if (i == 0) // topUnion is still NULL?
      topUnion = triggerTree;
    else
    {
      topUnion = new(heap) Union(topUnion, triggerTree, NULL, NULL, REL_UNION, 
                                 CmpCommon::statementHeap(), TRUE);

      if (bindWA->getHostArraysArea() && 
        bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
      {
	((Union *)topUnion)->setInNotAtomicStatement();
      }

    }

    topUnion->getInliningInfo().setFlags(II_AccessSetNeeded);

  }

  if (isRow) 
    return topUnion;
  else 
  {
    Union *newOU = new(heap) Union(topNode, topUnion, NULL, NULL, REL_UNION,
                                   CmpCommon::statementHeap(), TRUE);
    newOU->setOrderedUnion();
    newOU->setNoOutputs();
    newOU->getInliningInfo().setFlags(II_DrivingStatementTrigger | 
 				      II_AccessSetNeeded);

    if (bindWA->getHostArraysArea() && 
        bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
      {
	newOU->setInNotAtomicStatement();
      }
    return newOU;
  }
}

//////////////////////////////////////////////////////////////////////////////
// Create a dummy sub-tree as a place-holder for missing pipelined actions
// (RI or row triggers), in order to maintain a regular tree.
// Such dummy statements are later removed by the trigger transformation code.
//////////////////////////////////////////////////////////////////////////////
static RelExpr *createDummyStatement(CollHeap *heap)
{
  Tuple *tupleNode = new(heap) Tuple(new(heap) ConstValue(0));
  tupleNode->getInliningInfo().setFlags(II_DummyStatement);

  RelRoot *result = new RelRoot(tupleNode);
  result->setRootFlag(FALSE);
  result->setEmptySelectList();
  return result;
}


//////////////////////////////////////////////////////////////////////////////
// Inline the pipelined actions: RI and row triggers.
// The root node above the TSJ has an empty select-list, so that the Union
// node above it will accept it as compatible with it's other child. It also
// will not open a new BindScope when bound, so that when the binding will 
// reach the already bound 'this' node - it will be in the same scope. This 
// avoids problems when calculating inputs.
//
// The resulting tree looks like this:
//         RelRoot
//           |
//          TSJ
//         /  \
//   topNode   U
//            / \
//          RI   Row
//               Triggers
////////////////////////////////////////////////////////////////////////////// 
RelExpr *GenericUpdate::inlinePipelinedActions(RelExpr *topNode, 
					       BindWA *bindWA, 
					       TriggerList *rowTriggers, 
					       RefConstraintList *riList,
					       CollHeap *heap)
{
  RelExpr *resultTree=topNode;
  
  if ((rowTriggers != NULL) || (riList != NULL))
  {
    RelExpr *rowTriggersTree=NULL;
    RelExpr *riTree=NULL;
    
    // Create the tree that handles all row triggers
    if (rowTriggers != NULL)
    {
      rowTriggersTree = inlineTriggerGroup(NULL,
					   rowTriggers,
					   TRUE,
					   heap,
					   bindWA);
    }
    else
    {
      rowTriggersTree = createDummyStatement(heap);
    }
    
    // Create the tree that handles Referencial Integrity.
    if (riList != NULL) 
      riTree = inlineRI(bindWA, riList, heap);
    else
      riTree = createDummyStatement(heap);
    
    resultTree = new(heap) Union(riTree, rowTriggersTree, NULL, NULL, 
                                 REL_UNION, CmpCommon::statementHeap(), TRUE);
    resultTree->getInliningInfo().setFlags(II_AccessSetNeeded);
    if (riList!=NULL) 
      resultTree->getInliningInfo().setFlags(II_DrivingRI);
    if (rowTriggers != NULL)
      resultTree->getInliningInfo().setFlags(II_DrivingRowTrigger);
    
    // Put a RelRoot on top of the Union to avoid trashing the current scope.
    resultTree = new(heap) RelRoot(resultTree);
    ((RelRoot *)resultTree)->setRootFlag(FALSE);
    ((RelRoot *)resultTree)->setEmptySelectList();
    
    // Drive IM and RI trees using a TSJ on top of the GenericUpdate node.
    NABoolean needsOutputs = isMtsStatement() ||
      (getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_DELETE));
    OperatorTypeEnum joinType = needsOutputs ? REL_ANTI_SEMITSJ : REL_TSJ;
    resultTree = new(bindWA->wHeap()) Join(topNode, resultTree, joinType);
    resultTree->getInliningInfo().setFlags(II_AccessSetNeeded);
    resultTree->getInliningInfo().setFlags(II_DrivingPipelinedActions);

    // disable parallele execution for TSJs that control row triggers
    // execution. Parallel execution for triggers TSJ introduces the 
    // potential for non-deterministic execution 
    if (rowTriggers)
       resultTree->getInliningInfo().setFlags(II_SingleExecutionForTriggersTSJ);

    // Indicate to the Normalizer that this TSJ cannot be optimized away,
    // and that if the write operation is implemented via a cursor then 
    // it cannot be a "flow" cursor operation - i.e. it cannot utilize
    // a TSJFlow node.
    // Genesis case #10-990116-7164
    ((Join *)resultTree)->setTSJForWrite(TRUE);

  }
  
  RelRoot *rootNode = new(heap) RelRoot(resultTree);
  rootNode->setRootFlag(FALSE);
  rootNode->setEmptySelectList();
  rootNode->setDontOpenNewScope(); 
  
  return rootNode;
} // GenericUpdate::inlinePipelinedActions

//////////////////////////////////////////////////////////////////////////////
// Create the sub-tree that deletes the affected set from the temporary table.
// The corresponding SQL text is 
//    DELETE FROM <temp table> WHERE <Uniquifier> = <Uniquifier value>;
//
// The result looks like this:
//          OU
//         /  \
//   topNode   Delete
//              |
//             Scan (temp table)
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineTempDelete(BindWA   *bindWA, 
					 RelExpr  *topNode, 
					 TriggersTempTable& tempTableObj, 
					 CollHeap *heap)
{
  RelExpr *deleteSubTree = tempTableObj.buildDelete();

  Union   *newOU      = new(heap) Union(topNode, deleteSubTree, NULL, NULL,
                                        REL_UNION,CmpCommon::statementHeap(),
                                        TRUE);
  newOU->setOrderedUnion();
  newOU->getInliningInfo().setFlags(II_DrivingTempDelete | 
				    II_AccessSetNeeded);
  return newOU;
}

/*****************************************************************************
******************************************************************************
****  Methods for handling of before triggers.
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// Find all the NEW@columns in the RETDesc of the GU that is about to be 
// replaced by a "tentative execution" node. These columns point to columns 
// in the IUD TableDesc that will soon be not valid anymore. The names NEW@.*
// should instead reference the appropriate expresions from the new record 
// expression.
//////////////////////////////////////////////////////////////////////////////
void GenericUpdate::fixTentativeRETDesc(BindWA *bindWA, CollHeap *heap)
{
  RETDesc *retDesc = getRETDesc();

  // The name of the subject table should no longer be in the XTNM.
  bindWA->getCurrentScope()->getXTNM()->remove(&getTableName());

  // Create a "virtual column" called @EXECID for the value of the Unique 
  // Execute ID. All the before trigger SIGNAL expressions will be piggy-
  // backed on this "column" before it is inserted into the temp table.
  ItemExpr *execId = new(heap) UniqueExecuteId();
  addVirtualColumn(bindWA, execId, InliningInfo::getExecIdVirtualColName(), heap);

  if (getOperatorType() == REL_UNARY_DELETE)
    return;  // No NEW@ values for Delete.

  CorrName newCorr(NEWCorr);
  ColumnDescList newCols(heap);
  ValueIdArray& newRecordExpr = newRecExprArray();
  ValueId *foundAssignToCol;

  // Get all the NEW@ columns from the GU's RETDesc.
  newCols.insert(*(retDesc->getQualColumnList(newCorr)));

  // The getQualColumnList() call does not return SYSKEY, so if it's there
  // find it and add it to the list.
  NAString    syskeyName("SYSKEY", heap);
  ColRefName  newSyskeyName(syskeyName, newCorr, heap);
  ColumnNameMap *newSyskeyMap = retDesc->findColumn(newSyskeyName);
  if (newSyskeyMap != NULL)
  {
    ColumnDesc *newSyskey = newSyskeyMap->getColumnDesc();
    // Make sure SYSKEY is not already in the list.
    CMPASSERT(!newCols.contains(newSyskey));
    newCols.insert(newSyskey);
  }

  for (CollIndex i=0; i<newCols.entries(); i++) // For each NEW@ column,
  {
    ValueId tempValueId;
    foundAssignToCol = NULL;
    const ColRefName& colName = newCols[i]->getColRefNameObj();

    // Lookup the column name in the target of an Assign node in the 
    // new record expression of the GU.
    for (CollIndex j=0; j<newRecordExpr.entries(); j++)
    {
      ItemExpr *currentExpr = newRecordExpr[j].getItemExpr(); 
      CMPASSERT(currentExpr->getOperatorType() == ITM_ASSIGN);
      Assign *currentAssign = (Assign *)currentExpr;
      
      ItemExpr *target = currentAssign->getTarget().getItemExpr();
      if (target->getOperatorType() == ITM_BASECOLUMN)
      {
	// Do the column names match?
	const NAString& trgtCol = ((BaseColumn *)target)->getColName();
	if (!trgtCol.compareTo(colName.getColName()))
	{
	  // Save the ValueId of the Assign source expression.
	  tempValueId = currentAssign->getSource();
          foundAssignToCol = &tempValueId;
	  // No need to check the rest of the new record expression.
	  break;  
	}
      }
    }  // for each Assign in the newRecExpr

    // Delete the current NEW@.* column from the RETDesc.
    if (colName.getColName() == "SYSKEY")
    {
      retDesc->delColumn(bindWA, colName, SYSTEM_COLUMN);
    }
    else
    {
      retDesc->delColumn(bindWA, colName, USER_COLUMN);
    }
    // it is no longer a local reference in the current scope.
    ValueId colValId = newCols[i]->getValueId();
    bindWA->getCurrentScope()->removeLocalRef(colValId);

    // Did we find a matching Assign expression?
    if (foundAssignToCol != NULL)
    {
      ValueId newExpr = *foundAssignToCol;

      // Yes - Make NEW@.* reference it.
      if (getGroupAttr()->isCharacteristicInput(newExpr))
	newExpr = wrapWithCastExpr(bindWA, newExpr, heap);

      retDesc->addColumn(bindWA, colName, newExpr);
    }
    else
    {
      // No - this must be a column that is not SET into, in an Update node.
      CMPASSERT (getOperatorType() == REL_UNARY_UPDATE);

      // OK - just reference the appropriate OLD@.* value.
      CorrName   oldCorr(OLDCorr);
      ColRefName oldColName(colName.getColName(), oldCorr);
      ValueId    oldCol = retDesc->findColumn(oldColName)->getValueId();

      // Wrap it with a Cast expression to give it a different ValueId
      // than the original OLD@.* column, thus marking it as a
      // duplicate entry in the XCNM.
      retDesc->addColumn(bindWA, colName, wrapWithCastExpr(bindWA, oldCol, heap));
    }
  }  // for each NEW@ column

  // The next block handles the value of the SYSKEY column in the 
  // temporary table for Insert operations. The problem is that the row
  // is inserted into the temp table before it is inserted into the 
  // subject table, and so - before the actual SYSKEY value was 
  // generated for it. Since this column is part of the primary key of
  // the temp table, and the rest of the primary key columns may be 
  // identical, this SYSKEY value must be unique for each row.
  // Solution - give it the value of JulianTimestamp.
  // The Timestamp ItemExpr is a new BuiltInFunction that is evaluated
  // for each row.
  if (getOperatorType() == REL_UNARY_INSERT) 
  {
    // Does this RETDesc have a NEW@.SYSKEY column?
    CorrName   newCorr(NEWCorr);
    ColRefName syskey("SYSKEY", newCorr);
    if (retDesc->findColumn(syskey) != NULL)
    {
      // code added to make sure that the generated julian
      // timestamp is unique. This change is added to support
      // bulk inserts (including rowset inserts) when before
      // row triggers are used.
      ItemExpr* counterExpr, *incrementExpr;
      counterExpr = new (heap) ItmPersistentExpressionVar(0);
      incrementExpr = new (heap) ItmBlockFunction
          (counterExpr, new (heap) Assign (counterExpr,
           new (heap) BiArith(ITM_PLUS, counterExpr,
           new (heap) ConstValue(1))));

      // Synthesize the types and value IDs for the new items
      incrementExpr->synthTypeAndValueId(TRUE);
      
      // Construct a new JulianTimestamp expression
      ItemExpr *fakeSyskey = new (heap) 
        BiArith(ITM_PLUS, incrementExpr, new (heap)
	  JulianTimestamp(new (heap) InternalTimestamp));

      fakeSyskey->bindNode(bindWA);

      // Make NEW@.SYSKEY point to the timestamp expression.
      retDesc->delColumn(bindWA, syskey, SYSTEM_COLUMN);
      retDesc->addColumn(bindWA, syskey, fakeSyskey->getValueId());
    }
  }  // if REL_UNARY_INSERT
}  // End of GenericUpdate::fixTentativeRETDesc()

//////////////////////////////////////////////////////////////////////////////
// For Update nodes, add the predicate: OLD@.<ci> = NEW@.<ci>
//////////////////////////////////////////////////////////////////////////////
void GenericUpdate::addPredicateOnClusteringKey(BindWA   *bindWA, 
						RelExpr  *tentativeNode, 
						CollHeap *heap)
{  
  TableDesc *newTableDesc = getTableDesc();
  const IndexDesc *newCI = newTableDesc->getClusteringIndex();
  const ValueIdList& newCICols = newCI->getIndexKey();
  CorrName newCorrName(NEWCorr);
  CorrName oldCorrName(OLDCorr);

  ItemExpr *predicate = NULL;
  for (CollIndex i=0; i<newCICols.entries(); i++)
  {
    ItemExpr *currentCol = newCICols[i].getItemExpr();
    CMPASSERT(currentCol->getOperatorType() == ITM_INDEXCOLUMN);
    IndexColumn *currentBaseCol = (IndexColumn *) currentCol;
    const NAString& colName = currentBaseCol->getNAColumn()->getColName();

    ColRefName *newColName = new(heap) ColRefName(colName, newCorrName, heap);
    ColRefName *oldColName = new(heap) ColRefName(colName, oldCorrName, heap);

    ItemExpr *currentPredicate = new(heap)
      BiRelat(ITM_EQUAL, 
              new(heap) ColReference(newColName),
              new(heap) ColReference(oldColName));

    if (predicate == NULL)
      predicate = currentPredicate;
    else
      predicate = new(heap) BiLogic(ITM_AND, predicate, currentPredicate);
  }

  CMPASSERT(predicate != NULL);
  predicate->bindNode(bindWA);
  if (bindWA->errStatus()) 
    return;

  tentativeNode->selectionPred().insert(predicate->getValueId());
}

//////////////////////////////////////////////////////////////////////////////
// This method replaces the GenericUpdate node that fired the triggers (this)
// with a "tentative execution" node.
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::createTentativeGU(BindWA *bindWA, CollHeap *heap)
{
  // 'this' is the GU that started the whole mess. Let's kill it!
  // Create a dummy Rename node.
  RelExpr *tentativeNode = new(heap) 
    RenameTable(child(0), "TentativeGU");     
  // Fix the NEW@ cols to point to the right expressions.
  fixTentativeRETDesc(bindWA, heap); 
  // Give it my RETDesc with all the NEW and OLD stuff
  tentativeNode->setRETDesc(getRETDesc());      
  tentativeNode->setGroupAttr(getGroupAttr());

  ColumnNameMap *execIdCol = 
    getRETDesc()->findColumn(InliningInfo::getExecIdVirtualColName());
  CMPASSERT(execIdCol != NULL);

  ValueIdList outputs;
  getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
  outputs.remove(execIdCol->getValueId());
  tentativeNode->getGroupAttr()->addCharacteristicOutputs(outputs);

  // For Update nodes, add the predicate: OLD@.<ci> = NEW@.<ci>s
  if (getOperatorType() == REL_UNARY_UPDATE)
  {
    addPredicateOnClusteringKey(bindWA, tentativeNode, heap);
    if (bindWA->errStatus()) 
      return NULL;
  }

  tentativeNode->markAsBound(); // No more binding is needed here.
  return tentativeNode;
}

//////////////////////////////////////////////////////////////////////////////
// Find the position of all columns SET to by this before Trigger, and add
// them to colToSet. This way, when we call TriggerDB for after triggers we
// will get triggers that fire on these columns too.
//////////////////////////////////////////////////////////////////////////////
void BeforeTrigger::addUpdatedColumns(UpdateColumns *colsToSet, 
				      const NATable *naTable)
{
  if (setList_ == NULL)  // Does this trigger have a SET clause?
    return;

  // For each Assign expression, add the col position to ColsToSet.
  for (CollIndex i=0; i<setList_->entries(); i++)
  {
    Lng32 targetColPosition = getTargetColumn(i, NULL, naTable);
    CMPASSERT(targetColPosition != -1);
    colsToSet->addColumn(targetColPosition);
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method is called only when before triggers exist, and it builds the 
// left side of the inlining tree - the tentative execution tree.
// 1. Create the tentative GU node, that replaces this node.
// 2. Build a totem of before triggers on top of the tentative GU node.
//    Columns updated by before triggers are added to the list of columns
//    updated by the triggering statement, passed in colsToSet.
// 3. Inline the temp insert above the before triggers.
// 4. Add a RelRoot. This root has an empty select-list, so that the Union
//    node above it will accept it as compatible with it's other child. It
//    also will not open a new BindScope when bound, so that when the binding
//    will reach the already bound tentative node - it will be in the same
//    scope. This avoids problems when calculating inputs.
//
// The result looks like this, with 3 before triggers BT1, BT2 and BT3:
// (the triggers are already sorted by timestamp, BT1 is the oldest)
//          RelRoot
//            |
//           TSJ
//          /   \
//       BT3    Temp Insert
//        |
//       BT2
//        |
//       BT1
//        |
//    TentativeGU (replacing this)
//        |
//    this->child(0)
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::createTentativeSubTree(BindWA *bindWA, 
					       TriggerList *beforeTriggers, 
					       UpdateColumns *updatedColumns, 
					       TriggersTempTable& tempTableObj,
					       CollHeap *heap)
{
  const NATable *naTable = getTableDesc()->getNATable();

  // Step 1.
  RelExpr *topNode = createTentativeGU(bindWA, heap);  
  if (bindWA->errStatus()) 
    return NULL;

  // Step 2.
  Trigger *current;
  BeforeTrigger *triggerNode=0;
  for (CollIndex i=0; i<beforeTriggers->entries(); i++)   
  {
    current = (*beforeTriggers)[i];
    triggerNode = (BeforeTrigger *)current->getParsedTrigger(bindWA);
    if (bindWA->errStatus())
      return this;

    CMPASSERT(triggerNode->getOperatorType() == REL_BEFORE_TRIGGER);

    // BeforeTrigger nodes are created childless,
    // And the child is always added before binding it.
    triggerNode->child(0) = topNode;
    topNode = triggerNode;

    if (updatedColumns != NULL) // Is this an UPDATE op?
    {
      // Add columns changed by the trigger to the columns changed
      // by the original UPDATE operation.
      triggerNode->addUpdatedColumns(updatedColumns, naTable);
    }
    ItemExpr *whenClause = triggerNode->getWhenClause();
    whenClause = addCheckForTriggerEnabled(bindWA, whenClause, current, heap);
    triggerNode->setWhenClause(whenClause);
  }

  // Step 3.
  topNode = inlineTempInsert(topNode, bindWA, tempTableObj, TRUE, TRUE, heap);  
  if (bindWA->errStatus()) 
    return NULL;
  // Save a pointer to the TSJ for tansformNod().
  CMPASSERT(triggerNode);
  triggerNode->setParentTSJ(topNode);  

  // Step 4
  RelRoot *rootNode = new(heap) RelRoot(topNode);
  rootNode->setRootFlag(FALSE);
  rootNode->setEmptySelectList();			
  rootNode->setDontOpenNewScope();
  return rootNode;
} 

//////////////////////////////////////////////////////////////////////////////
// The effective GU affects the rows in the affected set into the subject
// table itself. Since this operation is different in Insert, Update and
// Delete, I implemented it as a virtual method, that is implemented by the 
// child classes only.
//////////////////////////////////////////////////////////////////////////////
// we are not supposed to get here
RelExpr *GenericUpdate::createEffectiveGU(BindWA   *bindWA, 
					  CollHeap *heap, 
					  TriggersTempTable& tempTableObj,
					  GenericUpdate **effectiveGUNode,
					  UpdateColumns *colsToSet)
{
  CMPASSERT(FALSE); // Not supposed to get here !!!
  return NULL;
}

//////////////////////////////////////////////////////////////////////////////
// Create an Insert node that inserts the NEW@ values into the subject table.
//////////////////////////////////////////////////////////////////////////////
RelExpr *Insert::createEffectiveGU(BindWA   *bindWA, 
				   CollHeap *heap, 
				   TriggersTempTable& tempTableObj, 
				   GenericUpdate **effectiveGUNode,
				   UpdateColumns *colsToSet)
{
  // Create the Scan on the temporary table.
  Scan *tempScanNode = 
    tempTableObj.buildScan(ChangesTable::INSERTED_ROWS);

  CorrName& tempTable = tempScanNode->getTableName();
  ItemExpr *selectList = tempTableObj.buildBaseColsSelectList(tempTable);

  // Build a RelRoot on top of the Scan node.
  RelRoot *rootNode = new(heap) RelRoot(tempScanNode, REL_ROOT, selectList);
  rootNode->setRootFlag(FALSE);

  // Create an Insert node above the RelRoot.
  // The newRecExpr will be created during binding if the Insert node.
  GenericUpdate *gu = new(heap) 
    Insert(getTableName(), NULL, REL_UNARY_INSERT, rootNode);

  // If this GU is an action of a trigger - don't count rows affected.
  gu->rowsAffected() = rowsAffected(); 
  gu->getInliningInfo().setFlags(II_EffectiveGU);

  *effectiveGUNode = gu;
  return gu;
}

//////////////////////////////////////////////////////////////////////////////
// Create an Update node that updates rows in the subject table according to 
// primary key, and sets them to the NEW@ values.
// Normally, the Update node itself does not have any outputs, because the 
// OLD and NEW values are taken from the temp table. However, when MV 
// logging is needed, the Update node must project the CurrentEpoch column.
//////////////////////////////////////////////////////////////////////////////
RelExpr *Update::createEffectiveGU(BindWA   *bindWA, 
				   CollHeap *heap, 
				   TriggersTempTable& tempTableObj, 
    				   GenericUpdate **effectiveGUNode,
				   UpdateColumns *colsToSet)
{
  ItemExpr *assignList=NULL;
  Assign *assignExpr=NULL;
  CorrName newCorrName(NEWCorr);

  NABoolean mvLoggingRequired = isMvLoggingRequired();

  // Get the columns of the subject table.
  const NAColumnArray &subjectColumns = 
    getTableDesc()->getNATable()->getNAColumnArray(); 

  for (CollIndex i=0; i<subjectColumns.entries(); i++)
  {
    // If this column was not SET into, no need to change it.
    if (!colsToSet->contains(i))
      continue;

    NAColumn *currentColumn = subjectColumns.getColumn(i);
    const NAString &colName = currentColumn->getColName();

    // Cannot update a clustering/primary key column!
    // This error is caught during binding in DDL. 
    // see BeforeTrigger::bindSetClause() in BindRelExpr.cpp
    CMPASSERT(!currentColumn->isClusteringKey() && !currentColumn->isPrimaryKey());

    NAString tempColName(colName);
    assignExpr = new(heap) 
      Assign(new(heap) ColReference(
	new(heap) ColRefName(colName)),
	new(heap) ColReference(new(heap) ColRefName(tempColName, newCorrName)),
	FALSE);
    if (assignList==NULL)
      assignList = assignExpr;
    else
      assignList = new(heap) ItemList(assignExpr, assignList);
  }

  // The selection predicate on the Scan is on the NEW@ clustering index cols.
  // The left side of the equation is using the "@SYSKEY" column while the right
  // side uses the SYSKEY column.
  NAString newName(NEWCorr);
  ItemExpr *selectionPredicate = new(heap)
    BiRelat(ITM_EQUAL,
	    tempTableObj.buildClusteringIndexVector(&newName,TRUE),
	    tempTableObj.buildClusteringIndexVector() );

  Scan *baseScanNode = new(heap) Scan(getTableName());
  baseScanNode->addSelPredTree(selectionPredicate);
  GenericUpdate *effectiveGu = new(heap) 
    Update(getTableName(), NULL, REL_UNARY_UPDATE, baseScanNode, assignList);

  // If this GU is an action of a trigger - don't count rows affected.
  effectiveGu->rowsAffected() = rowsAffected(); 
  effectiveGu->getInliningInfo().setFlags(II_EffectiveGU);

  RelRoot *effectiveRoot = new(heap) RelRoot(effectiveGu);
  if (!mvLoggingRequired)
    effectiveRoot->setEmptySelectList();

  RelExpr *joinTemps = tempTableObj.buildOldAndNewJoin();

  OperatorTypeEnum joinType = mvLoggingRequired ? REL_TSJ : REL_LEFT_TSJ;
  Join *tsjNode = new(heap) Join(joinTemps, effectiveRoot, joinType);
  tsjNode->setTSJForWrite(TRUE);

  *effectiveGUNode = effectiveGu;
  return tsjNode;
}

//////////////////////////////////////////////////////////////////////////////
// Create a Delete node that deletes rows from the subject table according
// to the primary from the row read by the temp Scan node.
//////////////////////////////////////////////////////////////////////////////
RelExpr *Delete::createEffectiveGU(BindWA   *bindWA, 
  				   CollHeap *heap, 
				   TriggersTempTable& tempTableObj, 
				   GenericUpdate **effectiveGUNode,
				   UpdateColumns *colsToSet)
{
  // Create the Scan on the temporary table.
  Scan *tempScanNode = tempTableObj.buildScan(ChangesTable::DELETED_ROWS);

  Delete *gu = new(heap) 
    Delete(getTableName(), NULL, REL_UNARY_DELETE, tempScanNode);

  // If this GU is an action of a trigger - don't count rows affected.
  gu->rowsAffected() = rowsAffected(); 
  gu->getInliningInfo().setFlags(II_EffectiveGU);

  *effectiveGUNode = gu;
  return gu;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::bindEffectiveGU(BindWA *bindWA)
{
  if (getInliningInfo().hasPipelinedActions())
  {
    setNoFlow(TRUE);

    if (getOperatorType() != REL_UNARY_UPDATE)
    {
      createOldAndNewCorrelationNames(bindWA);
    }

    if (isMvLoggingRequired())
    {
      prepareForMvLogging(bindWA, bindWA->wHeap());
    }

    ValueIdList outputs;
    getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
    setPotentialOutputValues(outputs);
  }
  // case of before triggers and after statement triggers where the after triggers are in conflict
  // and the effective GU is either an insert or a delete.
  else if (getOperatorType() != REL_UNARY_UPDATE)
  {
      RETDesc *rd = createOldAndNewCorrelationNames(bindWA, TRUE /* only create RETDesc */);
      getInliningInfo().buildTriggerBindInfo(bindWA, rd, bindWA->wHeap());
      delete rd;
  }
  // indicate that this is a subject table for enable/disable
  getOptStoi()->getStoi()->setSubjectTable(TRUE);

  return this;
}

/*****************************************************************************
******************************************************************************
****  Methods for handling Index Maintenance.
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// See comments in common/ComTransInfo.h
//////////////////////////////////////////////////////////////////////////////
static void setScanLockForIM(const RelExpr *re)
{
  if (re->getOperator().match(REL_SCAN)) {
     Scan *rs = (Scan *)re;
     rs->accessOptions().setScanLockForIM(TRUE);
  }
  for (Int32 i = 0; i < re->getArity(); ++i ) {
    if (re->child(i)) 
       setScanLockForIM(re->child(i));
  }
}


// All table info in these createIM*() methods must come from the TableDesc.
// In particular, use of getTableName() is wrong:  that is the name of the
// topmost view if the target table is a view.  The TableDesc always represents
// the underlying *base* table.
//
RelExpr *GenericUpdate::createIMTree(BindWA *bindWA,
				     UpdateColumns *updatedColumns,
				     NABoolean useInternalSyskey)
{
  RelExpr *imTree = NULL;

  NAString origCorr(getTableDesc()->getCorrNameObj().getCorrNameAsString(),
		    bindWA->wHeap());

  const LIST(IndexDesc *) indexList = getTableDesc()->getIndexes();
  for (CollIndex i=0; i < indexList.entries(); i++) {

    IndexDesc *index = indexList[i];

    // The base table itself is an index (the clustering index);
    // obviously IM need not deal with it.
    //
    if (!index->isClusteringIndex()) {

      // An index always needs maintenance on an Insert or Delete...
      //
      NABoolean imNeeded = 
	((getOperatorType() != REL_UNARY_UPDATE) ||
	 (isMerge()));

      // ...but for an Update, it needs maint if it contains any of the columns
      // being updated.  The test for intersection must use column position
      // (which is always the position in the *base table*, so comparisons
      // *are* meaningful!).  Someday should be abstracted into a shared ##
      // method also used by ItemConstr.h ColSignature stuff... 	 ##
      //
      if (!imNeeded) {
        const ValueIdList &indexColumns = index->getIndexColumns();

      for (CollIndex j=0; j < indexColumns.entries() && !imNeeded; j++) {
        Lng32 indexCol = indexColumns[j].getNAColumn()->getPosition();

        if (updatedColumns != NULL)  // -- Triggers
          imNeeded |= updatedColumns->contains(indexCol);
        else {
          for (CollIndex k=0; k < newRecExprArray().entries(); k++) {
            Lng32 tableCol = newRecExprArray()[k].getItemExpr()->child(0).
	      					  getNAColumn()->getPosition();

            if (indexCol <= tableCol) {
              if (indexCol == tableCol) imNeeded = TRUE;
                break;  // newRecExprArray is ordered by position, so break if <=
			}
		  } // for k
		} // else
	  } // for j

	#ifndef NDEBUG
	  if (imNeeded && GU_DEBUG)
	    cerr << "imNeeded: " << index->getNAFileSet()->getExtFileSetName()
	         << endl;
	#endif
      } // Update, need to test whether IM is needed for this index

      if (imNeeded)
        if (!imTree)
        {
          imTree = createIMNodes(bindWA, useInternalSyskey,
                                 index, producedMergeIUDIndicator_);
          if (getOperatorType() == REL_UNARY_UPDATE ||
              getOperatorType() == REL_UNARY_DELETE)
            setScanLockForIM(child(0));
          if (bindWA->isTrafLoadPrep())
            imTree->setChild(0,this);
        }
        else
        {
          if (!bindWA->isTrafLoadPrep())
          {
            imTree = new (bindWA->wHeap()) 
              Union(imTree, createIMNodes(bindWA, useInternalSyskey,
                                          index, producedMergeIUDIndicator_),
                    NULL, NULL, REL_UNION, CmpCommon::statementHeap(), TRUE, TRUE);
            imTree->setBlockStmt(isinBlockStmt());
            imTree->getInliningInfo().setFlags(II_isIMUnion);
          } // not bulk load
          else {
            RelExpr * oldIMTree = imTree;
            imTree = createIMNodes(bindWA, useInternalSyskey, index,
                                   producedMergeIUDIndicator_);
            imTree->setChild(0,oldIMTree);
          } // is bulk load
        }

    } // !clusteringIndex
  } // loop over all indexes

  // ##IM: This extra RelRoot is probably unnecessary (wasteful),
  // ##    due to createIMNode*() always returning a RelRoot-topped tree --
  // ##    but I didn't have time to remove it and re-test.
  if (imTree && imTree->getOperatorType() != REL_ROOT)
    imTree = new (bindWA->wHeap()) RelRoot(imTree);

  getTableDesc()->getCorrNameObj().setCorrName(origCorr);

  return imTree;
} // GenericUpdate::createIMTree()


// Here, we make virgin ColReferences, which when bound will be found
// in an outer scope engendered by our (and/or GenericUpdate's) interposing
// a RelRoot between us and our parent GenericUpdate --
// and the LeafXxx will add these outer refs to its characteristic inputs.
static RelExpr *createIMNode(BindWA *bindWA, 
			     CorrName &tableCorrName,
			     const CorrName &indexCorrName,
			     IndexDesc *index,
                             const ValueId &mergeIUDIndicator,
			     NABoolean isIMInsert,
			     NABoolean useInternalSyskey,
                             NABoolean isForUpdateOrMergeUpdate,
                             NABoolean mergeDeleteWithInsertOrMergeUpdate,
			     NABoolean isEffUpsert)
{
   
 // See createOldAndNewCorrelationNames() for info on OLDCorr/NEWCorr
  
  // A merge statement can perform an update or an insert if a matching row 
  // is detected or not, correspondingly. In either case, a update operation is 
  // performed on the index table. If a unique index is involved, a update
  // operation would be able to delete a corresponding row in the index table
  // using the index "key" column before inserting a new row. If it is a insert
  // operation on the base table, then a update on the index table should not 
  // delete a row that corresponds to a different row in the base table(index
  // key belonging to a different row). Hence in this case, it is better to always
  // match not only the index key but also remaining columns in the index table
  // that correspond to the base table. Hence we introduce 
  // robustDelete below. This flag could also be called 
  // isIMOnAUniqueIndexForMerge
  NABoolean robustDelete = (mergeDeleteWithInsertOrMergeUpdate && index->isUniqueIndex()) || 
                           (isEffUpsert && index->isUniqueIndex());

  tableCorrName.setCorrName(isIMInsert ?  NEWCorr : OLDCorr);
  
  ItemExprList *colRefList = new(bindWA->wHeap()) ItemExprList(bindWA->wHeap());
  
  const ValueIdList &indexColVids = ((isIMInsert || robustDelete )? 
				     index->getIndexColumns() : 
				     index->getIndexKey());
  ItemExpr *preCond = NULL; // pre-condition for delete, insert if any
  for (CollIndex i=0; i < indexColVids.entries(); i++) {

    const NAString &colName = indexColVids[i].getNAColumn()->getColName();

    NAString realColName = colName;
    if (useInternalSyskey && colName == "SYSKEY")
    {
      realColName = "@SYSKEY";
    }

    ColReference *colRef =
      new (bindWA->wHeap()) ColReference
        (new (bindWA->wHeap()) ColRefName (realColName, tableCorrName, bindWA->wHeap()));

    colRefList->insert(colRef);
  }

  // There are 4 cases here. Following table shows when precondition
  // expression is addded
  // Index Type/IM operation->  Delete  | Insert
  // Non-unique Index           Yes        No 
  // Unique Index               Yes        Yes
  if ((!isIMInsert && isForUpdateOrMergeUpdate)||robustDelete || (!isIMInsert && isEffUpsert))
    {
      // For delete nodes that are part of an update or merge update or upsert,
      // generate a comparison expression between old and new index column 
      // values and suppress the delete if no columns change. This avoids the
      // situation where we delete and then re-insert the same index
      // row within one millisecond and get the same HBase timestamp
      // value assigned. In that case, the delete will win out over
      // the insert, even though the insert happens later in time. The
      // HBase-trx folks are also working on a change to avoid that.
      // similar checks are added for unique index insert (into the index
      // table only, using the robustDelete flag above). 
      // Since we do checkandput for unique indexes, putting 
      // an existing row (key + value) will raise a uniqueness violation,
      // while from the user's point of view no change in the uninque index
      // table is expected.

      CorrName predValues(tableCorrName);

      if (isIMInsert)
	predValues.setCorrName(OLDCorr);
      else
	predValues.setCorrName(NEWCorr);

      for (CollIndex cc=0; cc<colRefList->entries(); cc++)
        {
          ColReference *predColRef = static_cast<ColReference *>
	    ((*colRefList)[cc]);

	  BiRelat *comp1Col  = NULL;
          // create a predicate OLD@.<col> = NEW@.<col>
	  comp1Col = new (bindWA->wHeap())
	    BiRelat(ITM_EQUAL,
		    predColRef,
		    new (bindWA->wHeap()) ColReference(
			 new (bindWA->wHeap()) ColRefName(
	    		 predColRef->getColRefNameObj().getColName(),
			 predValues,
			 bindWA->wHeap())),
                    TRUE); // special NULLs, treat NULL == NULL as true

          if (preCond == NULL)
            preCond = comp1Col;
          else
            preCond = new (bindWA->wHeap()) BiLogic(ITM_AND, preCond, comp1Col);
        }

      // the actual condition is that the values are NOT the same
      preCond = new (bindWA->wHeap()) UnLogic(ITM_NOT, preCond);
    }

  // If we got an IUD indicator passed in, that means that we have
  // an IM tree for update, but the actual operation may be an
  // insert or a delete, and therefore we may need to suppress the
  // index delete or insert, respectively, with a precondition.
  if (mergeIUDIndicator != NULL_VALUE_ID)
    {
      ItemExpr *iudCond = 
        new(bindWA->wHeap()) BiRelat(
             ITM_NOT_EQUAL,
             mergeIUDIndicator.getItemExpr(),
             new(bindWA->wHeap()) SystemLiteral(
                  (isIMInsert ? "D" : "I"),
                  CharInfo::ISO88591));

      if (preCond == NULL) 
        preCond = iudCond;
      else
        preCond = new (bindWA->wHeap()) BiLogic(
             ITM_AND,
             iudCond,
             preCond);
    }

  // NULL tableDesc here, like all Insert/Update/Delete ctors in SqlParser,
  // because the LeafXxx::bindNode will call GenericUpdate::bindNode
  // which will do the appropriate createTableDesc.
  GenericUpdate *imNode;
  if (isIMInsert)
    {
      if (!bindWA->isTrafLoadPrep())
      {
        imNode = new (bindWA->wHeap()) 
	  LeafInsert(indexCorrName, NULL, colRefList, REL_LEAF_INSERT,
		     preCond, bindWA->wHeap());
        HostArraysWA * arrayWA = bindWA->getHostArraysArea() ;
        if (arrayWA && arrayWA->hasHostArraysInTuple()) {
          if (arrayWA->getTolerateNonFatalError() == TRUE)
            imNode->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);    
        }
        // For index maintenance on non-unique HBase indexes we can use a put.
        // In fact we must use a put, otherwise we'll get a uniqueness constraint
        // violation for those rows that didn't change and therefore didn't get
        // deleted, due to the precondition (see below).
        if (!index->isUniqueIndex())
          imNode->setNoCheck(TRUE);
      } // regular insert
      else {
        imNode = new (bindWA->wHeap()) Insert(indexCorrName,
                 NULL,
                 REL_UNARY_INSERT,
                 NULL);
        ((Insert *)imNode)->setBaseColRefs(colRefList);
        ((Insert *)imNode)->setInsertType(Insert::UPSERT_LOAD);
        ((Insert *)imNode)->setIsTrafLoadPrep(true);
        ((Insert *)imNode)->setNoIMneeded(TRUE);
      } // traf load prep
    }
  else
    {
      imNode = new (bindWA->wHeap()) LeafDelete(indexCorrName,
                                                NULL,
                                                colRefList,
                                                (robustDelete )?TRUE:FALSE,
                                                REL_LEAF_DELETE,
                                                preCond,
                                                bindWA->wHeap());
      imNode->setReferencedMergeIUDIndicator(mergeIUDIndicator);
    }

   // The base table's rowsAffected() will get set in ImplRule.cpp,
  // but we don't want any of these indexes' rowsAffected to be computed
  // (if I insert one row into a table, I want to see "1 row(s) inserted",
  // not 1 + number of indexes being maintained!).
  imNode->rowsAffected() = GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED;

  // Do not collect STOI info for security checks.
  imNode->getInliningInfo().setFlags(II_AvoidSecurityChecks);
  
  // Set the flag that this GU is part of IM
  imNode->getInliningInfo().setFlags(II_isIMGU);

  if (bindWA->isTrafLoadPrep())
    return imNode;

  // Add a root here to prevent error 4056 when binding the LeafDelete+Insert
  // pair for an Update.
  return new (bindWA->wHeap()) RelRoot(imNode);
} // static createIMNode()

RelExpr *GenericUpdate::createIMNodes(BindWA *bindWA,
				      NABoolean useInternalSyskey,
				      IndexDesc *index,
                                      const ValueId &mergeIUDIndicator)
{
  // We call getExtFileSetObj (returns QualifiedName),
  // NOT getExtFileSetName (returns NAString),
  // hence the CorrName ctor sets up entire QualifiedName,
  // NOT just an (erroneously delimited) objectName part of one.
  //
  CorrName indexCorrName(index->getNAFileSet()->getExtFileSetObj());
  indexCorrName.setSpecialType(ExtendedQualName::INDEX_TABLE);

  CorrName &tableCorrName = getTableDesc()->getCorrNameObj();
  if(tableCorrName.isVolatile())
    indexCorrName.setIsVolatile(TRUE);

  RelExpr *indexInsert = NULL, *indexDelete = NULL, *indexOp = NULL;
  NABoolean isForUpdateOrMergeUpdate = (getOperatorType() == REL_UNARY_UPDATE ||
                           isMergeUpdate());
  
  NABoolean isEffUpsert = ((getOperatorType() == REL_UNARY_INSERT) && ((Insert *)this)->xformedEffUpsert());
  if (indexCorrName.getUgivenName().isNull())
    {
      indexCorrName.setUgivenName(tableCorrName.getUgivenName());
    }

  // Create a list of base columns ColReferences for
  // ALL the index columns as AFTER/NEW columns.
  //
  if (getOperatorType() == REL_UNARY_INSERT ||
      getOperatorType() == REL_UNARY_UPDATE || isEffUpsert)
    indexInsert = indexOp = createIMNode(bindWA,
					 tableCorrName,
					 indexCorrName,
					 index,
                                         mergeIUDIndicator,
					 TRUE,
					 useInternalSyskey,
                                         isForUpdateOrMergeUpdate,
                                         isMerge(),
					 isEffUpsert);

  // Create a list of base columns ColReferences for
  // ONLY the index KEY columns as BEFORE/OLD columns.
  //
  if (getOperatorType() == REL_UNARY_DELETE ||
      getOperatorType() == REL_UNARY_UPDATE ||
      isEffUpsert)
    {
      NABoolean mergeDeleteWithInsertOrMergeUpdate = isMerge();
      if (mergeDeleteWithInsertOrMergeUpdate && 
          (getOperatorType() == REL_UNARY_DELETE) && 
          (!insertValues()))
        // merge delete without an insert
        mergeDeleteWithInsertOrMergeUpdate = FALSE;
      
      indexDelete = indexOp = createIMNode(bindWA,
					 tableCorrName,
                                         indexCorrName,
					 index,
                                         mergeIUDIndicator,
					 FALSE,
    			       		 useInternalSyskey,
                                         isForUpdateOrMergeUpdate,
                                         mergeDeleteWithInsertOrMergeUpdate,
					 isEffUpsert);
    }

  if ((getOperatorType() == REL_UNARY_UPDATE) || isEffUpsert){
    indexOp = new (bindWA->wHeap()) Union(indexDelete, indexInsert, 
                                          NULL, NULL, REL_UNION, 
                                          CmpCommon::statementHeap(),TRUE,TRUE);

    // is this in a compound statement?
    indexOp->setBlockStmt(isinBlockStmt());

    // is this GU driven by a row trigger
    // this a temporary fix to prevent data corruption when
    // the update operation is in the action of a row
    // trigger. The data corruption is the result of the 
    // insert side of the IM tree lagging behind the delete
    // in the case where multiple request to update the same rows
    // are flowing to this update node.
    // This is also the case when updates are being driven 
    // by rowsets.
    // The fix is to unconditionally block the ordered union
    // to handle all cases of IM updates.
    // Note that this may cause performance issues. Improving
    // the performance is an RFE at the moment. 
    //if (this->getInliningInfo().isInActionOfRowTrigger() ||
    //   bindWA->getHostArraysArea())
    //{
       ((Union *)indexOp)->setBlockedUnion();
    //}
    //else
    //{
    //   ((Union *)indexOp)->setOrderedUnion();
    //}

    // Add a root just to be consistent, so all returns from this method
    // are topped with a RelRoot.

    // Set this Union is part of IM
    indexOp->getInliningInfo().setFlags(II_isIMUnion);
    indexOp = new (bindWA->wHeap()) RelRoot(indexOp);
  }

  return indexOp;
} // GenericUpdate::createIMNodes()


/*****************************************************************************
******************************************************************************
****  Methods for handling Undo (for an insert) .
******************************************************************************
*****************************************************************************/

// All table info in these createUndo*() methods must come from the TableDesc.
// In particular, use of getTableName() is wrong:  that is the name of the
// topmost view if the target table is a view.  The TableDesc always represents
// the underlying *base* table.
//
RelExpr *GenericUpdate::createUndoTree(BindWA *bindWA,
				       UpdateColumns *updatedColumns,
				       NABoolean useInternalSyskey,
				       NABoolean imOrRiPresent,
				       NABoolean ormvPresent,
				       TriggersTempTable  *tempTableObj)
{
  RelExpr *undoTree = NULL;

  NAString origCorr(getTableDesc()->getCorrNameObj().getCorrNameAsString(),
		    bindWA->wHeap());

  const LIST(IndexDesc *) indexList = getTableDesc()->getIndexes();
 

   
  NABoolean undoNeeded = getOperatorType() == REL_UNARY_INSERT;
  if (!undoNeeded)
    return NULL;
  if (imOrRiPresent)
    {
      for (CollIndex i=0; i < indexList.entries(); i++) 
	{

	  IndexDesc *index = indexList[i];
	  if (undoNeeded)
	    if (!undoTree)
	      undoTree = createUndoNodes(bindWA, useInternalSyskey, index);
	    else
	      {
		undoTree = new (bindWA->wHeap()) 
		  Union(undoTree, createUndoNodes(bindWA, useInternalSyskey, index),
			NULL, NULL, REL_UNION, CmpCommon::statementHeap(), TRUE, TRUE);
		undoTree->setBlockStmt(isinBlockStmt());
	      }

	  
	} // loop over all indexes
    }
  if (ormvPresent)
    {
      if (!undoTree)
	undoTree = createUndoIUDLog(bindWA);
      else	
	undoTree = new (bindWA->wHeap()) 
	  Union(undoTree, createUndoIUDLog(bindWA),
		NULL, NULL, REL_UNION, CmpCommon::statementHeap(), TRUE, TRUE);
    }
  if (tempTableObj)
    {
      if (!undoTree)
	undoTree = createUndoTempTable(tempTableObj,bindWA);
      else	
	undoTree = new (bindWA->wHeap()) 
	  Union(undoTree, createUndoTempTable(tempTableObj,bindWA),
		NULL, NULL, REL_UNION, CmpCommon::statementHeap(), TRUE, TRUE); 
    }

  // ##IM: This extra RelRoot is probably unnecessary (wasteful),
  // ##    due to createIMNode*() always returning a RelRoot-topped tree --
  // ##    but I didn't have time to remove it and re-test.
  if (undoTree && undoTree->getOperatorType() != REL_ROOT)
    undoTree = new (bindWA->wHeap()) RelRoot(undoTree);

  getTableDesc()->getCorrNameObj().setCorrName(origCorr);

  return undoTree;
} // GenericUpdate::createUndoTree()


RelExpr * GenericUpdate::createUndoTempTable(TriggersTempTable *tempTableObj,BindWA *bindWA)
{
  
  // TriggersTempTable *tempTableObj = new(bindWA->wHeap()) TriggersTempTable(this, bindWA);
  const NAColumnArray &tempColumns = tempTableObj->getNaTable()->getNAColumnArray(); 
  ItemExprList *tempColRefList = new(bindWA->wHeap()) ItemExprList(bindWA->wHeap());
  /*  CorrName tempCorrName = *(tempTableObj->calcTargetTableName(tempTableObj->getSubjectTableName().getQualifiedNameObj()));*/
  CorrName tempCorrName = *(tempTableObj->getTableName());
  CorrName origTempCorrName = tempCorrName;
  tempCorrName.setCorrName( NEWCorr);
  for (CollIndex i=0; i<tempColumns.entries(); i++) 
    {
      NAString tempColName(tempColumns.getColumn(i)->getColName());
   

      ColReference *tempColRef = new(bindWA->wHeap()) 
	ColReference(new(bindWA->wHeap()) ColRefName(tempColName, tempCorrName));

      tempColRefList->insert(tempColRef);
    }

  RelExpr *delTemp = new (bindWA->wHeap()) LeafDelete(origTempCorrName, NULL, 
						      tempColRefList,FALSE);
  ((LeafDelete *)delTemp)->setTrigTemp(tempTableObj);
  ((GenericUpdate *)delTemp)->rowsAffected() = GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED;
 
  return new (bindWA->wHeap()) RelRoot(delTemp); 
 
  
}

// Here, we make virgin ColReferences, which when bound will be found
// in an outer scope engendered by our (and/or GenericUpdate's) interposing
// a RelRoot between us and our parent GenericUpdate --
// and the LeafXxx will add these outer refs to its characteristic inputs.
static RelExpr *createUndoNode(BindWA *bindWA, 
			     CorrName &tableCorrName,
			     const CorrName &indexCorrName,
			     IndexDesc *index,
			     NABoolean useInternalSyskey)
{
   
 // See createOldAndNewCorrelationNames() for info on OLDCorr/NEWCorr
  CorrName btCorrName = tableCorrName;
   
  tableCorrName.setCorrName( NEWCorr);
  
  
  ItemExprList *colRefList = new(bindWA->wHeap()) ItemExprList(bindWA->wHeap());
  
  const ValueIdList &indexColVids =  
    (index->isUniqueIndex()? index->getIndexColumns(): index->getIndexKey());
  
    

  
  for (CollIndex i=0; i < indexColVids.entries(); i++) {

    const NAString &colName = indexColVids[i].getNAColumn()->getColName();

    NAString realColName = colName;
    if (useInternalSyskey && colName == "SYSKEY")
    {
      realColName = "@SYSKEY";
    }

    ColReference *colRef =
      new (bindWA->wHeap()) ColReference
        (new (bindWA->wHeap()) ColRefName (realColName, tableCorrName, bindWA->wHeap()));

    colRefList->insert(colRef);
  }

  

  // NULL tableDesc here, like all Insert/Update/Delete ctors in SqlParser,
  // because the LeafXxx::bindNode will call GenericUpdate::bindNode
  // which will do the appropriate createTableDesc.
  GenericUpdate *delIndex; 
 
 
     
	
 
  if (index->isClusteringIndex())
    delIndex = new (bindWA->wHeap()) LeafDelete(btCorrName, NULL, 
						    colRefList);
  else
    delIndex = new (bindWA->wHeap()) LeafDelete(indexCorrName, NULL 
							,colRefList 
							,index->isUniqueIndex());
	
         
  // The base table's rowsAffected() will get set in ImplRule.cpp,
  // but we don't want any of these indexes' rowsAffected to be computed
  // (if I insert one row into a table, I want to see "1 row(s) inserted",
  // not 1 + number of indexes being maintained!).
  delIndex->rowsAffected() = GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED;

  // Do not collect STOI info for security checks.
  delIndex->getInliningInfo().setFlags(II_AvoidSecurityChecks);
  
  
  // Add a root here to prevent error 4056 when binding the LeafDelete+Insert
  // pair for an Update.
  return new (bindWA->wHeap()) RelRoot(delIndex); 	 
  
    
  return NULL;
} // static createUndoNode()

RelExpr *GenericUpdate::createUndoNodes(BindWA *bindWA,
				      NABoolean useInternalSyskey,
				      IndexDesc *index)
{
  // We call getExtFileSetObj (returns QualifiedName),
  // NOT getExtFileSetName (returns NAString),
  // hence the CorrName ctor sets up entire QualifiedName,
  // NOT just an (erroneously delimited) objectName part of one.
  //
  
  CorrName indexCorrName(index->getNAFileSet()->getExtFileSetObj());
  indexCorrName.setSpecialType(ExtendedQualName::INDEX_TABLE);

  CorrName &tableCorrName = getTableDesc()->getCorrNameObj();
  RelExpr *undoInsert = NULL;

  if (indexCorrName.getUgivenName().isNull())
    {
      indexCorrName.setUgivenName(tableCorrName.getUgivenName());
    }

  if(tableCorrName.isVolatile())
    indexCorrName.setIsVolatile(TRUE);

  // Create a list of base columns ColReferences for
  // ALL the index columns as AFTER/NEW columns.
  //
  
    undoInsert =  createUndoNode(bindWA, 
				 tableCorrName, 
				 indexCorrName,
				 index, 
				 useInternalSyskey);

 

    return undoInsert;
} // GenericUpdate::createUndoNodes()
/*****************************************************************************
******************************************************************************
****  Methods for handling undo from IUD log
******************************************************************************
*****************************************************************************/



RelExpr *GenericUpdate::createUndoIUDLog(BindWA *bindWA)
{
 						    
  MvIudLog logTableObj(this, bindWA);
  RelExpr *undoIUDNode = logTableObj.buildInsert(TRUE,
                                                 ChangesTable::ALL_ROWS,
                                                 TRUE,
                                                 TRUE);
  return undoIUDNode;
}

/*****************************************************************************
******************************************************************************
****  Methods for handling RI constraints
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RefConstraintList *GenericUpdate::getRIs(BindWA *bindWA, 
					 const NATable *naTable)
{
  RefConstraintList *allRIConstraints = new(bindWA->wHeap()) 
    RefConstraintList(bindWA->wHeap());

  if ((getOperatorType() == REL_UNARY_INSERT) || 
      (getOperatorType()== REL_UNARY_UPDATE))
    naTable->getRefConstraints().getRefConstraints(bindWA, 
						   newRecExpr(), 
						   *allRIConstraints);
  
  if ((getOperatorType() == REL_UNARY_DELETE) || 
      (getOperatorType()== REL_UNARY_UPDATE) ||
      ((getOperatorType() == REL_UNARY_INSERT) && ((Insert *)this)->xformedEffUpsert()))
    naTable->getUniqueConstraints().getRefConstraints(bindWA, 
						      newRecExpr(), 
						      *allRIConstraints);

  CollIndex numConstraints = allRIConstraints->entries();

  for(CollIndex index = 0; index < numConstraints; index++)
  {
    if(NOT (allRIConstraints->at(index)->getIsEnforced()))
    {
	allRIConstraints->removeAt(index);
	numConstraints--;
	index--;
    }
  }

  if(allRIConstraints->isEmpty())
  {
    delete allRIConstraints;
    allRIConstraints = NULL;
  }

  return allRIConstraints;
}

//////////////////////////////////////////////////////////////////////////////
// Given the columns being updated, do we need to enforce this RI constraint?
// Check if there is any matching columns in both the RI key columns and
// in the set of columns being updated.
//////////////////////////////////////////////////////////////////////////////
NABoolean RefConstraint::isRINeededForUpdatedColumns(UpdateColumns *UpdatedColumns)
{
  // UpdatedColumns is NULL for INSERT and DELETE. Columns should be matched
  // for UPDATE operations only.

  if (NOT getIsEnforced())
    return FALSE;

  if (UpdatedColumns == NULL)
    return TRUE;

  NABoolean isAReferencingConstraint = isaForeignKeyinTableBeingUpdated() 
					&& getIsEnforced();
  const KeyColumns *riColumns;

  if (isAReferencingConstraint)
    riColumns = &keyColumns();
  else
    riColumns = uniqueConstraintReferencedByMe_.keyColumns_;

  for (CollIndex i=0; i<riColumns->entries(); i++)
  {
    if (UpdatedColumns->contains(riColumns->at(i)->getPosition()))
      return TRUE;
  }
  return FALSE;
}

//////////////////////////////////////////////////////////////////////////////
// Return a list of only the RI constraints needed when updating the
// specified columns.
//////////////////////////////////////////////////////////////////////////////
RefConstraintList *RefConstraintList::getNeededRIs(UpdateColumns *updatedColumns,
						   CollHeap *heap)
{
  // Insert into neededRIs only the constraints that match the columns
  // being updated.
  RefConstraintList *neededRIs = new(heap) RefConstraintList(heap);
  for (CollIndex i=0; i<entries(); i++)
    if (at(i)->isRINeededForUpdatedColumns(updatedColumns))
      neededRIs->insert(at(i));

  return neededRIs;
}

//////////////////////////////////////////////////////////////////////////////
// The tree below with a refConstraint after its bound.
//          TSJ
//         /  \
//   Insert   RelRoot
//     |         |
//   Tuple    GroupByAgg
//               |
//              Scan
//
// This function creates the rightSubtree of the TSJ node.
// Step 1. create the scan node with the predicate.
// Step 2. Create the GroupBy Node with the aggregate expression.
// Step 3. create the RelRoot node.
//////////////////////////////////////////////////////////////////////////////
RelExpr* GenericUpdate::createRISubtree(BindWA *bindWA, 
				        const NATable *naTable, 
				        const RefConstraint& refConstraint,
				        CollHeap *heap)
{
  RelExpr *newScan = NULL;
  NAString constraintName(bindWA->wHeap());
  NAString tableName(bindWA->wHeap());
  Parser parser(bindWA->currentCmpContext());

  NABoolean isReferencingConstraint = 
    (refConstraint.isaForeignKeyinTableBeingUpdated() &&
    refConstraint.getIsEnforced());
  
  // Step 1: Create a scan node with predicate given by the refConstraint.
  const QualifiedName parentQualName = refConstraint.getOtherTableName();
  
  NAString scanPredicateTxt;
  CorrName corrName(naTable->getTableName(), heap,
		    (isReferencingConstraint ? NEWAnsi : OLDAnsi));

  NAString corrNameString = corrName.getCorrNameAsString();
  refConstraint.getPredicateText(scanPredicateTxt, &corrNameString);
  
  constraintName = refConstraint.getConstraintName().getQualifiedNameAsAnsiString();
  tableName = naTable->getTableName().getQualifiedNameAsAnsiString();
  
  // Create the Scan node.
  newScan = new (heap) Scan (CorrName(parentQualName));
  ItemExpr *newScanPredicate = parser.getItemExprTree 
    ((char *)scanPredicateTxt.data());
  newScan->addSelPredTree(newScanPredicate);
  ((Scan *)newScan)->accessOptions().accessType() = TransMode::REPEATABLE_READ_ACCESS_;
  // Do not collect STOI info for security checks.
  newScan->getInliningInfo().setFlags(II_AvoidSecurityChecks);

  
  // Step 2: Create GroupBy Node.
  // Create a selection predicate and attach it to the
  // GroupBy  Node. in the 
  //                      case
  //                       |
  //                   IfThenElse
  //               ________|__________
  //              |        |          |
  //              |        |          |
  //              |        |          |
  //             OR      False    RaiseError
  //           /    \
  //          /      \
  //    OneTrue  (FK1 IS NULL
  //       |          OR     
  //       =      FK2 IS NULL..)
  //     /   \
  //    1     1
  
  ItemExpr *aggSelPredicate = parser.getItemExprTree ("1 = 1");

  ItemExpr *newAggExpr = NULL;
  
  // For inserts we have to see if a value exists in the referenced table
  // and for deletes we have to check that the deleted value does not exist
  // in the referencing table. Update is a delete and an insert, so we
  // have to check both.
  // You can tell whether to use "EXISTS" or "NOT EXISTS" by looking at
  // RefConstraint::isaForeignKeyinTableBeingUpdated
  
  if (isReferencingConstraint) 
  {
    // According to ANSI SQL99 (4.17.2), RI constraint is satisfied if one of the 
    // following conditions is true, depending on the <match option> specified in the
    // <referential constraint definition>:
    // If no < match type> was specified then, for each row R1 of the referencing
    // table, either at least one of the values of the referencing columns in 
    // R1 shall be a null value, or the value of each referencing column in R1 shall
    // be equal to the value of the corresponding referenced  column in
    // some row of the referenced table.

    // The MX 2.0 does not support <match type>, so it would be equivalent to
    // not specifying the <match type>.

    // This MatchOptionPredicate of the form (fk1 IS NULL or fk2 IS NULL)
    // is added to let the FKs with NULL values pass the RI constraint.

    // Also note that this MatchOptionPredicate is evaluated in the GroupBy
    // instead of Scan node. This is because when this predicate is added
    // to the row value constructor in the Scan node, the Optimizer fails to
    // recognise it as a key predicate, hence affecting performance.
    
    NAString matchOptionPredicateTxt;
    refConstraint.getMatchOptionPredicateText(matchOptionPredicateTxt, 
					      &corrNameString);
    
    ItemExpr *matchOptionPred = parser.getItemExprTree
      ((char *)matchOptionPredicateTxt.data());
    newAggExpr = new (heap) BiLogic(ITM_OR, 
				    new (heap) 
				    Aggregate(ITM_ONE_TRUE, aggSelPredicate),
				    matchOptionPred
				    );
    
  }
  else 
  {
    newAggExpr = new (heap) 
      UnLogic(ITM_NOT, new (heap) Aggregate(ITM_ONE_TRUE, aggSelPredicate));
  }
  
  ItemExpr *grbySelectionPred = new (heap)
    Case(NULL,
	 new (heap)
	   IfThenElse(newAggExpr,
		    new (heap) BoolVal(ITM_RETURN_FALSE),
		    new (heap) 
		      RaiseError((Lng32)EXE_RI_CONSTRAINT_VIOLATION, constraintName, 
			       tableName)));

  
  // Create a GroupBy on the newScan, and attach the new case as "having" predicate.
  RelExpr * newGrby = new(heap)
    GroupByAgg(newScan, REL_GROUPBY);
  newGrby->addSelPredTree(grbySelectionPred);
  
  // Create the Root Node.
  RelExpr *newRoot = new (heap) 
    RelRoot(newGrby,
	    TransMode::REPEATABLE_READ_ACCESS_,
	    SHARE_);

  ((RelRoot *)newRoot)->setEmptySelectList();

  return newRoot;
} // createRISubtree()

//////////////////////////////////////////////////////////////////////////////
// Given the ConstraintList, this function creates a RI subtree and returns
// the root of the subtree to the caller.
//////////////////////////////////////////////////////////////////////////////
RelExpr* GenericUpdate::inlineRI (BindWA *bindWA, 
				  const RefConstraintList *refConstraints,
				  CollHeap *heap)
{
  Int32 entries = 0;
  RelExpr *riSubtree = NULL;
  const NATable *naTable = getTableDesc()->getNATable();

  CMPASSERT (!refConstraints->isEmpty())
  
  if ((entries = refConstraints->entries())) 
  {
    riSubtree = createRISubtree(bindWA, naTable, *(refConstraints->at(0)), heap);
    for (Int32 i=1; i < entries; i++) 
    {
      riSubtree = new(heap) 
	Union(createRISubtree(bindWA, naTable, *(refConstraints->at(i)), heap),
	      riSubtree, NULL, NULL, REL_UNION, CmpCommon::statementHeap(), TRUE);
    } //end of for
  } 

  CMPASSERT(riSubtree);

  // Create the Root Node, only if the "riSubtree" is not a RelRoot.
  // "riSubtree" will be a relroot when there is only one RI constraint.
  // Avoding duplicate roots.
  if (riSubtree->getOperatorType() != REL_ROOT) {
    riSubtree = new (heap) 
      RelRoot(riSubtree,
              TransMode::REPEATABLE_READ_ACCESS_,
              SHARE_);
    ((RelRoot *)riSubtree)->setEmptySelectList();
  }

  riSubtree->getInliningInfo().setFlags(II_ActionOfRI);
  return riSubtree;
} // inlineRI.

/*****************************************************************************
******************************************************************************
****  Methods for handling MV Logging
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// Logging should NOT be done in the following cases:
//    1. DELETE FROM MV
//    2. Update/Delete on INSERTLOG table.
//    3. NOLOG option specified
//    4. Pipelined refresh.
//    5. Recompute.
// In the first 3 cases, the table should be marked as inconsistent, and 
// getIsInsertLog() returns INCONSISTENT_NOLOG.
// In the cases of pipelined refresh and recompute, logging is 
// disabled, but the table is NOT marked as inconsistent (CONSISTENT_NOLOG).
// P.S. Marking the table as inconsistent is not implemented yet.
//////////////////////////////////////////////////////////////////////////////
NABoolean GenericUpdate::isMvLoggingRequired()
{
  const ComMvAttributeBitmap& bitmap = 
    getTableDesc()->getNATable()->getMvAttributeBitmap();

  if (!bitmap.getLoggingRequired())
  {
    // Just in case the user used NOLOG when logging is not required. We don't 
    // want to mark the table as inconsistent.
    isNoLogOperation_ = NORMAL_LOGGING; 
    return FALSE;
  }

#if 0
  // A set loggingRequired flag does not mean the MVs on this table
  // are initialized. If all the ON REQUEST MVs using this table
  // are not initialized, no logging is required.
  // This is commented out until we update the redefinition timestamp
  // of the base table when we initialize the MV.
  const UsingMvInfoList& mvsUsingMe = getTableDesc()->getNATable()->getMvsUsingMe();
  NABoolean foundInitializedMVs = FALSE;
  CollIndex maxEntries = mvsUsingMe.entries();
  for (CollIndex i=0; i<maxEntries; i++)
  {
    const UsingMvInfo* mv = mvsUsingMe[i];

    // Ignore MVs that are not ON REQUEST.
    if ( mv->getRefreshType() ==  COM_ON_REQUEST &&
         mv->isInitialized() )
    {
      // The MV is initialized. 
      // No need to continue the loop - logging is required.
      foundInitializedMVs = TRUE;
      break;
    }
  }
  if (foundInitializedMVs == FALSE)
  {
    // No initialized ON REQUEST MVs were found, so no reason to log.
    // Do not cache this query, to avoid breaking such statements
    // after the MV has been initialized.
    setNonCacheable();
    return FALSE;
  }
#endif

  // Check for Update/Delete on an INSERTLOG table
  if (getOperatorType() != REL_UNARY_INSERT &&
      bitmap.getIsInsertLog() )
  {
    setNoLogOperation(FALSE); // This is an inconsistent operation.
  }

  // Marking the table as inconsistent is not implemented yet,
  // therefore the INCONSISTENT_NOLOG mode is not considered logging.
  // When implemented, it will mean writing the CurrentEpoch to the UMD
  // table, and will be handled just like logging.
  return (isNoLogOperation() == NORMAL_LOGGING);
//return (isNoLogOperation() == NORMAL_LOGGING || 
//        isNoLogOperation() == INCONSISTENT_NOLOG);  
}

//////////////////////////////////////////////////////////////////////////////
// Add to the RETDesc the virtual columns needed for MV logging.
//////////////////////////////////////////////////////////////////////////////
void GenericUpdate::prepareForMvLogging(BindWA   *bindWA, 
					CollHeap *heap)
{
  // Create a "virtual column" called @CURRENT_EPOCH for the CurrentEpoch 
  // function. This function must be evaluated on the GU, and pipelined to
  // the Log Insert node.
  ItemExpr *currEpoch = new(heap) GenericUpdateOutputFunction(ITM_CURRENTEPOCH);
  ValueId epochId = 
    addVirtualColumn(bindWA, currEpoch, InliningInfo::getEpochVirtualColName(), heap);
  ValueId rowTypeId, rowCountId;
  if (getOperatorType() == REL_UNARY_INSERT &&
      getTableDesc()->getNATable()->getMvAttributeBitmap().getAutomaticRangeLoggingRequired())
  {
    // dead code, range logging is not supported
    ItemExpr *rowType  = new(heap) GenericUpdateOutputFunction(ITM_VSBBROWTYPE);
    ItemExpr *rowCount = new(heap) GenericUpdateOutputFunction(ITM_VSBBROWCOUNT);
    rowTypeId  = 
      addVirtualColumn(bindWA, rowType, InliningInfo::getRowTypeVirtualColName(), heap);
    rowCountId = 
      addVirtualColumn(bindWA, rowCount, InliningInfo::getRowCountVirtualColName(), heap);
  }

  ItemExpr *tsOutExpr = new (heap) 
                  GenericUpdateOutputFunction(ITM_JULIANTIMESTAMP, 
                                              1,
                                              new (heap) InternalTimestamp);

  ValueId tsId = addVirtualColumn(bindWA, 
                                  tsOutExpr, 
                                  InliningInfo::getMvLogTsColName(), 
                                  heap);


  ValueIdSet potentialOutputs;
  getPotentialOutputValues(potentialOutputs);
  potentialOutputs += epochId;
  potentialOutputs += tsOutExpr->getValueId();
  setPotentialOutputValues(potentialOutputs);
  getInliningInfo().setFlags(II_isMVLoggingInlined);

  // for push down
  if ( ((getOperatorType() == REL_UNARY_UPDATE)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_UPDATE) == DF_ON) || 
       ((getOperatorType() == REL_UNARY_DELETE)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_DELETE) == DF_ON) || 
       ((getOperatorType() == REL_UNARY_INSERT)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_INSERT) == DF_ON) )
      getInliningInfo().setFlags(II_isUsedForMvLogging);
}

//////////////////////////////////////////////////////////////////////////////
// Insert the OLD and NEW values into the MV IUD Log
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::createMvLogInsert(BindWA   *bindWA, 
					  CollHeap *heap,
					  UpdateColumns *updatedColumns,
					  NABoolean projectMidRangeRows)
{
  MvIudLog logTableObj(this, bindWA);
  logTableObj.setUpdatedColumns(updatedColumns);
  RelExpr *insertNode = logTableObj.buildInsert(TRUE,
                                                ChangesTable::ALL_ROWS,
                                                FALSE,
                                                TRUE);

  if (bindWA->errStatus())
    return NULL;

  prepareForMvLogging(bindWA, heap);

  if (projectMidRangeRows)
  {
    // Set the flag on this node.
    // This flag should be set even when range logging is off.
    getInliningInfo().setFlags(II_ProjectMidRangeRows);
  }

  RelExpr *topNode = insertNode;
  if (logTableObj.needsRangeLogging() && projectMidRangeRows)
  {
    // dead code, range logging is not supported
    RelRoot *rootNode = new (heap) RelRoot(insertNode);
    rootNode->setEmptySelectList();

    ItemExpr *noIgnoreCondition = new(heap)
      BiRelat(ITM_NOT_EQUAL,
	      new(heap) ConstValue(ComMvRowType_MidRange),
	      new(heap) ColReference(new(heap) 
		ColRefName(InliningInfo::getRowTypeVirtualColName())) );

    //  for the "else" of the 'when clause'
    ItemExpr *noOpArg  = new (heap) ConstValue(0);
    RelExpr  *noOp     = new (heap) Tuple(noOpArg);
    RelRoot  *noOpRoot = new (heap) RelRoot(noOp);
    noOpRoot->setEmptySelectList();
	      
    Union *ifNode = new(heap) Union
      (rootNode, noOpRoot, NULL, noIgnoreCondition, REL_UNION,
       CmpCommon::statementHeap(), TRUE);
    ifNode->setCondUnary();

    topNode = ifNode;
  }

  RelRoot *rootNode = new (heap) RelRoot(topNode);
  rootNode->setEmptySelectList();
  rootNode->getInliningInfo().setFlags(II_ActionOfRI); 

  return rootNode;
}

// This helper function is called only from GenericUpdate::handleInlining and GenericUpdate::getTriggeredMVs
// It checks if we are compiling a NOT ATOMIC statement as raises the appropriate
// error/warning. A warning is raised for ODBC and the statement will be compiled as an 
// ATOMIC statement. This method retuns TRUE if an error is raised and returns FALSE otherwise
NABoolean GenericUpdate::checkForNotAtomicStatement(BindWA *bindWA, Lng32 sqlcode, NAString objname, NAString tabname)
{
  if (bindWA->getHostArraysArea() &&
	    bindWA->getHostArraysArea()->getTolerateNonFatalError()) {
      
      if (CmpCommon::getDefault(ODBC_PROCESS) != DF_ON) {
	*CmpCommon::diags() << DgSqlCode(-sqlcode) 
	  << DgString0(objname) 
	  << DgString1(tabname);
	bindWA->setErrStatus();
	return TRUE;
      }
      else {
	bindWA->getHostArraysArea()->setTolerateNonFatalError(FALSE);
	setTolerateNonFatalError(RelExpr::UNSPECIFIED_);
	*CmpCommon::diags() << DgSqlCode(sqlcode)
	  << DgString0(objname) 
	  << DgString1(tabname);
      }

    }
  return FALSE ;
}
 
/*****************************************************************************
******************************************************************************
****  Methods for handling ON STATEMENT MVs
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// This method inserts for each ON STATEMENT MV, that is affected by the
// action at the IUD node, a MVImmediate trigger(s) to the list of triggers to
// be fired on the subject table. These MVImmediate triggers are responsible for
// refreshing the MVs.
//
// The algorithm is as follows:
//
// 1. get list of MVs defined on the subject table
// 2. for each MV in the list do
//    2.1 ensure refresh type is "ON STATEMENT" - if not, skip MV
//    2.2 verify that the MV is initialized - if not, skip MV
//    2.3 add MV to the list of triggers (call insertMvToTriggerList)
//
// For now, only ON STATEMENT MJVs are supported!!!
//
//////////////////////////////////////////////////////////////////////////////
BeforeAndAfterTriggers *
GenericUpdate::getTriggeredMvs(BindWA                 *bindWA,
			       BeforeAndAfterTriggers *list,
			       UpdateColumns          *updatedColumns)
{
  CollHeap *heap = bindWA->wHeap();

  const NATable *subjectNA = tabId_->getNATable();
  CMPASSERT(subjectNA != NULL);

  const UsingMvInfoList &mvList = subjectNA->getMvsUsingMe();
  if (mvList.isEmpty())
  {
    // No MVs are to be refreshed - return the given list as is
    return list;
  }
   else {  //check for any non-atomic statements
     const PartitioningFunction *partFunc =
       subjectNA->getClusteringIndex()->getPartitioningFunction();


     for (CollIndex i = 0; i < mvList.entries(); i++)
       {
	 if ((CmpCommon::getDefault(NAR_DEPOBJ_ENABLE2) == DF_OFF) ||
	     ((partFunc->isARangePartitioningFunction())))

	   {
	     if (checkForNotAtomicStatement(bindWA,30033,
					    (mvList[i]->getMvName()).getQualifiedNameAsAnsiString(),
					    (subjectNA->getTableName()).getQualifiedNameAsAnsiString()))
	       {
		 return list;
	       } 
	   }
	
	 if (isNoRollback() ||
	     (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) {
	   *CmpCommon::diags() << DgSqlCode(-3232) 
			       << DgString0((subjectNA->getTableName()).getQualifiedNameAsAnsiString()) 
			       << DgString1("Materialized View :")
			       << DgString2((mvList[i]->getMvName()).getQualifiedNameAsAnsiString());
	   bindWA->setErrStatus();

	   return list ;
	 }
       }
   }


  // If the given list of triggers is still empty, allocate a new one for the
  // new MVImmediate trigger(s) that might be added
  BeforeAndAfterTriggers *newList = list;
  if (newList == NULL)
  {
    newList = new(heap)
      BeforeAndAfterTriggers(NULL, NULL, NULL, subjectNA->getRedefTime());
  }

  // Search for MVs that should be refreshed
  for (CollIndex i = 0; i < mvList.entries(); i++)
  {
    // If MV is not ON STATEMENT - skip it
    if (mvList[i]->getRefreshType() != COM_ON_STATEMENT)
    {
      continue;
    }

    // If MV not intialized - skip it
    if (!mvList[i]->isInitialized())
    {
      continue;
    }

    // Retreive NATable of the MV. Return on error.
    CorrName mvCorr = CorrName(mvList[i]->getMvName(), heap);
    NATable *naTableMv = bindWA->getNATable(mvCorr);
    if (bindWA->errStatus())
    {
      return list;
    }

    // Retreive MVInfo for the MV. Return on error.
    MVInfoForDML *mvInfo = naTableMv->getMVInfo(bindWA);
    if (mvInfo == NULL)
    {
      return list;
    }

    // For now, only ON STATMENET MJVs are supported!
    if (mvInfo->getMVType() != COM_MJV)
    {
      continue;
    }

    if (bindWA->getTopRoot() != NULL)
      bindWA->getTopRoot()->setContainsOnStatementMV(TRUE);

    // The MV have passed all the general pre-conditions. Do some specific
    // checks and if it passes, add it to the triggers list.
    insertMvToTriggerList(newList,
			  bindWA,
			  heap,
			  mvList[i]->getMvName(),
			  mvInfo,
			  getTableName().getQualifiedNameObj(),
			  updatedColumns);
  }

  if (newList->entries() == 0)
  {
    //"newList" will be freed by statementHeap
    // add code annotation to prevent Coverity RESORUCE_LEAK checking error
    // coverity[leaked_storage]
    return NULL; // the list doesn't contain any triggers
  }

  // If there are only immediate MVs but not triggers, and this is an 
  // embedded IUD statement, abort with an error.
  if (list == NULL &&
      (getGroupAttr()->isEmbeddedUpdateOrDelete() || getGroupAttr()->isEmbeddedInsert()))
  {
    *CmpCommon::diags() << DgSqlCode(-12118);
    bindWA->setErrStatus();
    return NULL;
  }

  return newList; // return the updated list (including added MVs, if any)
}

//////////////////////////////////////////////////////////////////////////////
// This method does the actual insertion of the MVImmediate trigger to the
// list of triggers to be fired. Implemented only for derived classes!
//
//////////////////////////////////////////////////////////////////////////////

// we are not supposed to get here
void GenericUpdate::insertMvToTriggerList(BeforeAndAfterTriggers *list,
					  BindWA                 *bindWA,
					  CollHeap               *heap,
					  const QualifiedName    &mvName,
					  MVInfoForDML           *mvInfo,
					  const QualifiedName    &subjectTable,
					  UpdateColumns          *updateCols)
{
  CMPASSERT(false); // not implemented in GenericUpdate
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineOnlyRIandIMandMVLogging(BindWA *bindWA,
						      RelExpr *topNode,
						      NABoolean needIM,
						      RefConstraintList *riConstraints, 
						      NABoolean isMVLoggingRequired,
						      UpdateColumns *columns, 
						      CollHeap *heap)
{
  RelExpr *imTree = NULL;
  RelExpr *undoTree = NULL;
  RelExpr *riTree = NULL;
  RelExpr *mvTree = NULL;
  RelExpr *result = NULL;

  if (needIM || (riConstraints!=NULL) || isMVLoggingRequired)
  {
    if (topNode->getFirstNRows() >= 0)
	{
	  // create a firstN node to delete N rows.
	  FirstN * firstn = new(bindWA->wHeap())
	    FirstN(topNode, topNode->getFirstNRows(), FALSE /* No ordering requirement */);
	  firstn->bindNode(bindWA);
	  if (bindWA->errStatus())
	    return NULL;

	  topNode->setFirstNRows(-1);
	  topNode = firstn;
	}
  }
  // Create the tree that handles Index Maintainance.
  if (needIM)
    {
      // here we don't use the internal syskey column name ("@SYSKEY") since the
      // whole backbone is driven by the IUD node on the subject table
      imTree = createIMTree(bindWA, columns, FALSE);

    }
  

  // Create the tree that handles RI
  if (riConstraints!=NULL)
    riTree = inlineRI(bindWA, riConstraints, heap);

  // Create the tree for MV Logging.
  if (isMVLoggingRequired)
  {
    // When RI/IM/Triggers are not inlined, we can skip the projection of
    // the rows that are not Single/BeginRange/EndRange.
    NABoolean projectMidRangeRows = TRUE;
    if (imTree==NULL && riTree==NULL)
      projectMidRangeRows = FALSE;

    mvTree = createMvLogInsert(bindWA, heap, columns, projectMidRangeRows);
    if (mvTree != NULL)
    {
      // Use REL_SEMITSJ if it should not project any outputs
      // to the IM or RI trees.
      OperatorTypeEnum 
	joinType = (imTree || riTree) ? REL_LEFT_TSJ : REL_TSJ;
         NABoolean needsOutputs = isMtsStatement() ||
	  (getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_DELETE));
	if (needsOutputs && joinType == REL_TSJ)
	  joinType = REL_ANTI_SEMITSJ;
//	joinType = (imTree || riTree) ? REL_ANTI_SEMITSJ : REL_SEMITSJ;
  
	Join *logTSJ = new(heap) Join (topNode, mvTree, joinType);
	logTSJ->getInliningInfo().setFlags(II_DrivingMvLogInsert);
	logTSJ->setTSJForWrite(TRUE);

        if ( ((getOperatorType() == REL_UNARY_UPDATE)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_UPDATE) != DF_ON) ||
             ((getOperatorType() == REL_UNARY_DELETE)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_DELETE) != DF_ON) ||
             ((getOperatorType() == REL_UNARY_INSERT)  && CmpCommon::getDefault(MV_LOG_PUSH_DOWN_DP2_INSERT) != DF_ON) )
           logTSJ->setAllowPushDown (FALSE);

	if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError())
	  logTSJ->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
	topNode = logTSJ;
    }
  }

  result = imTree;
  if (riTree != NULL)
  {
    if (result == NULL)
    {
      result = riTree;
    }
    else
    {
      result = new (heap) Union(imTree, riTree, NULL, NULL, REL_UNION,
                                CmpCommon::statementHeap(), TRUE);
    }
  }
 
 // For NAR , generate an undo tree as well
  if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError() && (imTree || riTree)) 
    undoTree = createUndoTree(bindWA,columns,FALSE,(imTree||riTree),isMVLoggingRequired,NULL);
   if (undoTree && result)
    {
      OperatorTypeEnum joinType= REL_TSJ;
      Join * joinResultUndo = new (heap) Join(result,undoTree,joinType);      
      joinResultUndo->setTSJForWrite(TRUE);
      joinResultUndo->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      joinResultUndo->setTSJForUndo(TRUE); 
      result = joinResultUndo;
    }
  
  
   if (bindWA->isTrafLoadPrep())
     return result ;


  if (result!=NULL)
  {
    // This RelRoot opens a new BindScope, so that Union::bindChildern()
    // will not overwrite the RETDesc of the current scope with the NEW 
    // and OLD values.
    RelRoot *rootNode = new(heap) RelRoot(result);
    rootNode->setRootFlag(FALSE);
    rootNode->setEmptySelectList();

    OperatorTypeEnum joinOp;
    if ((topNode->child(0).getGroupAttr()->getEmbeddedIUD()) ||
	isMtsStatement() || // This is an embedded IUD statement 
	                   // (i.e. an IUD statement that has an outer select)
	(getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_DELETE)))  
    {
      // originally index maintenance was using a TSJ joining the
      // tuples to be deleted from the base table with the tuples to
      // be deleted in the invidual indices. When returning tuples to
      // the user this causes the tuples to be deleted multiplied by
      // the number of indices. Therefore we now use an ANTI_SEMITSJ 
      // which does not require LeafDeletes to return tuples...i.e. it 
      // only return the leaf tuple if nothing is returned from the right 
      // child...this is what we want.
      joinOp = REL_ANTI_SEMITSJ;
    }
    else
    {
      joinOp = REL_TSJ;
    }

    Join *newTSJ = new(heap) Join (topNode, rootNode, joinOp);
    topNode = newTSJ;
  }
  
  ((Join *)topNode)->setTSJForWrite(TRUE);

  if (isMerge())
    {
      ((Join *)topNode)->setTSJForMerge(TRUE);

      if (isMergeUpdate())
	{
	  if (((MergeUpdate*)this)->insertValues())
	    ((Join *)topNode)->setTSJForMergeWithInsert(TRUE);
	}
      else
	{
	  if (((MergeDelete*)this)->insertValues())
	    ((Join *)topNode)->setTSJForMergeWithInsert(TRUE);
	}
    }

  if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError())
    { 
      ((Join *)topNode)->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      ((Join *)topNode)->setTSJForSetNFError(TRUE);
    }
  return topNode;
    
}

/*****************************************************************************
******************************************************************************
****  The "main" methods of inlining.
****  Build the trigger backbone and handle all the special cases.
******************************************************************************
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineAfterOnlyBackbone(BindWA *bindWA, 
						TriggersTempTable& tempTableObj,
						TriggerList *rowTriggers,
						TriggerList *stmtTriggers,
						RefConstraintList *riConstraints,
						NABoolean needIM,
						NABoolean isMVLoggingRequired,
						UpdateColumns *updatedColumns,
						CollHeap *heap)
{





  RelExpr   *topNode = this;
  if (topNode->getFirstNRows() > 0)
  {
    // create a firstN node to delete N rows.
    FirstN * firstn = new(bindWA->wHeap())
      FirstN(topNode, topNode->getFirstNRows(), FALSE /* No ordering requirement */);
    firstn->bindNode(bindWA);
    if (bindWA->errStatus())
      return NULL;

    topNode->setFirstNRows(-1);
    topNode = firstn;
  }
  
  NABoolean noPipelinedActions = 
    (rowTriggers == NULL) && (riConstraints == NULL);

  NABoolean rowTriggersPresent = (rowTriggers != NULL);

  // First inline MV logging, so it will be pushed to DP2 with the IUD.
  if (isMVLoggingRequired)
  {
    RelExpr *mvTree = createMvLogInsert(bindWA, heap, updatedColumns, TRUE);
    if (mvTree != NULL)
    {
      Join *logTSJ = new(heap) Join(topNode, mvTree, REL_LEFT_TSJ);
      logTSJ->setTSJForWrite(TRUE);
      logTSJ->getInliningInfo().setFlags(II_DrivingMvLogInsert);
      if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError())
	logTSJ->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      topNode = logTSJ;
    }
  }

  // Next inline Index Maintainance
  if (needIM)
  {
    // here we don't use the internal syskey column name ("@SYSKEY") since the
    // whole backbone is driven by the IUD node on the subject table
    topNode = inlineIM(topNode, bindWA, FALSE, updatedColumns, heap, FALSE, rowTriggersPresent);
  }

  // Next inline the temp Insert
  topNode = inlineTempInsert(topNode,
			     bindWA,
			     tempTableObj,
			     FALSE,
			     noPipelinedActions,
			     heap);
  if (bindWA->errStatus()) 
    return NULL;

  Insert *pTempInsert = (Insert *)(RelExpr *)(topNode->child(1)->child(0));
  CMPASSERT(pTempInsert->getOperatorType() == REL_LEAF_INSERT ||
            pTempInsert->getOperatorType() == REL_UNARY_INSERT  );

  // Inline RI and row triggers.
  topNode = inlinePipelinedActions(topNode, bindWA, 
				   rowTriggers, 
				   riConstraints, 
				   heap);

  // Inline statement triggers
  topNode = inlineTriggerGroup(topNode, stmtTriggers, FALSE, heap, bindWA);

  // Inline the Temp delete.
  topNode = inlineTempDelete(bindWA, topNode, tempTableObj, heap);
  ((Union *)topNode)->setBlockedUnion();
  ((Union *)topNode)->setNoOutputs();
  if (isMtsStatement())
   ((Union *)topNode)->setIsTemporary();
  
  // If we are in an NAR, then set the InNotAtomicStatement flag
  if (bindWA->getHostArraysArea() && 
      bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
    {
      ((Union *)topNode)->setInNotAtomicStatement();
    }

  if (bindWA->errStatus())
  {
     return this;
  }

  // Now bind the resulting tree
  topNode = topNode->bindNode(bindWA);
  if (bindWA->errStatus())
  {
    return this;
  }

  // store information for triggers transformation phase
  getInliningInfo().buildTriggerBindInfo(bindWA, getRETDesc(), heap);

  return topNode;
}




RelExpr *GenericUpdate::inlineAfterOnlyBackboneForUndo(BindWA *bindWA, 
						       TriggersTempTable&  tempTableObj,
						       TriggerList *rowTriggers,
						       TriggerList *stmtTriggers,
						       RefConstraintList *riConstraints,
						       NABoolean needIM,
						       NABoolean isMVLoggingRequired,
						       UpdateColumns *updatedColumns,
						       CollHeap *heap)
{
  RelExpr *imTree = NULL;
  RelExpr *undoTree = NULL;
  RelExpr *riTree = NULL;
  RelExpr *mvTree = NULL;
  RelExpr *result = NULL;
  RelExpr   *topNode = this;
  if (topNode->getFirstNRows() > 0)
    {
      // create a firstN node to delete N rows.
      FirstN * firstn = new(bindWA->wHeap())
	FirstN(topNode, topNode->getFirstNRows(), FALSE /* No ordering requirement */);
      firstn->bindNode(bindWA);
      if (bindWA->errStatus())
	return NULL;

      topNode->setFirstNRows(-1);
      topNode = firstn;
    }
  
  NABoolean noPipelinedActions = 
    (rowTriggers == NULL) && (riConstraints == NULL);

  NABoolean rowTriggersPresent = (rowTriggers != NULL);
 
  // create the temp insert tree here 
      
  RelExpr *tempInsertNode = tempTableObj.buildInsert(TRUE);
  RelRoot *tempInsRoot = new (heap) RelRoot(tempInsertNode);
  tempInsRoot->setRootFlag(FALSE);
  tempInsRoot->setEmptySelectList();

  if (isMVLoggingRequired)  
    mvTree = createMvLogInsert(bindWA, heap, updatedColumns, TRUE);
  
  
  if (mvTree != NULL)
    {
    
      RelRoot *mvRoot = new (heap) RelRoot(mvTree);	       
      if (mvRoot != NULL)
	{
	  Join *logTSJ = new(heap) Join(topNode, mvRoot, REL_LEFT_TSJ);     
	  logTSJ->setTSJForWrite(TRUE);
	  logTSJ->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
          logTSJ->getInliningInfo().setFlags(II_DrivingMvLogInsert);
	  topNode = logTSJ;
	}      
    }

  if (tempInsRoot != NULL)
    {
      Join *logTSJ = new(heap) Join(topNode, tempInsRoot, REL_LEFT_TSJ);     
      logTSJ->setTSJForWrite(TRUE);
      logTSJ->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      topNode = logTSJ;
    }
    
  
    

  // Create the tree that handles Index Maintainance.
  if (needIM)
    {
      // here we don't use the internal syskey column name ("@SYSKEY") since the
      // whole backbone is driven by the IUD node on the subject table
      imTree = createIMTree(bindWA, updatedColumns, FALSE);

    }
  // Create the tree that handles RI
  if (riConstraints!=NULL)
    riTree = inlineRI(bindWA, riConstraints, heap);

  result = imTree;
  if (riTree != NULL)
    {
      if (result == NULL)
	{
	  result = riTree;
	}
      else
	{
	  result = new (heap) Union(imTree, riTree, NULL, NULL, REL_UNION,
				    CmpCommon::statementHeap(), TRUE);
	}
    }
  undoTree = createUndoTree(bindWA,updatedColumns,FALSE,(imTree||riTree),isMVLoggingRequired, &tempTableObj);
  if (undoTree && result)
    {
      OperatorTypeEnum joinType= REL_TSJ;
      Join * joinResultUndo = new (heap) Join(result,undoTree,joinType);
      joinResultUndo->setTSJForWrite(TRUE);
      joinResultUndo->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      joinResultUndo->setTSJForUndo(TRUE); 
      result = joinResultUndo;
	 
    }

 

  if (result!=NULL)
    {
      // This RelRoot opens a new BindScope, so that Union::bindChildern()
      // will not overwrite the RETDesc of the current scope with the NEW 
      // and OLD values.
      RelRoot *rootNode = new(heap) RelRoot(result);
      rootNode->setRootFlag(FALSE);
      rootNode->setEmptySelectList();

      OperatorTypeEnum joinOp;
      if ((topNode->child(0).getGroupAttr()->getEmbeddedIUD()) ||
	  isMtsStatement())  // This is an embedded IUD statement 
	// (i.e. an IUD statement that has an outer select)
	{
	  // originally index maintenance was using a TSJ joining the
	  // tuples to be deleted from the base table with the tuples to
	  // be deleted in the invidual indices. When returning tuples to
	  // the user this causes the tuples to be deleted multiplied by
	  // the number of indices. Therefore we now use an ANTI_SEMITSJ 
	  // which does not require LeafDeletes to return tuples...i.e. it 
	  // only return the leaf tuple if nothing is returned from the right 
	  // child...this is what we want.
	  joinOp = REL_ANTI_SEMITSJ;
	}
      else
	{
	  joinOp = REL_TSJ;
	}

      Join *newTSJ = new(heap) Join (topNode, rootNode, joinOp);
      newTSJ->setTSJForWrite(TRUE);
	
      newTSJ->setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      newTSJ->setTSJForSetNFError(TRUE);      
      RelRoot *rootNode2 = new(heap) RelRoot(newTSJ);
      rootNode2->setRootFlag(FALSE);
      rootNode2->setEmptySelectList();
	  
      topNode = rootNode2;
    }
    // Inline statement triggers
     topNode = inlineTriggerGroup(topNode, stmtTriggers, FALSE, heap, bindWA);

    // Inline the Temp delete.
     topNode = inlineTempDelete(bindWA, topNode, tempTableObj, heap);
    ((Union *)topNode)->setBlockedUnion();
    ((Union *)topNode)->setNoOutputs();
    if (isMtsStatement())
      ((Union *)topNode)->setIsTemporary();

    // If we are in an NAR, then set the InNotAtomicStatement flag
    if (bindWA->getHostArraysArea() && 
        bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
      {
	((Union *)topNode)->setInNotAtomicStatement();
      }

    if (bindWA->errStatus())
      {
	return this;
      }

    // Now bind the resulting tree
    topNode = topNode->bindNode(bindWA);
    if (bindWA->errStatus())
      {
	return this;
      }

    // store information for triggers transformation phase
    getInliningInfo().buildTriggerBindInfo(bindWA, getRETDesc(), heap);
 
    return topNode;
   
}
//////////////////////////////////////////////////////////////////////////////
// Remove from the inputs of 'node' any ValueIds that do not reference 
// any of the values in realInputs.
//////////////////////////////////////////////////////////////////////////////
static void minimizeInputsForNode(RelExpr *node, ValueIdSet &realInputs)
{
  ValueIdSet inputsOfNode(node->getGroupAttr()->getCharacteristicInputs());
  realInputs.weedOutUnreferenced(inputsOfNode);
  node->getGroupAttr()->setCharacteristicInputs(inputsOfNode);
}

//////////////////////////////////////////////////////////////////////////////
// For each and every node in 'subtree' call minimizeInputsForNode()
// to remove the redundant inputs.
//////////////////////////////////////////////////////////////////////////////
static void minimizeInputsForSubtree(RelExpr *subtree, ValueIdSet &realInputs)
{
  minimizeInputsForNode(subtree, realInputs);

  for (Int32 i=0; i<subtree->getArity(); i++)
    minimizeInputsForSubtree(subtree->child(i), realInputs);
}

//////////////////////////////////////////////////////////////////////////////
// The binding process adds redundant inputs to the temp insert subtree.
// This usually works out in the transformation and normalization, but
// when the triggering action is an Update with sub-queries - it does not.
// The real inputs for the temp insert subtree, are the OLD values, plus 
// the UniqueExecuteId. Remove from thecharacteristic inputs of every node
// of the temp insert subtree, all the values that do not reference the
// real inputs as defined above.
//////////////////////////////////////////////////////////////////////////////
void GenericUpdate::removeRedundantInputsFromTempInsertTree(BindWA  *bindWA, 
							    RelExpr *tentativeSubtree)
{
  // The OLD values are the outputs of the Scan node below the triggering IUD 
  // node (this node).
  Scan *scanNode = getScanNode();
  CMPASSERT(scanNode != NULL);
  ValueIdSet realInputs(scanNode->getGroupAttr()->getCharacteristicOutputs());

  // All instantiations of the UniqueExcuteId funcction have the same ValueId.
  // Once the transformation code changes are merged in, we can take the ExecId
  // ValueId from the BindInfo.
  ItemExpr *execId = new(bindWA->wHeap()) UniqueExecuteId();
  execId->bindNode(bindWA);
  realInputs += execId->getValueId();

  // Find the top node of the temp insert subtree.(through the RelRoot and TSJ).
  RelExpr *tempInsertNode = tentativeSubtree->child(0)->child(1);
  CMPASSERT(tempInsertNode->getOperatorType() == REL_ROOT);
  CMPASSERT(tempInsertNode->child(0)->getOperatorType() == REL_UNARY_INSERT);

  // Now remove the redundant inputs.
  minimizeInputsForSubtree(tempInsertNode, realInputs);
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
RelExpr *GenericUpdate::inlineBeforeAndAfterBackbone(BindWA *bindWA, 
						     RelExpr *tentativeSubtree,
						     TriggersTempTable& tempTableObj,
						     TriggerList *rowTriggers,
						     TriggerList *stmtTriggers,
						     RefConstraintList *riConstraints,
						     NABoolean needIM,
						     NABoolean isMVLoggingRequired,
						     UpdateColumns *updatedColumns,
						     CollHeap *heap)
{
  // Create the effective Insert, Update or Delete node.
  GenericUpdate *effectiveGuNode = NULL;
  RelExpr *effectiveGuRootNode = 
    createEffectiveGU(bindWA, heap, tempTableObj, &effectiveGuNode, updatedColumns);

  CMPASSERT(effectiveGuNode != NULL);

  RelExpr *topNode = effectiveGuRootNode;
  // used by the generator to indicate that this plan has triggers so
  // if the trigger is dropped the plan is recompiled
  topNode->getInliningInfo().setFlags(II_hasTriggers);

  // We only use the FiringTriggers flag if this GU will have to generate
  // the NEW and OLD values for Row triggers, RI or IM.
  if (getInliningInfo().hasPipelinedActions())
  {
    effectiveGuNode->getInliningInfo().setFlags(II_hasPipelinedActions); 
  }

  // First inline MV logging, so it will be pushed to DP2 with the IUD.
  if (isMVLoggingRequired)
  {
    RelExpr *mvTree = createMvLogInsert(bindWA, heap, updatedColumns, TRUE);
    if (mvTree != NULL)
    {
      OperatorTypeEnum joinType = REL_LEFT_TSJ;
      if (!rowTriggers && !riConstraints && !needIM)
	joinType = REL_TSJ;
      Join *logTSJ = new(heap) Join(topNode, mvTree, joinType);
      logTSJ->setTSJForWrite(TRUE);

      // disable parallele execution for TSJs that control row triggers
      // execution. Parallel execution for triggers TSJ introduces the
      // potential for non-deterministic execution
      if (rowTriggers)
        logTSJ->getInliningInfo().setFlags(II_SingleExecutionForTriggersTSJ);

      topNode = logTSJ;
    }
  }

  if (needIM)
  {
    // Next inline Index Maintainance
    NABoolean imIsLastTSJ = ((rowTriggers==NULL) && (riConstraints==NULL));
    // here we do use the internal syskey column name ("@SYSKEY") since the
    // whole backbone is driven by the temp-table insert node

    NABoolean rowTriggersPresent = (rowTriggers != NULL);

    if (getOperatorType() == REL_UNARY_INSERT)
    {
       topNode = inlineIM(topNode, bindWA, imIsLastTSJ, updatedColumns, 
                          heap, FALSE, rowTriggersPresent);
    }
    else  // REL_UNARY_UPDATE or REL_UNARY_DELETE
    { 
       topNode = inlineIM(topNode, bindWA, imIsLastTSJ, updatedColumns, 
                          heap, TRUE, rowTriggersPresent);
    }
  }

  // Next inline RI and row triggers (temp Insert is on the tentative side).
  topNode = inlinePipelinedActions(topNode,
                                   bindWA, 
				   rowTriggers, 
				   riConstraints, 
				   heap);

  // Inline statement triggers
  topNode = inlineTriggerGroup(topNode, stmtTriggers, FALSE, heap, bindWA);

  // Inline the Temp delete.
  topNode = inlineTempDelete(bindWA, topNode, tempTableObj, heap);
  topNode->getInliningInfo().setFlags(II_BeforeTriggersExist);

  // Open a new scope for the after-trigger part.
  topNode = new(heap) RelRoot(topNode); 
  ((RelRoot *)topNode)->setRootFlag(FALSE);

  // Join the two parts of the backbone using a blocked Union node.
  Union *topUnion = new(heap) Union(tentativeSubtree, topNode, NULL, NULL,
                                    REL_UNION, CmpCommon::statementHeap(),
                                    TRUE);
  topUnion->setBlockedUnion();
  topUnion->setNoOutputs();
  topUnion->getInliningInfo().setFlags(II_DrivingBeforeTriggers);
 
  // If we are in an NAR, then set the InNotAtomicStatement flag
  if (bindWA->getHostArraysArea() && 
      bindWA->getHostArraysArea()->getTolerateNonFatalError()) 
    {
	topUnion->setInNotAtomicStatement();
    }
  
  topNode = topUnion;

  // Now bind the resulting tree
  topNode = topNode->bindNode(bindWA);
  if (bindWA->errStatus())
    return this;

  // store information for triggers transformation phase
  InliningInfo &info = effectiveGuNode->getInliningInfo();

  if (!(info.hasPipelinedActions()) && getOperatorType() != REL_UNARY_UPDATE)
  {
     // case of before triggers and after statement triggers where the after triggers are in conflict
     // and the effective GU is either an insert or a delete.
     info.getTriggerBindInfo()->setBackboneIudNum(bindWA->getUniqueIudNum());
  }
  else
  {
     info.buildTriggerBindInfo(bindWA, effectiveGuRootNode->getRETDesc(), heap);
  }


  // The binding process adds redundant inputs to the temp insert subtree.
  // This usually works out in the transformation and normalization, but
  // when the triggering action is an Update with sub-queries - it does not.
  if (getOperatorType() == REL_UNARY_UPDATE)
    removeRedundantInputsFromTempInsertTree(bindWA, tentativeSubtree);

  return topNode;
}

//////////////////////////////////////////////////////////////////////////////
// Is this backbone cascaded from a row trigger?
//////////////////////////////////////////////////////////////////////////////
NABoolean GenericUpdate::shouldForbidMaterializeNodeHere(BindWA *bindWA)
{
  // If this backbone is cascaded from a row after trigger, Do not allow the
  // optimizer to use any Materialize nodes below this point.
  BindScope *triggerScope = NULL;
  // Skip this if the flag was already set by a trigger above us.
  if (!getInliningInfo().isMaterializeNodeForbidden())
  {
    // For each scope above us, that has a trigger object
    while ((triggerScope = bindWA->findNextScopeWithTriggerInfo(triggerScope))
           != NULL)
    {
      StmtDDLCreateTrigger* triggerObj = triggerScope->context()->triggerObj();
      // If its not a row after trigger - continue searching.
      if (triggerObj->isStatement() || !triggerObj->isAfter())
	continue;

      return TRUE;
    }
  }

  return FALSE;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void GenericUpdate::InliningFinale(BindWA *bindWA, RelExpr *topNode, 
                                   RETDesc *origRETDesc)
{
  // QSTUFF
  // this expression is executed once all inlining and binding 
  // for index maintenance, RI and triggers has been done. We replace the 
  // current scope with a RETDesc containing references to old and new column
  // values as can be referenced in the return clause of an embedded delete or
  // and embedded update 
  
  if (getGroupAttr()->isEmbeddedUpdateOrDelete() ||
      isMtsStatement() ||
      (getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_DELETE)))
    {
      
      // lets only return the implicit old and new table columns
      if (!getRETDesc()) delete getRETDesc();
      
      CorrName corrNEWTable
	(getTableDesc()->getCorrNameObj().getQualifiedNameObj(), 
	 bindWA->wHeap(),NEWTable);
      
      if (getOperatorType() == REL_UNARY_UPDATE  ||
	  getOperatorType() == REL_UNARY_INSERT){
	// expose NEW table columns
	setRETDesc(new (bindWA->wHeap()) 
		   RETDesc(bindWA,getTableDesc(),&corrNEWTable));
      }
      else
	setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));
      
      if (getOperatorType() == REL_UNARY_UPDATE ||
	  getOperatorType() == REL_UNARY_DELETE)
	{
	  CorrName corrOLDTable
	    (getScanNode(TRUE)->getTableDesc()->getCorrNameObj().getQualifiedNameObj(), 
	     bindWA->wHeap(),OLDTable
	     );
	  
	  // expose OLD table columns
	  getRETDesc()->
	    addColumns(bindWA, *getScanNode(TRUE)->getRETDesc(), &corrOLDTable);
	  
	}
      
      // allow the TSJRule to be used to transform Updates/Deletes
      setNoFlow(TRUE);
      
      // record the GenericUpdateRoot property in the group
      // attributes of the root of the generic update tree.
      // this is used by pushdowncovered expression to prevent
      // expression to be push beyond the root of a generic update
      // tree
      topNode->getGroupAttr()->setGenericUpdateRoot(TRUE);
      
      // set current scope to contain NEW and OLD tables only               
      origRETDesc = getRETDesc();       
    }
  
  if (bindWA->inDDL())
    return;
  
  //QSTUFF

  ValueIdList outputs;
  getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
  addPotentialOutputValues(outputs);

  // If ever extend the SQL syntax to such non-Ansi constructs as
  // INSERT INTO TI (DELETE FROM TD ... );
  //		SELECT * FROM (UPDATE TU SET ... ) X;
  // then we'll want to revisit these next two lines,
  // (resetting our RETDesc to an empty one) because otherwise
  // this nonempty one'll become our parent RelRoot's compExpr(),
  // which will cause 
  // 		RelRoot::preCodeGen - compExpr().replaceVEGExpressions - 
  //		VEGReference::replaceVEGReference
  // to assert with "no available values hence valuesToBeBound.isEmpty".
  //
  // QSTUFF
  // please see above..we made the extensions and did fixed whats 
  // referred to above
  // select * from (delete from x)y, z where y.x = z.x;
  // select * from (update x set x = x + 1) y, z where y.x = z.x;
  if (!getGroupAttr()->isEmbeddedUpdateOrDelete() &&
      !isMtsStatement() &&
      !(getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_DELETE)))
  {
    delete getRETDesc();
    setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));
  }

    // QSTUFF
  topNode->setRETDesc(getRETDesc());
  bindWA->getCurrentScope()->setRETDesc(origRETDesc);
}

// Helper function used to check the existence of at least one update
// trigger whose explicit columns match at least one of the columns
// supplied as a second parameter
NABoolean atLeastOneMatch(const BeforeAndAfterTriggers *allTriggers,
                          const UpdateColumns *columns)
{
    TriggerList *trigs = NULL;

    assert(allTriggers != NULL);

    // check the before row triggers for a match
    if (allTriggers->getBeforeTriggers() != NULL)
    {
       trigs = 
         allTriggers->getBeforeTriggers()->getColumnMatchingTriggers (columns);
    }

    // check the after row triggers for a match
    if ((trigs == NULL) && (allTriggers->getAfterRowTriggers() != NULL))
    {
       trigs = 
        allTriggers->getAfterRowTriggers()->getColumnMatchingTriggers (columns);
    }

    // check the after statement triggers for a match
    if ((trigs == NULL) && (allTriggers->getAfterStatementTriggers() != NULL))
    {
       trigs = 
        allTriggers->getAfterStatementTriggers()->getColumnMatchingTriggers (columns);
    } 

    // at least one match was found
    if (trigs != NULL)
    {
       return TRUE;
    }

    // no match
    return FALSE;
}

NABoolean GenericUpdate::checkNonSupportedTriggersUse(BindWA *bindWA, 
                           QualifiedName &subjectTable,
                           ComOperation op,
                           BeforeAndAfterTriggers *allTriggers)
{
  CollHeap *heap = bindWA->wHeap();

  // disable embedded update and delete as trigger events
  if ((allTriggers != NULL) && (getGroupAttr()->isEmbeddedUpdateOrDelete()))
  {
       // for update operations we have to make sure that there is at least
       // one trigger defined on the column updated by the operation
       if (op == COM_UPDATE)
       {
           // Get the list of updated columns.
           UpdateColumns *columns = new(heap) UpdateColumns(stoi_->getStoi());

           // find at least one trigger that is fired by the columns updated
           // by this operation 
           if (atLeastOneMatch(allTriggers, columns))
           {
               *CmpCommon::diags() << DgSqlCode(-11027);
               bindWA->setErrStatus();
               // "columns" will be freed by statementHeap. 
               // add code annotation to prevent Coverity checking error
               // coverity[leaked_storage]
               return TRUE;
           }
                 
       }
       else // delete - all delete triggers are considered
       {
           *CmpCommon::diags() << DgSqlCode(-11027);
           bindWA->setErrStatus();
           return TRUE;
       }

  }

  // disable embedded insert as trigger events
  if ((allTriggers != NULL) && (getGroupAttr()->isEmbeddedInsert()))
  {
    *CmpCommon::diags() << DgSqlCode(-11027);
    bindWA->setErrStatus();
    return TRUE;
  }

  // the set clause of SET ON ROLLBACK statements may not change
  // columns on which update triggers are defined 
  if (newRecBeforeExpr() != NULL)
  {
        BeforeAndAfterTriggers *allTriggers2 = allTriggers;

        // for SET ON ROLLBACK delete statements, we are not interested
        // in the triggers fired by the delete operation but rather by the
        // triggers defined on the columns updated by the SET ON ROLLBACK
        // clause. These triggers are update triggers not delete triggers.
        if (op == COM_DELETE)
        {
           ComOperation op2 = COM_UPDATE;
           allTriggers2 =
               bindWA->getSchemaDB()->getTriggerDB()->getTriggers(subjectTable,
                                         op2, bindWA);
           if (bindWA->errStatus())
             return TRUE;   
        }

        if (allTriggers2 != NULL)
        {
            ValueId exprId;
            UpdateColumns *columns = 
                        new(heap) UpdateColumns((SqlTableOpenInfo *)NULL);
            for (exprId = newRecBeforeExpr().init(); 
               newRecBeforeExpr().next(exprId); 
               newRecBeforeExpr().advance(exprId))
            {
                 ItemExpr *thisIE = exprId.getItemExpr();
                 columns->addColumn((thisIE->child(0).getNAColumn())->getPosition());
            }

           // if at least one of the columns updated in SET ON ROLLBACK clause 
           // of the SET ON ROLLBACK statement is a subject column of an update
           //  trigger, raise an error message
           if (atLeastOneMatch(allTriggers2, columns))
           {
               *CmpCommon::diags() << DgSqlCode(-11026);
               bindWA->setErrStatus();
               // "columns" will be freed by statementHeap. 
               // add code annotation to prevent Coverity checking error
               // coverity[leaked_storage]
               return TRUE;   
           }
       }
  }

  return FALSE;
}

//////////////////////////////////////////////////////////////////////////////
// Handle the inlining of Triggers, RI, IM, MV logging and ON STATEMENT MVs.
// This method is called from the end of the bindNode() methods of Insert,
// Update and Delete.
// The trigger backbone is different if before triggers exist.
// Please read the Triggers internal documentation before trying to understand
// this code.
//////////////////////////////////////////////////////////////////////////////
RelExpr * GenericUpdate::handleInlining(BindWA *bindWA, RelExpr *boundExpr)
{
  RETDesc  *origScopeRETDesc = bindWA->getCurrentScope()->getRETDesc();
  CorrName &subjectTableCorr = getTableDesc()->getCorrNameObj();

  if (bindWA->inDDL())
  {
    // some QSTUFF code in inlineingFinale() should be executed when we
    // are in create view statement.
    InliningFinale(bindWA, boundExpr, origScopeRETDesc);
    return boundExpr;
  }

  // MultiCommit is currently only valid for DELETE statements
  if (NOT getOperator().match(REL_ANY_DELETE)
      &&
      CmpCommon::transMode()->getMultiCommit() == TransMode::MC_ON_)
    {
      *CmpCommon::diags() << DgSqlCode(-4351);	 
      bindWA->setErrStatus();  
      return boundExpr;
    }
  
  // We don't do views.
  // ignore location specified operations.
  if ( (getTableDesc()->getNATable()->getViewText() != NULL) ||
       (subjectTableCorr.isLocationNameSpecified() ))
    return boundExpr;

  if (subjectTableCorr.getSpecialType() == ExtendedQualName::SG_TABLE)
    {
      InliningFinale(bindWA, boundExpr, origScopeRETDesc);
      return boundExpr;  // Nothing for us to do here.
    }

  // A "DELETE [FIRST n] FROM <IUD-log-table>"
  // is the only case we allow a special table through here.
  NABoolean firstN_OnIudLogTable = FALSE;
  if ((subjectTableCorr.getSpecialType() == ExtendedQualName::IUD_LOG_TABLE) &&
      (getFirstNRows() > 0) )
    firstN_OnIudLogTable = TRUE;

  // Don't waste time on special tables like index etc.
  // The IUD log is allowed here because we allow delete with multi commit on it.
  if ((subjectTableCorr.getSpecialType() != ExtendedQualName::NORMAL_TABLE) &&
      (subjectTableCorr.getSpecialType() != ExtendedQualName::MV_TABLE)     &&
      !firstN_OnIudLogTable                                                 &&
      !getInliningInfo().isNeedGuOutputs() )
    return boundExpr;

  // no inlining for the effective GU of a before trigger
  if (getInliningInfo().isEffectiveGU())
    return bindEffectiveGU(bindWA);

  if (getInliningInfo().isNeedGuOutputs())
  {
    // The OLD/NEW outputs of this GU node are needed for some purpose
    // other than triggers/RI/IM etc.
    createOldAndNewCorrelationNames(bindWA);

    ValueIdList outputs;
    getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
    setPotentialOutputValues(outputs);

    setNoFlow(TRUE);

    return boundExpr;
  }

  // If code future changes cause this assertion to fail, we need to make
  // sure our code still works.
  CMPASSERT(boundExpr == this);

  ComOperation op;
  switch (getOperatorType()) 
  {
    case REL_UNARY_INSERT: op = COM_INSERT; break;
    case REL_UNARY_UPDATE: op = COM_UPDATE; break;
    case REL_UNARY_DELETE: op = COM_DELETE; break;
    default : return boundExpr;  // We only handle these three operators.
  }

  CollHeap *heap = bindWA->wHeap();
  QualifiedName& subjectTable = subjectTableCorr.getQualifiedNameObj();

  // get all triggers in the triggerDB, and RIs from the SchemaDB.
#if DISABLE_TRIGGERS
  BeforeAndAfterTriggers *allTriggers = NULL;
#else
  BeforeAndAfterTriggers *allTriggers = 0;

     if ((isIgnoreTriggers() == FALSE) && !firstN_OnIudLogTable )
  {
    if (getUpdateCKorUniqueIndexKey())
    {
      // if this the delete node of updateCKorUniqueIndexKey then skip
      // inlining triggers altogether (allTriggers remains NULL).
      if (op == COM_INSERT)
      {
	op = COM_UPDATE;
	allTriggers = bindWA->getSchemaDB()->getTriggerDB()->getTriggers(subjectTable, op, bindWA);
      }
    }
    else
      {
	allTriggers = bindWA->getSchemaDB()->getTriggerDB()->getTriggers(subjectTable, op, bindWA);

	if ((allTriggers == NULL) && (isMerge()))
	  {
	    // Triggers are not supported with Merge statement.
	    // if update part of merge didn't cause any triggers to be inlined,
	    // check for insert triggers.
	    // These triggers will be inlined here but an error will be
	    // returned during preCodeGen.
	    allTriggers = bindWA->getSchemaDB()->getTriggerDB()->getTriggers(
		 subjectTable, COM_INSERT, bindWA);
	  }
      }
  }
#endif

  if (bindWA->errStatus())
     return NULL;

  if (allTriggers) {
    getInliningInfo().setFlags(II_hasTriggers);
    bindWA->setInTrigger();
  }

  // certain triggers uses are currently not supported and errors
  // are raised if these uses are tried
  if (checkNonSupportedTriggersUse(bindWA, subjectTable, op, allTriggers))
  {
     return this;
  }

#if DISABLE_RI
  RefConstraintList *riConstraints = NULL; 
#else
  RefConstraintList *riConstraints = 
    getRIs(bindWA, getTableDesc()->getNATable());
#endif

  if (riConstraints) 
    getInliningInfo().setFlags(II_hasRI);

#if DISABLE_MV_LOGGING
  NABoolean isMVLoggingRequired = FALSE;
#else
  NABoolean isMVLoggingRequired = isMvLoggingRequired();
#endif

  RelExpr  *topNode=boundExpr;

  // Get the list of updated columns.
  UpdateColumns *columns = NULL;
  if (op == COM_UPDATE)
    columns = new(heap) UpdateColumns(stoi_->getStoi());

  // Get only the before triggers that match these columns.
  TriggerList *beforeTriggers = NULL;
  if ((allTriggers != NULL) && (allTriggers->getBeforeTriggers() != NULL))
    beforeTriggers = allTriggers->getBeforeTriggers()->getColumnMatchingTriggers(columns);

  NABoolean tsjRETDescCreated = FALSE;

  if (beforeTriggers != NULL) {   
    if (checkForNotAtomicStatement(bindWA, 30027, 
				  ((*beforeTriggers)[0])->getTriggerName(), 
				  subjectTable.getQualifiedNameAsAnsiString())) {
	return this;
    }

    tsjRETDescCreated = TRUE;
    createOldAndNewCorrelationNames(bindWA);
  }

  // Save the previous IudNum, it will be restored at the end of the 
  // inlining of the current backbone.
  Lng32 prevIudNum = bindWA->getUniqueIudNum();
  // Set the IudNum for the current generic update backbone.
  // This value is used later as part of the uniquifier
  // as the temporary table column UNIQUEIUD_COLUMN
  bindWA->setUniqueIudNum();

  // When triggers defined on the subject table, it is assured that the
  // temp-table exists for this table. Since during initialization of the
  // TriggersTempTable object there's a seek for the temp-table's NATable, we
  // must be sure this table actually exists before creating that object.

  TriggersTempTable *tempTableObj = NULL;
  if (allTriggers != NULL)
  {
    tempTableObj = new(heap) TriggersTempTable(this, bindWA);
  }

  // Build the before triggers side of the inlining backbone.
  // This method also adds to 'columns' any column that is updated by before triggers.
  RelExpr  *beforeSubtree = NULL;
  if (beforeTriggers != NULL) 
    beforeSubtree = createTentativeSubTree(bindWA, 
					   beforeTriggers, 
					   columns,	
					   *tempTableObj, 
					   heap);

  if (bindWA->errStatus()) 
    return NULL;

#if DISABLE_TRIGGERS
  // Nothing to do.
#else
  if ((allTriggers != NULL) && (allTriggers->getAfterStatementTriggers() != NULL))
    {
    TriggerList *pureStmtTriggers = allTriggers->getAfterStatementTriggers()->getColumnMatchingTriggers(columns);
    // There are statement triggers which are not for statement MVs.
    // The ones used for statement MVs will be pupulated with the
    // getTriggeredMVs call below.
    if (pureStmtTriggers)
      if (checkForNotAtomicStatement(bindWA, 30034, 
				     ((*pureStmtTriggers)[0])->getTriggerName(), 
				     subjectTable.getQualifiedNameAsAnsiString())) 
	{
	  return this;
	}
    }
  // Now that we know the final set of columns updated in the query, we
  // can determine whether the update of the MVs is direct or indirect.
  allTriggers = getTriggeredMvs(bindWA, allTriggers, columns);
  if (bindWA->errStatus())
    return this;
#endif

  if ((allTriggers   == NULL) && 
      (riConstraints == NULL) && 
      !isMVLoggingRequired    &&
      !getTableDesc()->hasSecondaryIndexes())
  {
    InliningFinale(bindWA, boundExpr, origScopeRETDesc);
    bindWA->resetUniqueIudNum(prevIudNum); // restore the saved IudNum
    return boundExpr;  // Nothing for us to do here.
  }

  // Get the row and statement triggers that match the updated column list.
  TriggerList *rowTriggers  = NULL;
  if ((allTriggers != NULL) && (allTriggers->getAfterRowTriggers() != NULL))
    rowTriggers = allTriggers->getAfterRowTriggers()->getColumnMatchingTriggers(columns);
  TriggerList *stmtTriggers = NULL;
  if ((allTriggers != NULL) && (allTriggers->getAfterStatementTriggers() != NULL))
    stmtTriggers = allTriggers->getAfterStatementTriggers()->getColumnMatchingTriggers(columns);

  if (rowTriggers != NULL) {   
    if (checkForNotAtomicStatement(bindWA, 30034, 
				  ((*rowTriggers)[0])->getTriggerName(), 
				  subjectTable.getQualifiedNameAsAnsiString())) 
    {
	return this;
    }
    else if (isNoRollback() ||
	      (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) 
    {
	*CmpCommon::diags() << DgSqlCode(-3232) 
	<< DgString0(subjectTable.getQualifiedNameAsAnsiString()) 
	<< DgString1("After Trigger :")
	<< DgString2(((*rowTriggers)[0])->getTriggerName());
	bindWA->setErrStatus();

	return this ;
    }
  }
  else if (stmtTriggers != NULL) { 
   if ((CmpCommon::getDefault(NAR_DEPOBJ_ENABLE2) == DF_OFF) )
     {
       if (checkForNotAtomicStatement(bindWA, 30034, 
				      ((*stmtTriggers)[0])->getTriggerName(), 
				      subjectTable.getQualifiedNameAsAnsiString())) 
	 {
	   return this;
	 }
     }
    else if (isNoRollback() ||
	      (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) 
    {
	*CmpCommon::diags() << DgSqlCode(-3232) 
	<< DgString0(subjectTable.getQualifiedNameAsAnsiString()) 
	<< DgString1("After Trigger :")
	<< DgString2(((*stmtTriggers)[0])->getTriggerName());
	bindWA->setErrStatus();

	return this ;
    }
  }
  

  if ((stmtTriggers != NULL) || (beforeTriggers != NULL))
  {
    NAString trigName = stmtTriggers ? ((*stmtTriggers)[0])->getTriggerName() : ((*beforeTriggers)[0])->getTriggerName() ;
    if (getFirstNRows() > 0)
    {
      // first N delete not supported with before triggers and after statement triggers.
      *CmpCommon::diags() << DgSqlCode(-11045) 
	  << DgString0(trigName) 
	  << DgString1(subjectTable.getQualifiedNameAsAnsiString());
	bindWA->setErrStatus();
	return this;
    }
  }

  // Filter only the RI constraints that match the updated columns.
  if (riConstraints != NULL)
  {
    riConstraints = riConstraints->getNeededRIs(columns, heap);
    if (riConstraints->isEmpty())
      riConstraints = NULL;		
    else // There are RI constraints that need to be enforced.  
      {
	// Disallow embedded delete on a referenced table.
	// Disallow embedded updates on columns which are part of an RI constraint.
	if (getGroupAttr()->isEmbeddedDelete()) 
	  {
	    *CmpCommon::diags() << DgSqlCode(-4183);
	    bindWA->setErrStatus();
	    return this;
	  }
	if (getGroupAttr()->isEmbeddedUpdate()) 
	  {
	    *CmpCommon::diags() << DgSqlCode(-4184);
	    bindWA->setErrStatus();
	    return this;
	  }
	if ((CmpCommon::getDefault(NAR_DEPOBJ_ENABLE2) == DF_OFF) )
	  {
       
	    if (checkForNotAtomicStatement(bindWA, 30028, 
					   (riConstraints->at(0)->getConstraintName()).getQualifiedNameAsAnsiString(),
					   subjectTable.getQualifiedNameAsAnsiString())) {
	      return this ;
	    }
	  }
	  
	if (isNoRollback() ||
		  (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) {
	  *CmpCommon::diags() << DgSqlCode(-3232) 
	  << DgString0(subjectTable.getQualifiedNameAsAnsiString()) 
	  << DgString1("Referential Intergrity Constraint :")
	  << DgString2((riConstraints->at(0)->getConstraintName()).getQualifiedNameAsAnsiString());
	  bindWA->setErrStatus();

	  return this ;
	}
	
      }
  }

  NABoolean needIM = isIMNeeded(columns);

  if (needIM) {
    if ((isNoRollback() || 
	(CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) ||
	(bindWA->getHostArraysArea() &&
	bindWA->getHostArraysArea()->getTolerateNonFatalError())) {
      NAString indexName;
      const LIST(IndexDesc *) indexList = getTableDesc()->getIndexes();
      for (CollIndex i=0; i<indexList.entries(); i++) 
	{
	  IndexDesc *index = indexList[i];
	  if (!(index->isClusteringIndex())) {
	    indexName = index->getExtIndexName();
	    break;
	  }
	}
      if ((CmpCommon::getDefault(NAR_DEPOBJ_ENABLE) == DF_OFF) )
	{
	  if (checkForNotAtomicStatement(bindWA, 
					 30026, 
					 indexName, 
					 subjectTable.getQualifiedNameAsAnsiString())) 
	    {
	      return this;
	
	    }
	}
      if (isNoRollback() ||
	  (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_)) {
	*CmpCommon::diags() << DgSqlCode(-3232) 
			    << DgString0(subjectTable.getQualifiedNameAsAnsiString()) 
			    << DgString1("Index :")
			    << DgString2(indexName);
	bindWA->setErrStatus();

	return this ;
	  
      }
    }
    getInliningInfo().setFlags(II_hasIM);
  }

  // Do we have any triggers to work on?
  if ((beforeTriggers == NULL) && 
      (rowTriggers    == NULL) && 
      (stmtTriggers   == NULL) )
  {
     bindWA->resetUniqueIudNum(prevIudNum);

     if (!needIM && !isMVLoggingRequired && (riConstraints  == NULL))
     {
	// We get here only if this is an Update operation, and there are 
	// triggers/IM/RI defined on Update on this table, but all of them
	// are on columns other than the ones updated.
	// e.g. A trigger AFTER UPDATE OF (a) ON T1,
	// and a triggering statement like: UPDATE T1 SET B=5;
        InliningFinale(bindWA, boundExpr, origScopeRETDesc);
	CMPASSERT (op == COM_UPDATE);		
	return boundExpr;
     }

     // OK, so we have no triggers - just RI, IM or both.
     createOldAndNewCorrelationNames(bindWA);
     setNoFlow(TRUE);
     getInliningInfo().setFlags(II_hasPipelinedActions); 

     topNode = 
       inlineOnlyRIandIMandMVLogging(bindWA, 
				     this, 
				     needIM, 
				     riConstraints, 
				     isMVLoggingRequired, 
				     columns, 
				     heap);

     if (needIM)
     {
        topNode->getInliningInfo().setFlags(II_DrivingIM);
     }

     topNode = topNode->bindNode(bindWA);
     // Create the tree that handles Index Maintainance.
     if (needIM)
     {
       // don't allow index maintenance on non-audited tables unless
       // this is enabled by a default
       // We allow index maintenance in an Internal refresh statement 
       if (!getTableDesc()->getClusteringIndex()->getNAFileSet()->isAudited() &&
	   !bindWA->isBindingMvRefresh())
       {
         NAString dummyTokString(bindWA->wHeap());
         const NATable *naTable = bindWA->getNATable(getTableName());
         DefaultToken imAllowed =
            bindWA->getSchemaDB()->getDefaults().token(IUD_NONAUDITED_INDEX_MAINT,
						       dummyTokString);

         switch (imAllowed)
         {
           case DF_ON:
             // go ahead and do it, the user asked for it
             break;
           case DF_WARN:
             // emit a warning and continue
             *CmpCommon::diags() << DgSqlCode(4203) <<
               DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
             break;
           default:
             // stop with an error, index maintenance is not allowed on
             // nonaudited tables
             *CmpCommon::diags() << DgSqlCode(-4203) <<
               DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
             bindWA->setErrStatus();
             return this;
         }
       }
     }

     if (bindWA->errStatus())
     {
       return boundExpr;
     }

     getInliningInfo().setFlags(II_hasInlinedActions);

     InliningFinale(bindWA, topNode, origScopeRETDesc);
     return topNode;
  }

  // Now, that we know for sure there are triggers to be fired, tempTableObj
  // must be initialized. In case there are no regular triggers (not MVImmediate)
  // defined on the table, the tempTableObj is not initialized yet (see initializing
  // of tempTableObj above).

  if (tempTableObj == NULL)
  {
    tempTableObj = new(heap) TriggersTempTable(this, bindWA);
  }

  setNoFlow(TRUE);

  if (!tsjRETDescCreated)
    createOldAndNewCorrelationNames(bindWA);

  if ( (rowTriggers   != NULL) ||
       (riConstraints != NULL) ||
	needIM                 ||
	isMVLoggingRequired)
    getInliningInfo().setFlags(II_hasPipelinedActions); 

  // Forbid the use of the Materialize node by the optimizer, for the entire
  // backbone, if we are now cascaded from a row after trigger.
  NABoolean forbidMaterializeNodeHere = shouldForbidMaterializeNodeHere(bindWA);
  Int32 prevStateOfFlags = 0;
  if (forbidMaterializeNodeHere)
  {
    // Set this InliningInfo flag in every node being bound (see RelExpr::bindSelf())
    // but save the previous state first.
    prevStateOfFlags = bindWA->getInliningInfoFlagsToSetRecursivly();
    bindWA->setInliningInfoFlagsToSetRecursivly(II_MaterializeNodeForbidden);
  }

  // Create and bind the rest of the trigger backbone.
  if (beforeTriggers == NULL)
    {
      if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->getTolerateNonFatalError()&& (needIM || riConstraints))
	{
	  
	  topNode = inlineAfterOnlyBackboneForUndo(bindWA, 
					    *tempTableObj,
					    rowTriggers,
					    stmtTriggers,
					    riConstraints,
					    needIM,
					    isMVLoggingRequired,
					    columns,
					    heap);
	}
      else
	{
	  topNode = inlineAfterOnlyBackbone(bindWA, 
					    *tempTableObj,
					    rowTriggers,
					    stmtTriggers,
					    riConstraints,
					    needIM,
					    isMVLoggingRequired,
					    columns,
					    heap);
	}
    }
  else
    topNode = inlineBeforeAndAfterBackbone(bindWA, 
					   beforeSubtree,
					   *tempTableObj,
					   rowTriggers,
					   stmtTriggers,
					   riConstraints,
					   needIM,
					   isMVLoggingRequired,
					   columns,
					   heap);

  if (forbidMaterializeNodeHere)
  {
    // Restore to the the previous state. This effectivly resets the flag
    // we set before binding, so we don't affect sibtrees that will be bound 
    // after us.
    bindWA->setInliningInfoFlagsToSetRecursivly(prevStateOfFlags);
  }

  bindWA->resetUniqueIudNum(prevIudNum);
  // indicate that this is a subject table for enable/disable
  getOptStoi()->getStoi()->setSubjectTable(TRUE);

  getInliningInfo().setFlags(II_hasInlinedActions);

  InliningFinale(bindWA, topNode, origScopeRETDesc);
  return topNode;
}

//////////////////////////////////////////////////////////////////////////////
// This method checks to see if an update should be transformed into 
// insert/delete nodes.  This is true if the update is on a primary key and
// special conditions don't exist.
//
// Return value: 
// TRUE  - if the update is on a clustering or unique index key and no special
//         conditions exist.  Causes the update to be transformed to a delete
//         followed by an insert with intervening order by.
// FALSE - if the update is on a clustering or unique index key and no special
//         conditions exist.  OR
//         NOT update is on a clustering or unique index key.
//////////////////////////////////////////////////////////////////////////////
NABoolean Update::updatesClusteringKeyOrUniqueIndexKey(BindWA *bindWA)
{
  // This CQD must be ON or AGGRESSIVE in order to enable the transformation 
  // for special conditions.  If not, return false
  if (CmpCommon::getDefault(UPDATE_CLUSTERING_OR_UNIQUE_INDEX_KEY) == DF_OFF)
    return FALSE;

  ULng32 numberofKeys = getTableDesc()->
                         getClusteringIndex()->getIndexKey().entries();

  NABoolean hasSysKey = getTableDesc()->getClusteringIndex()->
                            getNAFileSet()->hasSyskey();

  // this restriction (i.e unable to transform update of unique index key
  // if base table has only syskey as clustering key may be removable
  // the intention is to revisit this once a similar problem has been 
  // solved for the Halloween feature.
  if ((numberofKeys == 1) AND hasSysKey)
    return FALSE;  // This should never be reached.

  // 1. Determine whether columns being updated are clustering key columns
  //    of base table or of a unique index.  Set flags used later.
  const LIST(IndexDesc *) & ixlist = getTableDesc()->getIndexes();
  NABoolean isUniqueIndexCol = FALSE;
  NABoolean isClusteringKeyCol = FALSE;
  NAString ckColName;  // Save column name if is clustering key.
  Scan * scanNode = getScanNode();
  const ValueIdList colUpdated = scanNode->getTableDesc()->getColUpdated();
  for (CollIndex indexNo = 0; indexNo < ixlist.entries(); indexNo++)
  {
    if (isUniqueIndexCol && isClusteringKeyCol)
      break ;

    IndexDesc *idesc = ixlist[indexNo];
    if (idesc->isUniqueIndex() || idesc->isClusteringIndex())
    {
      const ValueIdList indexKey = idesc->getIndexKey();

      for (CollIndex i = 0; i < colUpdated.entries(); i++)
      {
        ItemExpr *updateCol = colUpdated[i].getItemExpr();
        CMPASSERT(updateCol->getOperatorType() == ITM_BASECOLUMN);
        for (CollIndex j = 0; j < indexKey.entries(); j++)
        {
          ItemExpr *keyCol = indexKey[j].getItemExpr();
          ItemExpr *baseCol = ((IndexColumn*)keyCol)->getDefinition().getItemExpr();
          CMPASSERT(baseCol->getOperatorType() == ITM_BASECOLUMN);
          if (((BaseColumn*)updateCol)->getColNumber() ==
              ((BaseColumn*)baseCol)->getColNumber())
          {
            if (idesc->isUniqueIndex())
              isUniqueIndexCol = TRUE;
            else {
              isClusteringKeyCol = TRUE;
              ckColName = ((BaseColumn*)updateCol)->getColName();
            }
          }
        }
      } // for (CollIndex ...)
    }
  } // for (CollIndex ...)

  if ((CmpCommon::getDefault(UPDATE_CLUSTERING_OR_UNIQUE_INDEX_KEY) == DF_AGGRESSIVE) &&
      (NOT isClusteringKeyCol)) 
    return FALSE;

  // 2. If columns being updated are unique index or clustering key columns, 
  //    check for 5 unsupported special cases and issue error in each case.
  if (isUniqueIndexCol || isClusteringKeyCol)
  {
    // 2a. Check for first three unsupported special cases:
    //     i.   User declared cursor and performing update current of.
    //     ii.  Update statement with set on rollback.
    //     iii. Update with a select surrounding it.
    if ( updateCurrentOf() || 
         newRecBeforeExpr().entries() > 0 || 
         getGroupAttr()->isEmbeddedUpdate()
       )
    {
      if (isUniqueIndexCol && NOT isClusteringKeyCol)
	return FALSE; // column being updated is unique key but one of the 
        // three special cases apply. Revert to delete followed by insert 
        // without intervening sort.  NOT AN ERROR.

      // Set appropriate error for first three special cases.
      if ( updateCurrentOf() )
	*CmpCommon::diags() << DgSqlCode(-4118) ;
      if (newRecBeforeExpr().entries() > 0)
	*CmpCommon::diags() << DgSqlCode(-4199) ;
      if (getGroupAttr()->isEmbeddedUpdate())
	*CmpCommon::diags() << DgSqlCode(-4198) ;
      bindWA->setErrStatus();
      return FALSE ; // ERROR condition.
    }
     
    // 2b. Check for unsupported special case 4:
    //     iv. There is an MV on this table that is defined on 
    //         the clustering key(s).
    const NATable *naTable = bindWA->getNATable(getTableName());
    if (naTable)
    {
      // Check for MVs on table.
      const UsingMvInfoList &mvList = naTable->getMvsUsingMe();
      if (!mvList.isEmpty())
      {
        // MV(s) exist.  Check to see if any MV is ON STATEMENT and is
        // significant.  (Update on a primary key with an MV on that 
        // key is not supported - return FALSE.)
        for (CollIndex i = 0; i < mvList.entries(); i++)
          if (mvList[i]->isInitialized() && 
              mvList[i]->getRefreshType() == COM_ON_STATEMENT)
          {
            CorrName mvCorr = CorrName(mvList[i]->getMvName(), bindWA->wHeap());
            NATable *naTableMv = bindWA->getNATable(mvCorr);
            if (bindWA->errStatus()) return FALSE;
            MVInfoForDML *mvInfo = naTableMv->getMVInfo(bindWA);
            // getMVInfo() reads from metadata, but saves the info found
            // and will be called later anyway during binding.
            UpdateColumns *columns = NULL;
            columns = new(bindWA->wHeap()) UpdateColumns(getOptStoi()->getStoi());
            if (checkUpdateType(mvInfo, naTable->getTableName(), columns) !=
                IRELEVANT)
            {
              if (isClusteringKeyCol) // update CK not supported in this case.
              {
                *CmpCommon::diags() << DgSqlCode(-4033) << DgColumnName(ckColName);
                bindWA->setErrStatus();
              }
              return FALSE;
            }
          }
      }
    }

if (isIgnoreTriggers() == FALSE)
    {
      ComOperation op;
      op = COM_UPDATE; 
      BeforeAndAfterTriggers *allTriggers = 0;
      QualifiedName& subjectTable = getTableDesc()->getCorrNameObj().getQualifiedNameObj();
      allTriggers = bindWA->getSchemaDB()->getTriggerDB()->getTriggers(subjectTable, op, bindWA);
      UpdateColumns *columns = NULL;
      columns = new(bindWA->wHeap()) UpdateColumns(getOptStoi()->getStoi());
      TriggerList *beforeTriggers = NULL;
      if ((allTriggers != NULL) && (allTriggers->getBeforeTriggers() != NULL))
        beforeTriggers = allTriggers->getBeforeTriggers()->getColumnMatchingTriggers(columns);
      if (beforeTriggers)
      {
        if (isClusteringKeyCol) // update CK not supported if table has beforeTriggers.
        {
          *CmpCommon::diags() << DgSqlCode(-4033) << DgColumnName(ckColName);
          bindWA->setErrStatus();
        }
        return FALSE;
      }
    }

    return TRUE;  // Column being updated is CK or unique index key and no special cases apply.
  } // if (isUniqueIndexCol || isClusteringKeyCol)

  return FALSE ;  // Column being updated is not CK or unique index key
}

RelExpr *Update::transformUpdatePrimaryKey(BindWA *bindWA)
{

   Delete * delNode = new (bindWA->wHeap())
			Delete(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()),
				NULL,
				REL_UNARY_DELETE,
				child(0),
				NULL);
   delNode->setNoLogOp(CONSISTENT_NOLOG);
   delNode->setUpdateCKorUniqueIndexKey(TRUE);
   delNode->rowsAffected() = GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED;

   ValueIdList selectList, sourceColsList, lhsOfSetClause;
   
   getTableDesc()->getUserColumnList(selectList);
   getScanIndexDesc()->getPrimaryTableDesc()->getUserColumnList(sourceColsList);
   ValueId vid ;
   CollIndex pos;

   // newRecExprArray is a list of assigns. For each assign
   // child(0) is the LHS of the set clause and child(1) is
   // the RHS of the SET clause

   for (CollIndex i=0; i < newRecExprArray().entries(); i++)
    {
      lhsOfSetClause.insertAt(i,newRecExprArray().at(i).getItemExpr()->child(0).getValueId());
    }

   for (CollIndex i=0; i < selectList.entries(); i++)
    {
      if ((pos = lhsOfSetClause.index(selectList[i])) == NULL_COLL_INDEX)
	selectList[i] = sourceColsList[i];
      else
	selectList[i] = newRecExprArray().at(pos).getItemExpr()->child(1).getValueId();
    }

    for (CollIndex i=0; i < oldToNewMap().getTopValues().entries(); i++) {
      BaseColumn *col = (BaseColumn *) oldToNewMap().getBottomValues()[i].getItemExpr();
      NABoolean addToOldToNewMap = TRUE;

      // Copy the oldToNewMap.
      if (col->getNAColumn()->isComputedColumnAlways()) {
        // Computed columns can be copied from delete to insert if they don't
        // change. Don't include the column in this map, though, if one of
        // the underlying columns gets updated, because the value of the
        // computed column has to be recomputed. That computation will be
        // done in the new insert node.
        ValueIdSet underlyingCols;

        col->getUnderlyingColumnsForCC(underlyingCols);

        if (NOT underlyingCols.intersect(lhsOfSetClause).isEmpty())
          addToOldToNewMap = FALSE;
      }

      // Copy the oldToNewMap.
      if (addToOldToNewMap)
        delNode->oldToNewMap().addMapEntry(oldToNewMap().getTopValues()[i],
                                           oldToNewMap().getBottomValues()[i]);
    }

   RelRoot * rootNode = new (bindWA->wHeap())
			RelRoot(delNode, 
				REL_ROOT,
				selectList.rebuildExprTree(ITM_ITEM_LIST));

   RelExpr * boundExpr;
   Insert * insNode = new (bindWA->wHeap())
		Insert(CorrName(getTableDesc()->getCorrNameObj(),bindWA->wHeap()),
				getTableDesc(), // insert gets the same tabledesc as the update
				REL_UNARY_INSERT,
				rootNode,
				NULL);
   insNode->setNoLogOp(isNoLogOperation());
   insNode->setSubqInUpdateAssign(subqInUpdateAssign());

   if (this->rowsAffected() == GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED)
      insNode->rowsAffected() = GenericUpdate::DO_NOT_COMPUTE_ROWSAFFECTED;
   else
      insNode->rowsAffected() = GenericUpdate::COMPUTE_ROWSAFFECTED;
      
   insNode->setUpdateCKorUniqueIndexKey(TRUE);
   InliningInfo inlineInfo = getInliningInfo();
   insNode->setInliningInfo(&inlineInfo);
   if (CmpCommon::getDefault(UPDATE_CLUSTERING_OR_UNIQUE_INDEX_KEY) == DF_ON) {
     insNode->setAvoidHalloween(TRUE);
     insNode->setHalloweenCannotUseDP2Locks(TRUE);
   }
   // used to convey updated columns to insert node's stoi
   // during inlining the update node is not present anymore, we read the 
   // insert's stoi to figure out which columns are updated.
   SqlTableOpenInfo * scanStoi = getLeftmostScanNode()->getOptStoi()->getStoi();
   short updateColsCount = getOptStoi()->getStoi()->getColumnListCount();
   scanStoi->setColumnListCount(updateColsCount);
   scanStoi->setColumnList(new (bindWA->wHeap()) short[updateColsCount]);
   for (short i=0; i<updateColsCount; i++)
    scanStoi->setUpdateColumn(i,getOptStoi()->getStoi()->getUpdateColumn(i));

   boundExpr = insNode->bindNode(bindWA);
   return boundExpr;
}

