/* -*-C++-*-
// @@@ 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 @@@
 *****************************************************************************
 *
 * File:         BindStmtDDL.C
 * Description:  DDL statements
 *               Methods related to the SQL binder
 *               
 * Created:      3/28/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */


#define   SQLPARSERGLOBALS_FLAGS        // must precede all #include's
#include "AllStmtDDL.h"
#include "BindWA.h"
// QSTUFF
#include "NormWA.h"
// QSTUFF
// #include "CatError.h"
// #define  CAT_ALTER_CANNOT_ADD_NOT_DROPPABLE_CONSTRAINT       1053
// The above are commented out because we use sqlcode 3067 instead.
#include "ComASSERT.h"
#include "ComObjectName.h"
#include "ComOperators.h"
#include "CmpCommon.h"
#include "CmpMain.h"
#include "ElemDDLPartitionSystem.h"
#include "ElemDDLUdrLibrary.h"
#include "ElemDDLLike.h"
#include "ElemDDLConstraintCheck.h"
#include "ElemDDLConstraintRI.h"
#include "ElemDDLReferences.h"
#include "NATable.h"
#include "RelMisc.h"
#include "TableDesc.h"
#include "RelJoin.h"   
#include "SqlParserGlobals.h"           // must be last #include
#include "Triggers.h"
#include "NormWA.h" 
#include "Analyzer.h"
#include "QRDescriptor.h"

// -----------------------------------------------------------------------
// Forward declarations
// -----------------------------------------------------------------------
void CatCollectCheckConstraintUsages
            (const StmtDDLAddConstraintCheck &addCheckNode,
             const QualifiedName &tableQualName);

// -----------------------------------------------------------------------
// definition of method bindNode() for class ElemDDLConstraintRI
// -----------------------------------------------------------------------

ExprNode *
ElemDDLConstraintRI::bindNode(BindWA * pBindWA)
{
  for (Int32 i = 0; i < getArity(); i++)
  {
    if (getChild(i))
    {
      getChild(i)->castToElemDDLNode()->bindNode(pBindWA);
    }
  }
  
  markAsBound();
  
  return this;  
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class ElemDDLReferences
// -----------------------------------------------------------------------

ExprNode *
ElemDDLReferences::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
    
  getReferencedNameAsQualifiedName().applyDefaultsValidate(pBindWA->getDefaultSchema());
  
  markAsBound();
  
  return this;  
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class ElemDDLUdrLibrary
// -----------------------------------------------------------------------

ExprNode *
ElemDDLUdrLibrary::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  libraryName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(libraryName_))
    return this;

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// Added a new bindNode() for the class ElemDDLLike for the name expansion
// using Matthew's common code.
// -----------------------------------------------------------------------

ExprNode *
ElemDDLLike::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  //  sourceTableCorrName_.getQualifiedNameObj().applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &sourceTableCorrName_.getQualifiedNameObj()))
    {
      pBindWA->setErrStatus();
      return this;
    }

  sourceTableName_ = sourceTableCorrName_.getQualifiedNameObj().getQualifiedNameAsAnsiString();
  markAsBound();
  return this;  
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLNode
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within a DDL Statement tree
//
ExprNode *
StmtDDLNode::bindNode(BindWA *  /* bindWAPtr */ )
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterAuditConfig
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterAuditConfig::bindNode(BindWA *pBindWA)
{
  ComASSERT(pBindWA);
  markAsBound();
  return this;
}



// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterIndex
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterIndex::bindNode(BindWA *pBindWA)
{
  ComASSERT(pBindWA);
  indexQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(indexQualName_))
    return this;
  indexName_ = indexQualName_.getQualifiedNameAsAnsiString();
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterLibrary
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterLibrary::bindNode(BindWA *pBindWA)
{
  ComASSERT(pBindWA);
  libraryName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(libraryName_))
    return this;
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterSynonym
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterSynonym::bindNode(BindWA *pBindWA)
{

  ComASSERT(pBindWA);
  synonymName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(synonymName_))
    return this;
  objectReference_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(objectReference_))
    return this;
  if (synonymName_.getCatalogName() NEQ objectReference_.getCatalogName())
  {
    *CmpCommon::diags() << DgSqlCode(-3230);
    pBindWA->setErrStatus();
  }

  markAsBound();
  return this;
}

// ----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAddConstraintUnique
// ----------------------------------------------------------------------
// virtual
ExprNode * 
StmtDDLAddConstraintUnique::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA)
  QualifiedName &tableQualName = getTableNameAsQualifiedName();

  //  tableQualName.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName))
    return this;

  QualifiedName & constraintQualName = getConstraintNameAsQualifiedName();

  //
  // if constraint name was not specified, the "exec" layer (defined
  // in module CatAddCheckConstraint.C) will make up one.
  //
  if (NOT getConstraintName().isNull())  // constraint name was specified
  {
    constraintQualName.applyDefaults(tableQualName);
    if (pBindWA->violateAccessDefaultSchemaOnly(constraintQualName))
      return this;

    if (tableQualName.getCatalogName() NEQ constraintQualName.getCatalogName()
        OR
        tableQualName.getSchemaName() NEQ constraintQualName.getSchemaName())
    {
      *CmpCommon::diags() << DgSqlCode(-3050);
      pBindWA->setErrStatus();
      return this;
    }
  }

  markAsBound();
  return this;

}
// ----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAddConstraintRI
// ----------------------------------------------------------------------
// virtual
ExprNode * 
StmtDDLAddConstraintRI::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA)

  QualifiedName &tableQualName = getTableNameAsQualifiedName();
  tableQualName.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName))
    return this;

  QualifiedName & constraintQualName = getConstraintNameAsQualifiedName();

  //
  // if constraint name was not specified, the "exec" layer (defined
  // in module CatAddCheckConstraint.C) will make up one.
  //
  if (NOT getConstraintName().isNull())  // constraint name was specified
  {
    constraintQualName.applyDefaults(tableQualName);
    if (pBindWA->violateAccessDefaultSchemaOnly(constraintQualName))
      return this;

    if (tableQualName.getCatalogName() NEQ constraintQualName.getCatalogName()
        OR
        tableQualName.getSchemaName() NEQ constraintQualName.getSchemaName())
    {
      *CmpCommon::diags() << DgSqlCode(-3050);
      pBindWA->setErrStatus();
      return this;
    }
  }

  getConstraint()->bindNode(pBindWA);  

  markAsBound();
  return this;

}
// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAddConstraint
// -----------------------------------------------------------------------

// virtual 
ExprNode *
StmtDDLAddConstraint::bindNode(BindWA * pBindWA)
{ 
  ComASSERT(pBindWA)
  
  QualifiedName &tableQualName = getTableNameAsQualifiedName();
  tableQualName.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName))
    return this;

  QualifiedName & constraintQualName = getConstraintNameAsQualifiedName();
  
  //
  // if constraint name was not specified, the "exec" layer (defined
  // in module CatAddCheckConstraint.C) will make up one.
  //
  if (NOT getConstraintName().isNull())  // constraint name was specified
  {
    constraintQualName.applyDefaults(tableQualName);
    if (pBindWA->violateAccessDefaultSchemaOnly(constraintQualName))
      return this;

    if (tableQualName.getCatalogName() NEQ constraintQualName.getCatalogName()
        OR
        tableQualName.getSchemaName() NEQ constraintQualName.getSchemaName())
    {
      *CmpCommon::diags() << DgSqlCode(-3050);
      pBindWA->setErrStatus();
      return this;
    }
  }
  
  markAsBound();

  return this;      
}



// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAddConstraintCheck
// -----------------------------------------------------------------------

// virtual
ExprNode *
StmtDDLAddConstraintCheck::bindNode(BindWA * pBindWA )
{
  ComASSERT(pBindWA);
  
  pBindWA->setNameLocListPtr(&nameLocList_);
  pBindWA->setUsageParseNodePtr(this);

  QualifiedName &tableQualName = getTableNameAsQualifiedName();
  tableQualName.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName))
    return this;

  QualifiedName & constraintQualName = getConstraintNameAsQualifiedName();

  ElemDDLConstraint *elemDDLC = getElemDDLConstraintCheck();

  // We can "add" nondroppable constraints only in a Create Table,
  // not an Alter Table.
  //
  if (!Get_SqlParser_Flags(ALLOW_ADD_CONSTRAINT_NOT_DROPPABLE))
  {
    // Alter Table constraints default to DROPPABLE.
    if (!elemDDLC->anyDroppableClauseSpecifiedExplicitly())
      elemDDLC->setDroppableFlag(TRUE);

    if (!elemDDLC->isDroppable())
    {
      *CmpCommon::diags() << DgSqlCode(-3067);
      pBindWA->setErrStatus();
      return this;
    }
  }

  //
  // if constraint name was not specified, the "exec" layer (defined
  // in module CatAddCheckConstraint.C) will make up one.
  //
  if (NOT getConstraintName().isNull())  // constraint name was specified
  {
    constraintQualName.applyDefaults(tableQualName);
    if (pBindWA->violateAccessDefaultSchemaOnly(constraintQualName))
      return this;

    if (tableQualName.getCatalogName() NEQ constraintQualName.getCatalogName()
        OR
        tableQualName.getSchemaName() NEQ constraintQualName.getSchemaName())
    {
      *CmpCommon::diags() << DgSqlCode(-3050);
      pBindWA->setErrStatus();
      return this;
    }
  }


  // if isFakeNode() returns TRUE, the StmtDDLAddConstraintCheck node
  // represents a check constraint definition appearring in a create
  // table statement. Cannot bind the Search Condition expression for
  // this case because the table SOL object has not been created yet.
  // The binding of the expression will be done in CatExecCreateTable().
  if (NOT isFakeNode())
  {                      // check constraint def in alter table stmt
    //
    // Get the NATable for this object
    //
    CorrName tableCorrName(tableQualName, (CollHeap*)0, 
                           NAString() /*no corr. name*/);

    switch(getTableType())
    {
    case COM_IUD_LOG_TABLE:
      tableCorrName.setSpecialType(ExtendedQualName::IUD_LOG_TABLE);
      break;
    case COM_SG_TABLE:
      tableCorrName.setSpecialType(ExtendedQualName::SG_TABLE);
      break;
    case COM_GHOST_IUD_LOG_TABLE:
      tableCorrName.setSpecialType(ExtendedQualName::GHOST_IUD_LOG_TABLE);
      break;
    case COM_RANGE_LOG_TABLE:
      tableCorrName.setSpecialType(ExtendedQualName::RANGE_LOG_TABLE);
      break;
    case COM_GHOST_MV_TABLE:
    case COM_GHOST_REGULAR_TABLE:
       tableCorrName.setSpecialType(ExtendedQualName::GHOST_TABLE);
      break;
    default:
      break;
    }

    NATable *naTable = pBindWA->getNATable(tableCorrName,
                                           FALSE /*don't collect usage info*/);
    if (pBindWA->errStatus())
      return this;

    //
    // Allocate a TableDesc
    // This call also allocates a RETDesc and attaches to the BindScope
    //
    pBindWA->createTableDesc(naTable, tableCorrName);
    if (pBindWA->errStatus())
      return this;
    
    // Genesis 10-980609-5773: tell Binder we're in a check constraint
    NAString tmpTxt("CHECK(...)");
    CheckConstraint tmpChk(constraintQualName, tmpTxt, pBindWA->wHeap());
    CheckConstraint *&savChk =
      pBindWA->getCurrentScope()->context()->inCheckConstraint();
    pBindWA->getCurrentScope()->context()->inCheckConstraint() = &tmpChk;

    getSearchCondition()->bindNode(pBindWA);

    pBindWA->getCurrentScope()->context()->inCheckConstraint() = savChk;
  }  // if (NOT isFakeNode())

  markAsBound();

  pBindWA->setNameLocListPtr(NULL);
  pBindWA->setUsageParseNodePtr(NULL);
  
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateCatalog
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Create Catalog tree
//
ExprNode *
StmtDDLCreateCatalog::bindNode(BindWA *  /* bindWAPtr */ )
{
  markAsBound();
  return this;
}


//----------------------------------------------------------------------------
// OZ
ExprNode *
StmtDDLCreateMvRGroup::bindNode(BindWA *  pBindWA)
{
  ComASSERT(pBindWA NEQ NULL);
  mvRGroupQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(mvRGroupQualName_))
    return this;

  markAsBound();
  return this;
}

ExprNode *
StmtDDLDropMvRGroup::bindNode(BindWA *  pBindWA)
{
  ComASSERT(pBindWA NEQ NULL);
  mvRGroupQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(mvRGroupQualName_))
    return this;

  markAsBound();
  return this;
}


/***********************************************************/
// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateTrigger
// -----------------------------------------------------------------------

//
// Virtual function for performing name binding within the Create Trigger tree
//   This node has two children: 
//     1. Columns (not null in case of explicit update columns) which does
//        not need binding here (the columns are verified seperately in
//        CatExecCreateTrigger. )
//     2. Trigger's action (including the "when" condition) which is bound
//        here.
//
ExprNode *
StmtDDLCreateTrigger::bindNode(BindWA * pBindWA )
{
  ComASSERT(pBindWA NEQ NULL);

  // Verify that the name of the subject table was not used in the 
  // REFERENCING clause.
  const NAString& subjectTable = getTableNameObject().getObjectName();
  if ( ( (getOldName() != NULL) && (subjectTable == *getOldName() ) ) ||
       ( (getNewName() != NULL) && (subjectTable == *getNewName() ) ) )
  {
	// 11021 The subject table name cannot be used in the REFERENCING clause.
	*CmpCommon::diags() << DgSqlCode(-11021);
    pBindWA->setErrStatus();
    return this;
  }

  if ( (getOldName() != NULL) && 
	   (getNewName() != NULL) && 
	   (*getOldName() == *getNewName()) )
  {
	// 11024 Cannot reference both OLD and NEW with the same name MYNEW.
	*CmpCommon::diags() << DgSqlCode(-11024)
		<< DgString0(*getOldName());
    pBindWA->setErrStatus();
    return this;
  }

  pBindWA->setInTrigger();
  pBindWA->setNameLocListPtr(nameLocListPtr_);
  pBindWA->setUsageParseNodePtr(this);

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;
      
  triggerQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(triggerQualName_))
    return this;

  ParNameLoc *pNameLoc
    = nameLocListPtr_->getNameLocPtr(triggerQualName_.getNamePosition());
  ComASSERT(pNameLoc);
  pNameLoc->setExpandedName(triggerQualName_.getQualifiedNameAsAnsiString());
  
  pNameLoc
    = nameLocListPtr_->getNameLocPtr(tableQualName_.getNamePosition());
  ComASSERT(pNameLoc);
  pNameLoc->setExpandedName(tableQualName_.getQualifiedNameAsAnsiString());

  // Bind child nodes

  //   For the first child (optional update columns) Do nothing! 
  //   The columns would be checked in CatExecCreateTrigger 

  //   Bind the second child -- the trigger's action expression
  RelExpr *actionExpr = getChild(TRIGGER_ACTION_EXPRESSION)->castToRelExpr();

  ComASSERT( actionExpr NEQ NULL );
  pBindWA->getCurrentScope()->context()->triggerObj() = this;

  if (isStatement())  // Statement triggers don't need help binding.
    actionExpr = actionExpr->bindNode(pBindWA);
  else                // Row triggers need the transition values flowing in
    actionExpr = bindRowTrigger(pBindWA);
  
  if ( !pBindWA->errStatus()) 
  { // bind succeeded
    ComASSERT(actionExpr->getOperatorType() == REL_ROOT);  
    // run the transformNode() pass for further semantic checks
    actionExpr = CmpTransform(actionExpr); 
  }
  
  //
  // sets a flag to let user know that the parse has  been bound.
  //

  setAction( actionExpr ) ;

  markAsBound();

  pBindWA->setNameLocListPtr(NULL);
  pBindWA->setUsageParseNodePtr(NULL);
  
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropTrigger
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropTrigger tree
//
ExprNode *
StmtDDLDropTrigger::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA NEQ NULL);
  triggerQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(triggerQualName_))
    return this;

  markAsBound();
  return this;
}

ExprNode * 
StmtDDLAlterCatalog::bindNode (BindWA* pBindWA)
{
  ComASSERT (pBindWA NEQ NULL);

  if (!isAllSchemaPrivileges_)
  {
     schemaName_ = ToAnsiIdentifier(schemaQualName_.getSchemaName());
  }

  markAsBound();
  return this;
}

//----------------------------------------------------------------------------
// MV - RG
ExprNode *
StmtDDLAlterMvRGroup::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA NEQ NULL);
  // bind mv group
  mvRGroupQualName_.applyDefaults(pBindWA->getDefaultSchema());
  //do the following instead of the above if need to support public schema for alter mvgroup
  //mvRGroupQualName_.applyDefaultsValidate(pBindWA->getDefaultSchema(), COM_MVRG_NAME);

  if (pBindWA->violateAccessDefaultSchemaOnly(mvRGroupQualName_))
    return this;

  // bind list of MV's

  QualifiedName *pQualName = & getFirstMvInList();
  pQualName->applyDefaults(pBindWA->getDefaultSchema());
  //do the following instead of the above if need to support public schema for alter mvgroup
  //pQualName->applyDefaultsValidate(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
    return this;

  while(listHasMoreMVs())
  {
    pQualName = &getNextMvInList();
    pQualName->applyDefaults(pBindWA->getDefaultSchema());
    //do the following instead of the above if need to support public schema for alter mvgroup
    //pQualName->applyDefaultsValidate(pBindWA->getDefaultSchema());
    if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
      return this;
  }

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterRoutine
// -----------------------------------------------------------------------

ExprNode * StmtDDLAlterRoutine::bindNode(BindWA * pBindWA)
{

  ComASSERT(pBindWA NEQ NULL);

  getRoutineNameAsQualifiedName().applyDefaults(pBindWA->getDefaultSchema());

  if (getRoutineNameSpace() EQU COM_UUDF_ACTION_NAME)
  {
    getActionNameAsQualifiedName().applyDefaults(pBindWA->getDefaultSchema());
  }

  markAsBound();
  return this;
} // StmtDDLAlterRoutine::bindNode()




// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterTrigger
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterTrigger::bindNode(BindWA *pBindWA)
{
  ComASSERT(pBindWA);
  triggerOrTableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(triggerOrTableQualName_))
    return this;

  markAsBound();
  return this;
}

/////////////////////////////////////////////////////////////////////////////
// This method is used during DDL only.
// it is called during a CREATE TRIGGER DDL operation, after the 
// parsing was completed, the DDL statement is bound for semantic checks.
// This method is specific for binding of Row Triggers (before and after), 
// since these triggers expect the OLD and NEW transition variables to be 
// pipelined to them. 
// Instead of creating a GenericUpdate node that looks like the operation 
// driving the trigger, we are getting the same result by creating Scan nodes
// on the subject table, with the correct OLD and NEW correlation names. In 
// case this is an Update trigger, a cross join is created to supply all the 
// needed names. This is not expensive since this code will only be used for
// semantic checks, and will never be executed.
// The resulting tree that is bound looks like this (for Update triggers):
//
// An After Row trigger:                  A Before trigger:
//
//         RelRoot                            RelRoot
//            |                                  |
//           TSJ                            BeforeTrigger
//          /   \                                |
//      Join     Trigger action                 Join
//     /    \                                  /    \
//  Scan     Scan                            Scan    Scan
//  OLD@     NEW@                            OLD@    NEW@
/////////////////////////////////////////////////////////////////////////////
RelExpr *StmtDDLCreateTrigger::bindRowTrigger(BindWA *pBindWA)
{
  CollHeap *heap = pBindWA->wHeap();
  RelExpr  *rowTrigger = getActionExpression();
  RelExpr  *scanTree = NULL;
  RelExpr  *topNode = NULL;
  CorrName *NewName = NULL;
  CorrName *OldName = NULL;
  
  switch(getIUDEvent()) 
  {
    case COM_INSERT:  // Insert: Need only NEW values
    {
      NewName  = new(heap) CorrName(tableQualName_, heap, NEWCorr);
      scanTree = new(heap) Scan(*NewName);
    }
    break;
    
    case COM_UPDATE: // Update: Need both OLD and NEW values
    {
      OldName  = new(heap) CorrName(tableQualName_, heap, OLDCorr);
      NewName  = new(heap) CorrName(tableQualName_, heap, NEWCorr);
      Scan     *scanOld = new(heap) Scan(*OldName);
      Scan     *scanNew = new(heap) Scan(*NewName);
      scanTree = new(heap) Join(scanOld, scanNew);
    }
    break;
    
    case COM_DELETE: // Delete: Need only OLD values
    {
      OldName  = new(heap) CorrName(tableQualName_, heap, OLDCorr);
      scanTree = new(heap) Scan(*OldName);
    }
    break;
    
    default: CMPASSERT(FALSE);
  }
  
  // Now connect the scan nodes to the trigger action
  if (isAfter())
  {   // An after row trigger is driven from above using a TSJ.
    topNode = new(heap) Join(scanTree, rowTrigger, REL_TSJ);
  }
  else
  {   // A before trigger is driven from below.
    CMPASSERT(rowTrigger->getOperatorType() == REL_BEFORE_TRIGGER);
    // BeforeTrigger nodes are constructed childless.
    rowTrigger->child(0) = scanTree; 
    topNode = rowTrigger;
  }
  
  // TransformNode() will fail if the top most node is not a RelRoot.
  RelRoot  *rootNode   = new(heap) RelRoot(topNode);
  rootNode->setRootFlag(TRUE);
  
  // Now bind the resulting tree.
  return rootNode->bindNode(pBindWA);
}  // StmtDDLCreateTrigger::bindRowTrigger()

//////////////////////////////////////////////////////////////////////////////
// Does the tableName match the Old or New transition names from the
// REFERENCING clause?
//////////////////////////////////////////////////////////////////////////////

// Is this a Scan on the OLD transition table name?
NABoolean StmtDDLCreateTrigger::isOldTransitionName(const NAString& tableName)
{
  if (getOldName() != NULL)
    if (getOldName()->compareTo(tableName) == 0)
      return TRUE;
  return FALSE;
}

// Is this a Scan on the NEW transition table name?
NABoolean StmtDDLCreateTrigger::isNewTransitionName(const NAString& tableName)
{
  if (getNewName() != NULL)
    if (getNewName()->compareTo(tableName) == 0)
      return TRUE;
  return FALSE;
}

NABoolean StmtDDLCreateTrigger::isTransitionName(const NAString& tableName)
{
  return (isOldTransitionName(tableName) || 
    isNewTransitionName(tableName)  );
}


// -----------------------------------------------------------------------
// Before beginning the expanded pass, add the system added columns
// to the select list of the root. This will make sure the system added
// columns are analyzed correctly.
// -----------------------------------------------------------------------
void addSystemColumnsToRootSelectList(RelRoot      *queryRoot, 
				      MVInfoForDDL *mvInfo,
				      BindWA       *bindWA)
{
  // Currently not supporting MJVs because of a bug (SYSKEY is ambiguous).
  if (mvInfo->getMVType() == COM_MJV)
    return;

  // Get the expressions for the system added columns.
  const NAString& systemAddedColsText = mvInfo->getSysColExprs();
  if (systemAddedColsText == "")
    return;

  // Verify that the first char is a ',' and skip it.
  const char *colsTextPtr = systemAddedColsText.data();
  CMPASSERT(colsTextPtr[0] == ',');
  colsTextPtr++;

  // Parse the expression text
  Parser parser(bindWA->currentCmpContext());
  ItemExpr *systemAddedColsExpr = parser.getItemExprTree(colsTextPtr);

  // Add the system added column expressions to the root select list.
  queryRoot->addCompExprTree(systemAddedColsExpr);
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateMV
// -----------------------------------------------------------------------

//
// Virtual function for performing name binding within the Create MV tree
//   This node has three children: 
//
//       ElemDDLNode * pMVColumnList_;
//       ElemDDLNode * pFileOptions_;
//       RelExpr     * pQueryExpression_;
//
//
ExprNode *
StmtDDLCreateMV::bindNode(BindWA * pBindWA )
{
  ComASSERT(pBindWA NEQ NULL);

  pBindWA->setNameLocListPtr(&nameLocList_);
  pBindWA->setUsageParseNodePtr(this);

  MVQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(MVQualName_))
    return this;

  ParNameLoc *pNameLoc
    = nameLocList_.getNameLocPtr(MVQualName_.getNamePosition());
  ComASSERT(pNameLoc);
  pNameLoc->setExpandedName(MVQualName_.getQualifiedNameAsAnsiString());
  MVInfoForDDL *mvInfo = getMVInfo();

  // Bind child nodes
  if (getOptionalColumnNames() != NULL)
    getOptionalColumnNames()->bindNode(pBindWA);

  if (getFileOptions() != NULL)
    getFileOptions()->bindNode(pBindWA);

  // Now call the binder to process the MV's query
  RelExpr *queryExpr = getQueryExpression();
  ComASSERT(queryExpr != NULL);
  ComASSERT(queryExpr->getOperatorType() == REL_ROOT);
  RelRoot *queryRoot = (RelRoot *)queryExpr;

  mvInfo->setRootNode(queryRoot, pBindWA );
  pBindWA->setBindingMvRefresh();
  // Bind the direct tree
  queryExpr = queryRoot->bindNode(pBindWA);
  if (!pBindWA->errStatus())
  {
    queryExpr->collectMVInformation(mvInfo, FALSE);
    mvInfo->processBoundInformation(pBindWA);
    
    // non-recompute mvs on views aren't supported.. remove this when 
    // mvs on views are supported
    if( mvInfo->isOnView() 
        && 
        ((COM_RECOMPUTE != mvInfo->getRefreshType()) &&  (COM_BY_USER !=mvInfo->getRefreshType()))
      )
    {
      *CmpCommon::diags() << DgSqlCode(-4222)
                          << DgString0("Non-recompute MVs on views");
      pBindWA->setErrStatus();
      return this;
    }

    // Transform the direct tree.
    NormWA normWA(CmpCommon::context());
    ExprGroupId eg(queryExpr);
    queryExpr->transformNode(normWA, eg);

    // Normalize the direct tree
    QueryAnalysis* queryAnalysis = CmpCommon::statement()->initQueryAnalysis();
    RelRoot *normRoot = (RelRoot *)eg.getPtr();
    normRoot->normalizeNode(normWA);

    // Set up any UDF references for use
    // by processNormalizedInformation().

    LIST(OptUDFInfo *) &udfMVList = mvInfo->getUDFListForUpdate();
    udfMVList.insert(getUDFList());

    queryExpr->collectMVInformation(mvInfo, TRUE);
    getMVInfo()->processNormalizedInformation(pBindWA);

    if (getMVInfo()->usesOtherMVs())
    {
      // Go over the tables used by the MVs used by this MV.
      // None of them can be directly used by this MV.
      if (!getMVInfo()->areTablesUsedOnlyOnce(pBindWA))
      {
	getMVInfo()->setNotIncremental();
      }
    }

    #ifndef NDEBUG
    if ( CmpCommon::getDefault(MV_DUMP_DEBUG_INFO) == DF_ON )
        mvInfo->display();
    #endif // NA_DEBUG_GUI
  }

  //-----------------------------------
  // bind list of tables in changes clause
  if(statementHasAttributeTableLists())
  {
    if( NULL NEQ pIgnoreChangesList_)
    {
      QualifiedName *pQualName = & (pIgnoreChangesList_->getFirstTableInList());
      pQualName->applyDefaults(pBindWA->getDefaultSchema());
      if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
        return this;
      while(pIgnoreChangesList_->listHasMoreTables())
      {
        pQualName = &(pIgnoreChangesList_->getNextTableInList());
        pQualName->applyDefaults(pBindWA->getDefaultSchema());
        if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
          return this;
      }
    }
  }

  ////---------------------------------------------


  markAsBound();

  pBindWA->setNameLocListPtr(NULL);
  pBindWA->setUsageParseNodePtr(NULL);

  return this;
}



// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropMV
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropMV tree
//
ExprNode * StmtDDLDropMV::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA NEQ NULL);
  MVQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(MVQualName_))
    return this;

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterMV
// -----------------------------------------------------------------------

ExprNode * StmtDDLAlterMV::bindNode(BindWA *pBindWA)
{

  ComASSERT(pBindWA);
  MVQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(MVQualName_))
    return this;

  // bind list of tables in the changes clause
  if( NULL NEQ pIgnoreChangesList_)
  {
    QualifiedName *pQualName = & (pIgnoreChangesList_->getFirstTableInList());
    pQualName->applyDefaults(pBindWA->getDefaultSchema());
    if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
      return this;
    while(pIgnoreChangesList_->listHasMoreTables())
    {
      pQualName = &(pIgnoreChangesList_->getNextTableInList());
      pQualName->applyDefaults(pBindWA->getDefaultSchema());
      if (pBindWA->violateAccessDefaultSchemaOnly(*pQualName))
        return this;
    }
  }

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterView
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterView::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  viewQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(viewQualName_))
    return this;
  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateExceptionTable
// -----------------------------------------------------------------------

ExprNode *
StmtDDLCreateExceptionTable::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  exceptionName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(exceptionName_))
    return this;

  objectReference_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(objectReference_))
    return this;

  if (exceptionName_.getSchemaName() NEQ objectReference_.getSchemaName())
  {
    *CmpCommon::diags() << DgSqlCode(-4222)
                        << DgString0("Exception Tables");
    pBindWA->setErrStatus();
  }

  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateIndex
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Create Index tree
//
ExprNode *
StmtDDLCreateIndex::bindNode(BindWA * pBindWA )
{
  CollIndex index;

  //
  // binds all partition parse nodes associating
  // this Create Table parse node.
  //
  
  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  tableQualName_.applyDefaultsValidate(pBindWA->getDefaultSchema());
/*  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }*/
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;

  indexQualName_= QualifiedName(getIndexName(),tableQualName_.getSchemaName(),
                                tableQualName_.getCatalogName(), pBindWA->wHeap());
  if (pBindWA->violateAccessDefaultSchemaOnly(indexQualName_))
    return this;
  indexName_ = indexQualName_.getQualifiedNameAsAnsiString();  
  
  ComASSERT(getPartitionArray().entries() > 0);
  for (index = 0; index < getPartitionArray().entries(); index ++)
  {
    getPartitionArray()[index]->bindNode(pBindWA);
  }

  if (getPartitionArray()[0]->castToElemDDLPartitionSystem())
  {
    //
    // Note that class ElemDDLPartitionRange is
    // derived from class ElemDDLPartitionSystem.
    // Also note that the primary partition parse
    // node has been bound.
    // 
    guardianLocation_ = getPartitionArray()[0]->castToElemDDLPartitionSystem()
                                              ->getGuardianLocation();
  }

  //
  // sets a flag to let user know that the parse has
  // been bound.
  //

  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateLibrary
// -----------------------------------------------------------------------

ExprNode *
StmtDDLCreateLibrary::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  libraryName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(libraryName_))
    return this;

  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateRoutine
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Create Routine tree
//
ExprNode *
StmtDDLCreateRoutine::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  //
  // expands routine name
  // 

  Int32 defaulted = routineQualName_.applyDefaults(pBindWA->getDefaultSchema());
  Int32 actionDefaulted = 0;
  if (pBindWA->violateAccessDefaultSchemaOnly(routineQualName_))
    return this;
  if (NOT actionQualName_.getObjectName().isNull())
  {
    ComASSERT(getRoutineType() EQU COM_ACTION_UDF_TYPE);
    actionDefaulted = actionQualName_.applyDefaults(pBindWA->getDefaultSchema());
    if (pBindWA->violateAccessDefaultSchemaOnly(actionQualName_))
      return this;
  }

  //
  // diagnose if non-ANSI defaults were applied to the name
  //
  if (NOT routineQualName_.verifyAnsiNameQualification(defaulted) OR
      NOT actionQualName_.verifyAnsiNameQualification(actionDefaulted))
  {
    *CmpCommon::diags() << DgSqlCode(-3206);
    pBindWA->setErrStatus();
  }

  //
  // sets a flag to let user know that the parse has
  // been bound.
  //

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateSynonym
// -----------------------------------------------------------------------

ExprNode *
StmtDDLCreateSynonym::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  synonymName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(synonymName_))
    return this;

  objectReference_.applyDefaultsValidate(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(objectReference_))
    return this;

  if (synonymName_.getCatalogName() NEQ objectReference_.getCatalogName())
  {
    *CmpCommon::diags() << DgSqlCode(-3230);
    pBindWA->setErrStatus();
  }

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateSchema
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Create Schema tree
//
ExprNode *
StmtDDLCreateSchema::bindNode(BindWA * pBindWA)
{
  //  *CmpCommon::diags() <<  DgSqlCode(-4222)
  //                    << DgString0("CREATE SCHEMA");
  //pBindWA->setErrStatus();
  // create schema is a no-op in open source
  markAsBound();
  return this;
} // StmtDDLCreateSchema::bindNode()

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateTable
// -----------------------------------------------------------------------

static void setColNotNullableIfCheckIsISNOTNULL(
                        BindWA * pBindWA,
                        StmtDDLAddConstraintCheck *pAddConstraintCheck,
                        ElemDDLColDefArray &colDefArray)
{
  ElemDDLConstraintCheck *elemDDLC = 
    pAddConstraintCheck->getElemDDLConstraintCheck();

  if (elemDDLC->isDroppable()) return;

  ItemExprList nnndCols(pBindWA->wHeap());
  elemDDLC->getColumnsNotNull(nnndCols);
  for (CollIndex i = 0; i < nnndCols.entries(); i++)
  {
    ItemExpr *nnndCol = nnndCols[i];
    CMPASSERT(nnndCol->getOperatorType() == ITM_REFERENCE);
    NAString colName(
      ((ColReference *)nnndCol)->getColRefNameObj().getColName());
    // Bug fix: CollIndex i scoping error, index j added
    // - Reviewed by Rayees Pasha 3/28/02 
	CollIndex j;
    for (j=0; j < colDefArray.entries(); j++)
      if (colName == colDefArray[j]->getColumnName()) break;
    if (j < colDefArray.entries())
    {
      // Set the column to be not nullable.
      colDefArray[j]->getColumnDataType()->setNullable(FALSE);

      // If user didn't specify any DEFAULT clause,
      // set it to NO DEFAULT (instead of the default of DEFAULT NULL).
      if (colDefArray[j]->getDefaultClauseStatus() == 
          ElemDDLColDef::DEFAULT_CLAUSE_NOT_SPEC)
      {
        colDefArray[j]->setDefaultClauseStatus(
          ElemDDLColDef::NO_DEFAULT_CLAUSE_SPEC);
        CMPASSERT(!colDefArray[j]->getDefaultValueExpr());
      }
    }
  }
} // setColNotNullableIfCheckIsISNOTNULL()

// a virtual function for performing name
// binding within the Create Table tree
//
ExprNode *
StmtDDLCreateTable::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  //
  // expands table name
  // 

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;

  if (getIsLikeOptionSpecified())
  {
    origLikeSourceTableQualName_ = likeSourceTableCorrName_.getQualifiedNameObj();
    likeSourceTableCorrName_.getQualifiedNameObj().applyDefaultsValidate(pBindWA->getDefaultSchema());
    if (pBindWA->violateAccessDefaultSchemaOnly(likeSourceTableCorrName_.getQualifiedNameObj()))
      return this;
  }

  //
  // binds all children
  //

  // binds Primary Key constraint (if exists)

  if (getAddConstraintPK())
  {
    getAddConstraintPK()->bindNode(pBindWA);
  }
  
  CollIndex index;
  Set_SqlParser_Flags(ALLOW_ADD_CONSTRAINT_NOT_DROPPABLE);

  // binds addConstraintCheckArray_

  StmtDDLAddConstraintCheck * pAddConstraintCheck = NULL;
  for (index = 0; index < addConstraintCheckArray_.entries(); index++)
  {
    pAddConstraintCheck = addConstraintCheckArray_[index];
    pAddConstraintCheck->bindNode(pBindWA);
    setColNotNullableIfCheckIsISNOTNULL(pBindWA,
                                        pAddConstraintCheck, getColDefArray());
  }

  // checks addConstraintRIArray_

  StmtDDLAddConstraintRI * pAddConstraintRI = NULL;
  for (index = 0; index < addConstraintRIArray_.entries(); index++)
  {
    pAddConstraintRI = addConstraintRIArray_[index];
    pAddConstraintRI->bindNode(pBindWA);
  }

  // checks addConstraintUniqueArray_

  StmtDDLAddConstraintUnique * pAddConstraintUnique = NULL;
  for (index = 0; index < addConstraintUniqueArray_.entries(); index++)
  {
    pAddConstraintUnique = addConstraintUniqueArray_[index];
    pAddConstraintUnique->bindNode(pBindWA);
  }

  Reset_SqlParser_Flags(ALLOW_ADD_CONSTRAINT_NOT_DROPPABLE);

  //
  // binds all partition parse nodes associating
  // this Create Table parse node.
  //

  ComASSERT(getPartitionArray().entries() > 0);
  for (index = 0; index < getPartitionArray().entries(); index ++)
  {
    getPartitionArray()[index]->bindNode(pBindWA);
  }

  if (getPartitionArray()[0]->castToElemDDLPartitionSystem())
  {
    //
    // Note that class ElemDDLPartitionRange is
    // derived from class ElemDDLPartitionSystem.
    // Also note that the primary partition parse
    // node has been bound.
    // 
    guardianLocation_ = getPartitionArray()[0]->castToElemDDLPartitionSystem()
                                              ->getGuardianLocation();
  }
  //
  // sets a flag to let user know that the parse has
  // been bound.
  //
  markAsBound();

  checkHbasePartitionKey();

  return this;
}

// a virtual function for performing name
// binding within the Create Hbase Table tree
//
ExprNode *
StmtDDLCreateHbaseTable::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  //
  // expands table name
  // 

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }

  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;

  // sets a flag to let user know that the parse has
  // been bound.
  //

  markAsBound();
  return this;
}

//New comments
//--This check will cover following cases:
//------When primary key columns specified------
//--1.PARTITION BY clause is not allowed for trafodion table.
//--2.STORE BY column list(if any) == primay key column list, also ordinally equal.
//------When no primary key columns specified------
//--3.PARTITION BY clause is not allowed for trafodion table.
//--[Already catched by 1195]Salt columns must be subset of clustering key, in any order.
//--[Already catched by 1195]There must be STORE BY or PRIMARY KEY columns.
void 
StmtDDLCreateTable::checkHbasePartitionKey()
{
  //Called as last step of bind.
  if (!nodeIsBound())
    return;

  //Make sure table created is in TRAFODION catalog
  QualifiedName qualifiedTableName = getTableNameAsQualifiedName();
  if (NOT (qualifiedTableName.getCatalogName() == TRAFODION_SYSCAT_LIT))
    return;

  //Disable PARTITION BY clause for tables of TRAFODION catalog.
  if (getPartitionKeyColRefArray().entries() > 0 )
  {
    *CmpCommon::diags() << DgSqlCode(-1199);
    return;
  }
  //Check primary key and clustering key consistant
  if(getStoreOption() == COM_KEY_COLUMN_LIST_STORE_OPTION 
       && getKeyColumnArray().entries() > 0 
       && getPrimaryKeyColRefArray().entries() > 0)
  {
    if (getPrimaryKeyColRefArray() != getKeyColumnArray())
    {
      *CmpCommon::diags() << DgSqlCode(-1193) 
                          << DgString0 ("clustering key")
                          << DgString1 ("STORE BY");
      return;
    }
  }
}

ExprNode *
StmtDDLCreateSequence::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  if (applyDefaultsAndValidateObject(pBindWA, &seqQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }

  // update default values
  ElemDDLSGOptions * sgo = getSGoptions();

  if (isAlter())
    {
      CorrName cn(getSeqNameAsQualifiedName(), (CollHeap*)NULL, NAString());
      cn.setSpecialType(ExtendedQualName::SG_TABLE);
      NATable *naTable = pBindWA->getNATable(cn); 
      if (naTable == NULL || pBindWA->errStatus())
        {
          return this;
        }
      
      const SequenceGeneratorAttributes* sga = naTable->getSGAttributes();
      if (sga)
        {
          ElemDDLSGOptions tempSGO;
          tempSGO.importSGA(sga);
          
          if (sgo)
            {
              tempSGO.importSGO(sgo);
            }
          
          if (tempSGO.validate(1/*alter sequence*/))
            {
              return this;
            }
        }
    }
  else
    {
      if (sgo->getFSDataType() == COM_UNKNOWN_FSDT)
        sgo->setFSDataType(COM_SIGNED_BIN64_FSDT);
      if (sgo->validate(isAlter() ? 1 : 0))
        {
          pBindWA->setErrStatus();
          
          return this;
        }
    }

  markAsBound();

  return this;
}

ExprNode * StmtDDLDropSequence::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  if (applyDefaultsAndValidateObject(pBindWA, &seqQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }

  markAsBound();

  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCreateView
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the CreateView tree
//
ExprNode *
StmtDDLCreateView::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  // QSTUFF
  CmpMain cmp;
  NormWA normWA(CmpCommon::context());
  // QSTUFF

  pBindWA->setNameLocListPtr(&nameLocList_);
  pBindWA->setUsageParseNodePtr(this);
  viewQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(viewQualName_))
    return this;
  
  ParNameLoc *pNameLoc
    = nameLocList_.getNameLocPtr(viewQualName_.getNamePosition());
  ComASSERT(pNameLoc);
  pNameLoc->setExpandedName(viewQualName_.getQualifiedNameAsAnsiString());

  // not allowed on volatile objects.
  CmpCommon::context()->sqlSession()->disableVolatileSchemaInUse();
  
  for (Int32 i = 0; i < getArity(); i++)
  {
    if (getChild(i))
    {
      if (getChild(i)->castToElemDDLNode())
      {
        getChild(i)->castToElemDDLNode()->bindNode(pBindWA);
      }
      else if (getChild(i)->castToRelExpr())
      {
        RelExpr *queryExpr = getChild(i)->castToRelExpr()->bindNode(pBindWA);
        if (!pBindWA->errStatus())
        {
          // If the operator type not REL_ROOT, reset VolatileSchemaInUse and
          // assert
          if (queryExpr->getOperatorType() != REL_ROOT)
          {
            CmpCommon::context()->sqlSession()->restoreVolatileSchemaInUse();
            CMPASSERT(FALSE);
          }

          ((RelRoot *)queryExpr)->setRootFlag(TRUE);

          // we need to check unique constraints on joins when 
          // when binding a view containing an embedded update
	  if (pBindWA->isEmbeddedIUDStatement())
	  {
            CmpCommon::context()->sqlSession()->restoreVolatileSchemaInUse();
	    *CmpCommon::diags() << DgSqlCode(-3218);
	    pBindWA->setErrStatus();
	    return this;
	  }

          queryExpr = cmp.transform(normWA, queryExpr);

          ComASSERT(queryExpr->getOperatorType() == REL_ROOT);
          RelRoot *rootExpr = (RelRoot *)queryExpr;
          isUpdatable_ = rootExpr->isUpdatableView(isInsertable_);

          if (getViewColDefArray().entries() == 0)
          {
            const ColumnDescList &colDescList = 
              *rootExpr->getRETDesc()->getColumnList();
            for (CollIndex i=0; i<colDescList.entries(); i++)
            {
              // Get internal colname, not external Ansi-format string
              getViewColDefArray().insert(
                new (pBindWA->wHeap()) ElemDDLColViewDef(
                  colDescList[i]->getColRefNameObj().getColName()));
            }
          }
          
          // Change to always flush information to the metadata
          if (getIsUpdatable())
          {
            //
            // For certain cases, the binder could guess that
            // the view is not updatable.  Better check to
            // make sure that the binder guessed correctly.
            //
            if (getViewUsages().isViewSurelyNotUpdatable())
            {
              CmpCommon::context()->sqlSession()->restoreVolatileSchemaInUse();
              CMPASSERT(FALSE);
            }
          }

          QueryAnalysis* queryAnalysis = CmpCommon::statement()->initQueryAnalysis();
          queryExpr = cmp.normalize(normWA, queryExpr);
          queryExpr->synthLogProp();

        } // if (!pBindWA->errStatus())
      }
      else
      {
        ABORT("internal logic error");
      }
    }
  }
  CmpCommon::context()->sqlSession()->restoreVolatileSchemaInUse();
  markAsBound();

  pBindWA->setNameLocListPtr(NULL);
  pBindWA->setUsageParseNodePtr(NULL);
  
  return this;
} // StmtDDLCreateView::bindNode

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropCatalog
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropCatalog tree
//
ExprNode *
StmtDDLDropCatalog::bindNode(BindWA *  /* bindWAPtr */ )
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropConstraint
// -----------------------------------------------------------------------

ExprNode *
StmtDDLDropConstraint::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  QualifiedName &tableQualName = getTableNameAsQualifiedName();
  tableQualName.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName))
    return this;

  QualifiedName & constraintQualName = getConstraintNameAsQualifiedName();
  constraintQualName.applyDefaults(tableQualName);
  if (pBindWA->violateAccessDefaultSchemaOnly(constraintQualName))
    return this;

  if (tableQualName.getCatalogName() NEQ constraintQualName.getCatalogName()
      OR
      tableQualName.getSchemaName() NEQ constraintQualName.getSchemaName())
  {
    *CmpCommon::diags() << DgSqlCode(-3050);
    pBindWA->setErrStatus();
  }
  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropIndex
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropIndex tree
//
ExprNode *
StmtDDLDropIndex::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  // remember the original index name specified by user
  origIndexQualName_ = indexQualName_;

  indexQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(indexQualName_))
    return this;

  markAsBound();
  return this;
}


// ----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropLibrary
// ----------------------------------------------------------------------

ExprNode *
StmtDDLDropLibrary::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  libraryName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(libraryName_))
    return this;

  markAsBound();
  return this;
}



// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropSchema
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropSchema tree
//
ExprNode *
StmtDDLDropSchema::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  if (pBindWA->raiseAccessDefaultSchemaOnlyError())
    return this;

  // expand schema Name.

  if (schemaQualName_.getCatalogName().isNull())
  {
    schemaQualName_.setCatalogName(pBindWA->getDefaultSchema().
                                   getCatalogName());
  }
     
  schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." + 
                ToAnsiIdentifier(schemaQualName_.getSchemaName()) ;

  markAsBound();

  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterSchema
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the AlterSchema tree
//
ExprNode *
StmtDDLAlterSchema::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  if (pBindWA->raiseAccessDefaultSchemaOnlyError())
    return this;

  // expand schema Name.

  if (schemaQualName_.getCatalogName().isNull())
  {
    schemaQualName_.setCatalogName(pBindWA->getDefaultSchema().
                                   getCatalogName());
  }
     
  schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." + 
                ToAnsiIdentifier(schemaQualName_.getSchemaName()) ;

  markAsBound();

  return this;
}

// ----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropSynonym
// ----------------------------------------------------------------------

ExprNode *
StmtDDLDropSynonym::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  synonymName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(synonymName_))
    return this;

  markAsBound();
  return this;
}

// ----------------------------------------------------------------------
// defination of method bindnode() for class StmtDDLDropModule
// ----------------------------------------------------------------------

ExprNode *
StmtDDLDropModule::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  moduleQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(moduleQualName_))
    return this;

  moduleName_ = moduleQualName_.getQualifiedNameAsAnsiString();
  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropTable
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropTable tree
//
ExprNode *
StmtDDLDropTable::bindNode(BindWA *  pBindWA)
{
  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropHbaseTable
// -----------------------------------------------------------------------

ExprNode *
StmtDDLDropHbaseTable::bindNode(BindWA *  pBindWA)
{
  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropView
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropView tree
//
ExprNode *
StmtDDLDropView::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  viewQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(viewQualName_))
    return this;

  markAsBound();
  return this;
}


// ----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropExceptionTable
// ----------------------------------------------------------------------

ExprNode *
StmtDDLDropExceptionTable::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  objectReference_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(objectReference_))
    return this;

  // If a single exception table is to be dropped verify 
  // exception table & schema match
  if (dropType_ == COM_DROP_SINGLE)
  {
     exceptionName_.applyDefaults(pBindWA->getDefaultSchema());
     if (pBindWA->violateAccessDefaultSchemaOnly(exceptionName_))
       return this;
     if (exceptionName_.getSchemaName() NEQ objectReference_.getSchemaName())
     {
       *CmpCommon::diags() << DgSqlCode(-4222)
                           << DgString0("Exception Tables");
       pBindWA->setErrStatus();
     }
  }

  markAsBound();
  return this;
}


//----------------------------------------------------------------------------
// StmtDDLAlterTableAlterColumnLoggable
//----------------------------------------------------------------------------

ExprNode *
StmtDDLAlterTableAlterColumnLoggable::bindNode(BindWA * pBindWA)
{
  StmtDDLAlterTable::bindNode(pBindWA);
  
  CorrName tableCorrName(getTableNameAsQualifiedName(), (CollHeap*)0, 
			 NAString() //no corr. name
			 );
  
  NATable *pNaTable = pBindWA->getNATable(tableCorrName,
					  FALSE //don't collect usage info
					  );
  
  if (pBindWA->errStatus())
    {
      return this;
    }
  
  
  const NAColumnArray & columnArray = pNaTable->getNAColumnArray();
  
  NAColumn * pColumn = columnArray.getColumn(columnName_.data());
  
  if(NULL == pColumn)
    {
      // If we are getting -4001,-4002 or -4003 when binding an ORDER BY column,
    }
  else
    {
      columnNum_ = pColumn->getPosition();
    }
  
  
  return this;
} // StmtDDLAlterTableAlterColumnLoggable::bindNode





// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLDropRoutine
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the DropRoutine tree
//
ExprNode *
StmtDDLDropRoutine::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  Int32 defaulted = routineQualName_.applyDefaults(pBindWA->getDefaultSchema());
  Int32 actionDefaulted = 0;
  if (pBindWA->violateAccessDefaultSchemaOnly(routineQualName_))
    return this;
  if (NOT routineActionQualName_.getObjectName().isNull())
  {
    ComASSERT(getRoutineType() EQU COM_ACTION_UDF_TYPE);
    actionDefaulted = routineActionQualName_.applyDefaults(pBindWA->getDefaultSchema());
    if (pBindWA->violateAccessDefaultSchemaOnly(routineActionQualName_))
      return this;
  }

  //
  // diagnose if non-ANSI defaults were applied to the name.
  //
  if (NOT routineQualName_.verifyAnsiNameQualification(defaulted) OR
      NOT routineActionQualName_.verifyAnsiNameQualification(actionDefaulted))
  {
    *CmpCommon::diags() << DgSqlCode(-3206);
    pBindWA->setErrStatus();
  }

  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLAlterTable
// -----------------------------------------------------------------------

ExprNode *
StmtDDLAlterTable::bindNode(BindWA * pBindWA)
{

  ComASSERT(pBindWA);

  // remember the original table name specified by user
  origTableQualName_ = tableQualName_;

  //  tableQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &tableQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(tableQualName_))
    return this;

  CollIndex index;
  if (getOperatorType() == DDL_ALTER_TABLE_ADD_COLUMN)
  {
    StmtDDLAlterTableAddColumn *altAddCol =
      castToStmtDDLAlterTableAddColumn();
    
    if (altAddCol->getAddConstraintPK())
    {
      altAddCol->getAddConstraintPK()->bindNode(pBindWA);
    }

    Set_SqlParser_Flags(ALLOW_ADD_CONSTRAINT_NOT_DROPPABLE);
    
    // Bind Check constraints

    StmtDDLAddConstraintCheck * pAddConstraintCheck = NULL;
    StmtDDLAddConstraintCheckArray &addConstraintCheckArray =
      altAddCol->getAddConstraintCheckArray();
    for (index = 0; index < addConstraintCheckArray.entries(); index++)
    {
      pAddConstraintCheck = addConstraintCheckArray[index];
      pAddConstraintCheck->bindNode(pBindWA);
      ElemDDLColDefArray colDefArray;
      colDefArray.insert((altAddCol->getColToAdd ())->castToElemDDLColDef());
      setColNotNullableIfCheckIsISNOTNULL(pBindWA,
                                          pAddConstraintCheck, colDefArray);
    }
    
    // Bind RI Constraints

    StmtDDLAddConstraintRI * pAddConstraintRI = NULL;
    StmtDDLAddConstraintRIArray &addConstraintRIArray =
      altAddCol->getAddConstraintRIArray();
    for (index = 0; index < addConstraintRIArray.entries(); index++)
    {
      pAddConstraintRI = addConstraintRIArray[index];
      pAddConstraintRI->bindNode(pBindWA);
    }
    
    // Bind Unique constraints

    StmtDDLAddConstraintUnique * pAddConstraintUnique = NULL;
    StmtDDLAddConstraintUniqueArray &addConstraintUniqueArray =
      altAddCol->getAddConstraintUniqueArray();
    for (index = 0; index < addConstraintUniqueArray.entries(); index++)
    {
      pAddConstraintUnique = addConstraintUniqueArray[index];
      pAddConstraintUnique->bindNode(pBindWA);
    }
    
    Reset_SqlParser_Flags(ALLOW_ADD_CONSTRAINT_NOT_DROPPABLE);
  }
  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLGrant
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Grant tree
//
ExprNode *
StmtDDLGrant::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  //  objectQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &objectQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(objectQualName_))
    return this;

  objectName_ = objectQualName_.getQualifiedNameAsAnsiString();

  // If specified, validate actionQualName
  if (actionQualName_)
  {
    if (applyDefaultsAndValidateObject(pBindWA, actionQualName_))
      {
        pBindWA->setErrStatus();
        return this;
      }
    if (pBindWA->violateAccessDefaultSchemaOnly(*actionQualName_))
      return this;
  }

  // If SELECT privilege is specified, make sure it does not contain
  // a column list
  //const ElemDDLPrivActArray &privList = getPrivilegeActionArray();
  //for (CollIndex pos = 0; pos < privList.entries(); pos++)
  //{
  //  const ElemDDLPrivActWithColumns * pPrivCols = NULL;
  //  if (privList[pos]->getOperatorType() == ELM_PRIV_ACT_SELECT_ELEM ||
  //      privList[pos]->getOperatorType() == ELM_PRIV_ACT_INSERT_ELEM)
  //  {
  //    pPrivCols = (const ElemDDLPrivActWithColumns *)privList[pos];
  //    if (pPrivCols != NULL)
  //    {
  //      if (pPrivCols->getColumnNameArray().entries() > 0) //columns exist
  //      {
  //        *CmpCommon::diags() << DgSqlCode(-3028);
  //        pBindWA->setErrStatus();
  //      }
  //    }
  //  }
  //}
  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLSchGrant
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Schema Grant tree
//
ExprNode *
StmtDDLSchGrant::bindNode(BindWA * pBindWA)
{   
  ComASSERT(pBindWA);

  if (schemaQualName_.getCatalogName().isNull())
  {
    schemaQualName_.setCatalogName(pBindWA->getDefaultSchema().
                                   getCatalogName());
  }
  QualifiedName qn("",
    ToAnsiIdentifier(schemaQualName_.getSchemaName()),
    ToAnsiIdentifier(schemaQualName_.getCatalogName()));
  if (pBindWA->violateAccessDefaultSchemaOnly(qn))
    return this;
     
  schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." + 
                ToAnsiIdentifier(schemaQualName_.getSchemaName()) ;  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLGiveAll
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Give All tree
//
ExprNode *
StmtDDLGiveAll::bindNode(BindWA * pBindWA)
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLGiveCatalog
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Give Catalog tree
//
ExprNode *
StmtDDLGiveCatalog::bindNode(BindWA * pBindWA)
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLGiveObject
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Give Object tree
//
ExprNode *
StmtDDLGiveObject::bindNode(BindWA * pBindWA)
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLGiveSchema
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Give Schema tree
//
ExprNode *
StmtDDLGiveSchema::bindNode(BindWA * pBindWA)
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLInitializeSQL
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the InitializeSQL tree
//
ExprNode *
StmtDDLInitializeSQL::bindNode(BindWA *  /* bindWAPtr */ )
{
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLRevoke
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Revoke tree
//
ExprNode *
StmtDDLRevoke::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  //  objectQualName_.applyDefaults(pBindWA->getDefaultSchema());
  if (applyDefaultsAndValidateObject(pBindWA, &objectQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  if (pBindWA->violateAccessDefaultSchemaOnly(objectQualName_))
    return this;

  objectName_ = objectQualName_.getQualifiedNameAsAnsiString();

// If specified, validate actionQualName
  if (actionQualName_)
  {
    if (applyDefaultsAndValidateObject(pBindWA, actionQualName_))
      {
        pBindWA->setErrStatus();
        return this;
      }
    if (pBindWA->violateAccessDefaultSchemaOnly(*actionQualName_))
      return this;
  }

 // a column list
  //const ElemDDLPrivActArray &privList = getPrivilegeActionArray();
  //for (CollIndex pos = 0; pos < privList.entries(); pos++)
  //{
  //  const ElemDDLPrivActWithColumns * pPrivCols = NULL;
  //  if (privList[pos]->getOperatorType() == ELM_PRIV_ACT_SELECT_ELEM ||
  //      privList[pos]->getOperatorType() == ELM_PRIV_ACT_INSERT_ELEM)
  //  {
  //    pPrivCols = (const ElemDDLPrivActWithColumns *)privList[pos];
  //    if (pPrivCols != NULL)
  //    {
  //      if (pPrivCols->getColumnNameArray().entries() > 0) //columns exist
  //      {
  //        *CmpCommon::diags() << DgSqlCode(-3028);
  //        pBindWA->setErrStatus();
  //      }
  //    }
  //  }
  //}

  markAsBound();
  return this;
}


// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLSchRevoke
// -----------------------------------------------------------------------

//
// a virtual function for performing name
// binding within the Revoke tree
//
ExprNode *
StmtDDLSchRevoke::bindNode(BindWA * pBindWA)
{  
  ComASSERT(pBindWA);

  if (schemaQualName_.getCatalogName().isNull())
  {
    schemaQualName_.setCatalogName(pBindWA->getDefaultSchema().
                                   getCatalogName());
  }
  QualifiedName qn("",
    ToAnsiIdentifier(schemaQualName_.getSchemaName()),
    ToAnsiIdentifier(schemaQualName_.getCatalogName()));
  if (pBindWA->violateAccessDefaultSchemaOnly(qn))
    return this;

  schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." + 
                ToAnsiIdentifier(schemaQualName_.getSchemaName()) ;
  
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// bindNode() for class StmtDDLRegisterUser
// -----------------------------------------------------------------------
//
////
// a virtual function for performing name
// binding within the Register user tree.
//
ExprNode *
StmtDDLRegisterUser::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// bindNode() for class StmtDDLRegOrUnregObject
// -----------------------------------------------------------------------
//
////
// a virtual function for performing name
// binding within the Register hive tree.
//
ExprNode *
StmtDDLRegOrUnregObject::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  if (storageType_ == HBASE)
    {
      if (origObjName_.numberExpanded() == 1)
        {
          objQualName_ = QualifiedName(origObjName_.getObjectName(),
                                       NAString(HBASE_SYSTEM_SCHEMA),
                                       NAString(HBASE_SYSTEM_CATALOG));
        }
      
     if (origObjName_.numberExpanded() == 2)
        {
          *CmpCommon::diags() << DgSqlCode(-1026)
                              << DgString0(origObjName_.getQualifiedNameAsString());
          pBindWA->setErrStatus();
          return NULL;
        }
 
     if ((origObjName_.numberExpanded() == 3) &&
         ((origObjName_.getCatalogName() != HBASE_SYSTEM_CATALOG) ||
          (NOT ((origObjName_.getSchemaName() == HBASE_CELL_SCHEMA) ||
                (origObjName_.getSchemaName() == HBASE_ROW_SCHEMA) ||
                (origObjName_.getSchemaName() == HBASE_MAP_SCHEMA)))))
        {
          *CmpCommon::diags() << DgSqlCode(-1026)
                              << DgString0(origObjName_.getQualifiedNameAsString());
          pBindWA->setErrStatus();
          return NULL;
        }
    }
  

  if ((storageType_ == HIVE) &&
      (objType_ == COM_SHARED_SCHEMA_OBJECT) &&
      (origObjName_.numberExpanded() == 2)) 
    {
      objQualName_ = QualifiedName(NAString("__SCHEMA__"),
                                   origObjName_.getObjectName(),
                                   NAString(HIVE_SYSTEM_CATALOG));
    }
  
  if (applyDefaultsAndValidateObject(pBindWA, &objQualName_))
    {
      pBindWA->setErrStatus();
      return this;
    }
  
  if (((storageType_ == HIVE) &&
       (objQualName_.getCatalogName() != HIVE_SYSTEM_CATALOG)) ||
      ((storageType_ == HBASE) &&
       (objQualName_.getCatalogName() != HBASE_SYSTEM_CATALOG)))
    {
      *CmpCommon::diags() << DgSqlCode(-1026)
                          << DgString0(origObjName_.getQualifiedNameAsString());
      pBindWA->setErrStatus();
      return NULL;
    }
      
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// bindNode() for class StmtDDLRoleGrant
// -----------------------------------------------------------------------
//
// a virtual function for performing name
// binding within the Create role tree.
//
ExprNode *
StmtDDLRoleGrant::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// bindNode() for class StmtDDLCreateRole
// -----------------------------------------------------------------------
//
// a virtual function for performing name
// binding within the Create role tree.
//
ExprNode *
StmtDDLCreateRole::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);
  markAsBound();
  return this;
}

// -----------------------------------------------------------------------
// bindNode() for class StmtDDLAlterUser  
// -----------------------------------------------------------------------
//
////
// a virtual function for performing name
// binding within the Alter User tree.
//
ExprNode *
StmtDDLAlterUser::bindNode(BindWA * pBindWA)
{

   ComASSERT(pBindWA);
   markAsBound();
   return this;

}

// -----------------------------------------------------------------------
// definition of method bindNode() for class StmtDDLCommentOn
// -----------------------------------------------------------------------

ExprNode *
StmtDDLCommentOn::bindNode(BindWA * pBindWA)
{
  ComASSERT(pBindWA);

  objectName_.applyDefaults(pBindWA->getDefaultSchema());
  if (pBindWA->violateAccessDefaultSchemaOnly(objectName_))
    return this;

  if (this->type_ == COMMENT_ON_TYPE_COLUMN)
    {
      if (NULL == colRef_)
        {
          ComASSERT(pBindWA);
        }
      else
        {
          ActiveSchemaDB()->getNATableDB()->useCache();

          CorrName cn(objectName_, STMTHEAP);

          NATable *naTable = pBindWA->getNATable(cn);
          if (naTable == NULL || pBindWA->errStatus())
            {
              *CmpCommon::diags()
                << DgSqlCode(-4082)
                << DgTableName(cn.getExposedNameAsAnsiString());

              return this;
            }

          const NAColumnArray &nacolArr = naTable->getNAColumnArray();
          const NAColumn * nacol = nacolArr.getColumn(getColName());
          if (! nacol)
            {
              // column doesnt exist. Error.
              *CmpCommon::diags() << DgSqlCode(-1009)
                                  << DgColumnName(getColName());

              return this;
            }

          isViewCol_ = (naTable->getViewText() ? TRUE : FALSE);
          colNum_ = nacol->getPosition();
        }
    }

  markAsBound();
  return this;
}


//
// End of File
//
