/**********************************************************************
// @@@ 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:         CmpSeabaseDDLcommon.cpp
 * Description:  Implements common methods and operations for SQL/hbase tables.
 *
 *
 * Created:     6/30/2013
 * Language:     C++
 *
 *
 *****************************************************************************
 */

#include "CmpSeabaseDDLincludes.h"
#include "CmpSeabaseDDLcleanup.h"
#include "RelExeUtil.h"
#include "ControlDB.h"
#include "NumericType.h"
#include "CmpDDLCatErrorCodes.h"
#include "ValueDesc.h"
#include "Globals.h"
#include "Context.h"
#include "ExSqlComp.h"
#include "CmpSeabaseDDLauth.h"
#include "NAUserId.h"
#include "StmtDDLCreateView.h"
#include "StmtDDLDropView.h"
#include "StmtDDLAlterTableDisableIndex.h"
#include "StmtDDLAlterTableEnableIndex.h"
#include "StmtDDLCreateComponentPrivilege.h"
#include "StmtDDLDropComponentPrivilege.h"
#include "StmtDDLGive.h"
#include "StmtDDLGrantComponentPrivilege.h"
#include "StmtDDLRevokeComponentPrivilege.h"
#include "StmtDDLRegisterComponent.h"
#include "StmtDDLCreateRole.h"
#include "StmtDDLRoleGrant.h"
#include "PrivMgrCommands.h"
#include "PrivMgrMD.h"
#include "PrivMgrComponentPrivileges.h"
#include "PrivMgrPrivileges.h"
#include "PrivMgrRoles.h"
#include "ComUser.h"
#include "ComMisc.h"
#include "CmpSeabaseDDLmd.h"
#include "CmpSeabaseDDLroutine.h"
#include "StmtDDLAlterLibrary.h"
#include "logmxevent_traf.h"
#include "exp_clause_derived.h"
#include "TrafDDLdesc.h"

void cleanupLOBDataDescFiles(const char*, int, const char *);

class QualifiedSchema
{
public:
   char catalogName[ComMAX_ANSI_IDENTIFIER_INTERNAL_LEN + 1];
   char schemaName[ComMAX_ANSI_IDENTIFIER_INTERNAL_LEN + 1];
};

static __thread MDDescsInfo * trafMDDescsInfo_ = NULL;

static void createSeabaseComponentOperation(
   const std::string & systemCatalog,
   StmtDDLCreateComponentPrivilege *pParseNode);
   
static void dropSeabaseComponentOperation(
   const std::string & systemCatalog,
   StmtDDLDropComponentPrivilege *pParseNode);
   
static void grantSeabaseComponentPrivilege(
   const std::string & systemCatalog,
   StmtDDLGrantComponentPrivilege *pParseNode);
   
static void revokeSeabaseComponentPrivilege(
   const std::string & systemCatalog,
   StmtDDLRevokeComponentPrivilege *pParseNode);
   
static void grantRevokeSeabaseRole(
   const std::string & systemCatalog,
   StmtDDLRoleGrant *pParseNode);   
   
static bool hasValue(
   std::vector<int32_t> container,
   int32_t value);   

static NABoolean isTrueFalseStr(const NAText& str);
static NABoolean isHBaseCompressionOption(const NAText& str);
static NABoolean isHBaseDurabilityOption(const NAText& str);
static NABoolean isHBaseEncodingOption(const NAText& str);
static NABoolean isHBaseBloomFilterOption(const NAText& str);


#include "EncodedKeyValue.h"
#include "SCMVersHelp.h"

CmpSeabaseDDL::CmpSeabaseDDL(NAHeap *heap, NABoolean syscatInit)
{
  savedCmpParserFlags_ = 0;
  savedCliParserFlags_ = 0;
  heap_ = heap;
  cmpSwitched_ = FALSE;

  if ((syscatInit) && (ActiveSchemaDB()))
    {
      const char* sysCat = ActiveSchemaDB()->getDefaults().getValue(SEABASE_CATALOG);
      
      seabaseSysCat_ = sysCat;
      CONCAT_CATSCH(seabaseMDSchema_,sysCat,SEABASE_MD_SCHEMA);
    }
}

// We normally don't send user CQDs to the metadata CmpContext.
// To bypass this set the env variable TRAF_PROPAGATE_USER_CQDS to 1.
// The sendAllControlsAndFlags() uses current CmpContext pointer, if given,
// to get the user CQDs and pass them to the new CmpContext.
static THREAD_P Int32 passingUserCQDs = -1;

// RETURN: -1, if error. 0, if context switched successfully.
short CmpSeabaseDDL::switchCompiler(Int32 cntxtType)
{
  if (passingUserCQDs == -1)
    {
      const char *pucStr = getenv("TRAF_PROPAGATE_USER_CQDS");
      passingUserCQDs = 0;  // check the flag only once
      if (pucStr != NULL && atoi(pucStr) == 1)
        passingUserCQDs = 1;
    }

  cmpSwitched_ = FALSE;
  CmpContext* currContext = CmpCommon::context();

  // we should switch to another CI only if we are in an embedded CI
  if (IdentifyMyself::GetMyName() == I_AM_EMBEDDED_SQL_COMPILER)
    {
      if (SQL_EXEC_SWITCH_TO_COMPILER_TYPE(cntxtType))
        {
          // failed to switch/create compiler context.
          return -1;
        }
  
      cmpSwitched_ = TRUE;
    }

  if (sendAllControlsAndFlags(currContext, cntxtType))
    {
      switchBackCompiler();
      return -1;
    }

  return 0;
}


short CmpSeabaseDDL::switchBackCompiler()
{

  if (cmpSwitched_)
  {
      GetCliGlobals()->currContext()->copyDiagsAreaToPrevCmpContext();
      CmpCommon::diags()->clear();
  }
  // do restore here even though switching may not have happened, i.e.
  // when switchToCompiler() was not called by the embedded CI, see above.
  restoreAllControlsAndFlags();
  
  if (cmpSwitched_)
    {
      // Clear the diagnostics area of the current CmpContext
      CmpCommon::diags()->clear();
      // switch back to the original commpiler, ignore return error
      SQL_EXEC_SWITCH_BACK_COMPILER();

      cmpSwitched_ = FALSE;
    }

  return 0;
}

// ----------------------------------------------------------------------------
// Method: getMDtableInfo
//
// When compiler context is instantiated, definitions of system and privmgr
// metadata tables are stored as an array of MDDescsInfo structs.  
//
// This method searches the list of MDDescsInfo structs looking for the 
// entry corresponding to the passed in name.
//
// Parameters:
//  input:
//    name - the fully qualified metadata table
//    objType - the object type (base table, index, etc)
//
//  output:
//    tableInfo, 
//    colInfoSize, colInfo, 
//    keyInfoSize, keyInfo, 
//    indexInfoSize, indexInfo
//
// Return:  TRUE, object is cached, FALSE, object not found (or error)
//
// Possible enhancements, instead of returning columns for each value in
// the MDDescsInfo entry, just return the MDDescsInfo entry
// ----------------------------------------------------------------------------
NABoolean CmpSeabaseDDL::getMDtableInfo(const ComObjectName &name,
                                        ComTdbVirtTableTableInfo* &tableInfo,
                                        Lng32 &colInfoSize,
                                        const ComTdbVirtTableColumnInfo* &colInfo,
                                        Lng32 &keyInfoSize,
                                        const ComTdbVirtTableKeyInfo * &keyInfo,
                                        Lng32 &indexInfoSize,
                                        const ComTdbVirtTableIndexInfo* &indexInfo,
                                        const ComObjectType objType)
{
  tableInfo = NULL;
  indexInfoSize = 0;
  indexInfo = NULL;

  NAString objName = name.getObjectNamePartAsAnsiString();
  if (objName.isNull())
    return FALSE;

  // If metadata tables have not yet been added to the compiler context, 
  // return FALSE
  if (! CmpCommon::context()->getTrafMDDescsInfo())
    return FALSE;

  // The first set of objects are system metadata.  Check the passed in
  // objName and objType for a match
  if (isSeabaseMD(name.getCatalogNamePartAsAnsiString(),
                  name.getSchemaNamePartAsAnsiString(TRUE),
                  name.getObjectNamePartAsAnsiString()))
    { 
      for (Int32 i = 0; i < sizeof(allMDtablesInfo)/sizeof(MDTableInfo); i++)
        {
          const MDTableInfo &mdti = allMDtablesInfo[i];
      
          if (! mdti.newName)
            return FALSE;

          MDDescsInfo &mddi = CmpCommon::context()->getTrafMDDescsInfo()[i];

          if (objName == mdti.newName)
            {
              if (objType == COM_BASE_TABLE_OBJECT)
                {
                  colInfoSize = mddi.numNewCols;
                  colInfo = mddi.newColInfo;
                  keyInfoSize = mddi.numNewKeys;
                  keyInfo = mddi.newKeyInfo;

                  indexInfoSize = mddi.numIndexes;
                  indexInfo = mddi.indexInfo;

                  // this is an index. It cannot selected as a base table objects.
                  if (mdti.isIndex)
                    return FALSE;
                }
              else if (objType == COM_INDEX_OBJECT)
                {
                  colInfoSize = mddi.numNewCols;
                  colInfo = mddi.newColInfo;
                  keyInfoSize = mddi.numNewKeys;
                  keyInfo = mddi.newKeyInfo;

                }
              else
                return FALSE;

              if (mddi.tableInfo == NULL)
                {
                  const NAString catName(TRAFODION_SYSCAT_LIT);
                  const NAString schName(SEABASE_MD_SCHEMA);
                  NAString extTableName = catName + "." + "\"" + schName + "\"" + "." + objName;

                  CmpSeabaseDDL cmpSBD(STMTHEAP);
                  if (cmpSBD.getSpecialTableInfo(CTXTHEAP,
                                                 catName, schName, objName, extTableName, 
                                                 objType, tableInfo) == 0)
                    mddi.tableInfo = (ComTdbVirtTableTableInfo*)tableInfo;
                  else
                    return FALSE; // error
                }
              else
                tableInfo = mddi.tableInfo;

              return TRUE;
            }
          else  //if (mdti.oldName && (objName == mdti.oldName))
            {
              const char * oldName = NULL;
              const QString * oldDDL = NULL;
              Lng32 sizeOfoldDDL = 0;
              if (getOldMDInfo(mdti, oldName, oldDDL, sizeOfoldDDL) == FALSE)
                return FALSE;

              if ((oldName) && (objName == oldName))
                {
                  if ((mddi.numOldCols > 0) && (mddi.oldColInfo))
                    {
                      colInfoSize = mddi.numOldCols;
                      colInfo = mddi.oldColInfo;
                    }
                  else
                    {
                      colInfoSize = mddi.numNewCols;
                      colInfo = mddi.newColInfo;
                    }
              
                  if ((mddi.numOldKeys > 0) && (mddi.oldKeyInfo))
                    {
                      keyInfoSize = mddi.numOldKeys;
                      keyInfo = mddi.oldKeyInfo;
                    }
                  else
                    {
                      keyInfoSize = mddi.numNewKeys;
                      keyInfo = mddi.newKeyInfo;
                    }

                  return TRUE;
                } // oldName
            }
        } // for
    }

  // check privmgr tables
  if (isSeabasePrivMgrMD(name.getCatalogNamePartAsAnsiString(),
                         name.getSchemaNamePartAsAnsiString(TRUE)))
    { 
      // privmgr metadata tables start after system metadata tables
      size_t startingPos = sizeof(allMDtablesInfo)/sizeof(MDTableInfo);
      for (size_t i = 0; i < sizeof(privMgrTables)/sizeof(PrivMgrTableStruct); i++)
        {
          const PrivMgrTableStruct &tableDefinition = privMgrTables[i];

          MDDescsInfo &mddi = CmpCommon::context()->getTrafMDDescsInfo()[startingPos + i];
          NAString descTbl(tableDefinition.tableName);

          // Privmgr metadata tables get their definition from the new values
          // stored in the MDDescsInfo struct
          // At this time there are no indexes or views 
          if (objName == descTbl)
            {
              colInfoSize = mddi.numNewCols;
              colInfo = mddi.newColInfo;
              keyInfoSize = mddi.numNewKeys;
              keyInfo = mddi.newKeyInfo;

              indexInfoSize = mddi.numIndexes;
              indexInfo = mddi.indexInfo;

              if (mddi.tableInfo == NULL)
                {
                  const NAString catName(TRAFODION_SYSCAT_LIT);
                  const NAString schName(SEABASE_PRIVMGR_SCHEMA);
                  NAString extTableName = catName + "." + "\"" + schName + "\"" + "." + objName;

                  CmpSeabaseDDL cmpSBD(STMTHEAP);
                  if (cmpSBD.getSpecialTableInfo(CTXTHEAP,
                                                 catName, schName, objName, extTableName,
                                                 objType, tableInfo) == 0)
                    mddi.tableInfo = (ComTdbVirtTableTableInfo*)tableInfo;
                  else
                    return FALSE; // error
                }
              else
                tableInfo = mddi.tableInfo;

              return TRUE;
          }
      }
    }
  return FALSE;
}

short CmpSeabaseDDL::convertColAndKeyInfoArrays(
                                                Lng32 btNumCols, // IN
                                                ComTdbVirtTableColumnInfo* btColInfoArray, // IN
                                                Lng32 btNumKeys, // IN
                                                ComTdbVirtTableKeyInfo* btKeyInfoArray, // IN
                                                NAColumnArray *naColArray,
                                                NAColumnArray *naKeyArr)
{
  for (Lng32 i = 0; i < btNumCols; i++)
    {
      ComTdbVirtTableColumnInfo &ci = btColInfoArray[i];

      Lng32 colnum, offset;
      TrafDesc * desc = 
        TrafMakeColumnDesc(NULL, NULL, colnum, ci.datatype, ci.length,
                           offset, ci.nullable, ci.charset, NULL);
      TrafColumnsDesc *column_desc = desc->columnsDesc();
      
      column_desc->datatype = ci.datatype;
      column_desc->length = ci.length;
      column_desc->precision = ci.precision;
      column_desc->scale = ci.scale;
      column_desc->setNullable(ci.nullable);
      column_desc->character_set/*CharInfo::CharSet*/ 
        = (CharInfo::CharSet)ci.charset;
      column_desc->setUpshifted(ci.upshifted);
      column_desc->setCaseInsensitive(FALSE);
      column_desc->collation_sequence = CharInfo::DefaultCollation;
      column_desc->encoding_charset = (CharInfo::CharSet)ci.charset;

      column_desc->datetimestart = (rec_datetime_field)ci.dtStart;
      column_desc->datetimeend = (rec_datetime_field)ci.dtEnd;
      column_desc->datetimefractprec = ci.scale;

      column_desc->intervalleadingprec = ci.precision;
      column_desc->setDefaultClass(ci.defaultClass);
      column_desc->colFlags = ci.colFlags;

      NAType *type;
      NAColumn::createNAType(column_desc, NULL, type, STMTHEAP);

      NAColumn * nac = new(STMTHEAP) NAColumn(ci.colName, i, type, STMTHEAP);
      naColArray->insert(nac);

      for (Lng32 ii = 0; ii < btNumKeys; ii++)
        {
          ComTdbVirtTableKeyInfo &ki = btKeyInfoArray[ii];
          if (strcmp(ci.colName, ki.colName) == 0)
            {
              if (ki.ordering == ComTdbVirtTableKeyInfo::ASCENDING_ORDERING)
                nac->setClusteringKey(ASCENDING);
              else // ki.ordering should be 1
                nac->setClusteringKey(DESCENDING);
              naKeyArr->insert(nac);
            }
        } // for

    } // for

  return 0;
}

static short resetCQDs(NABoolean hbaseSerialization, NAString hbVal,
                       short retval)
{
  if (hbaseSerialization)
    {
      ActiveSchemaDB()->getDefaults().validateAndInsert("hbase_serialization", hbVal, FALSE);
    }

  return retval;
}

short CmpSeabaseDDL::processDDLandCreateDescs(
                                              Parser &parser,
                                              const QString *ddl,
                                              Lng32 sizeOfddl,

                                              NABoolean isIndexTable,

                                              Lng32 btNumCols, // IN
                                              ComTdbVirtTableColumnInfo* btColInfoArray, // IN
                                              Lng32 btNumKeys, // IN
                                              ComTdbVirtTableKeyInfo* btKeyInfoArray, // IN

                                              Lng32 &numCols, // OUT
                                              ComTdbVirtTableColumnInfo* &colInfoArray, // OUT
                                              Lng32 &numKeys, // OUT
                                              ComTdbVirtTableKeyInfo* &keyInfoArray, // OUT

                                              ComTdbVirtTableIndexInfo* &indexInfo) // OUT
{
  numCols = 0;
  numKeys = 0;
  colInfoArray = NULL;
  keyInfoArray = NULL;

  indexInfo = NULL;

  ExprNode * exprNode = NULL;
  const QString * qs = NULL;
  Int32 sizeOfqs = 0;
  
  qs = ddl;
  sizeOfqs = sizeOfddl; 
  
  Int32 qryArraySize = sizeOfqs / sizeof(QString);
  char * gluedQuery;
  Lng32 gluedQuerySize;
  glueQueryFragments(qryArraySize,  qs,
                     gluedQuery, gluedQuerySize);

  NABoolean hbaseSerialization = FALSE;
  NABoolean defaultColCharset = FALSE;
  NAString hbVal;
  if (CmpCommon::getDefault(HBASE_SERIALIZATION) == DF_ON)
    {
      NAString value("OFF");
      hbVal = "ON";
      ActiveSchemaDB()->getDefaults().validateAndInsert(
                                                        "hbase_serialization", value, FALSE);
      hbaseSerialization = TRUE;
    }

  exprNode = parser.parseDML((const char*)gluedQuery, strlen(gluedQuery), 
                             CharInfo::ISO88591);

  NADELETEBASICARRAY(gluedQuery, STMTHEAP);

  if (! exprNode)
    return resetCQDs(hbaseSerialization, hbVal, -1);
  
  RelExpr * rRoot = NULL;
  if (exprNode->getOperatorType() EQU STM_QUERY)
    {
      rRoot = (RelRoot*)exprNode->getChild(0);
    }
  else if (exprNode->getOperatorType() EQU REL_ROOT)
    {
      rRoot = (RelRoot*)exprNode;
    }
  
  if (! rRoot)
    return resetCQDs(hbaseSerialization, hbVal, -1);
  
  ExprNode * ddlNode = NULL;
  DDLExpr * ddlExpr = NULL;
  
  ddlExpr = (DDLExpr*)rRoot->getChild(0);
  ddlNode = ddlExpr->getDDLNode();
  if (! ddlNode)
    return resetCQDs(hbaseSerialization, hbVal, -1);

  Lng32 keyLength = 0;
  if (ddlNode->getOperatorType() == DDL_CREATE_TABLE)
    {
      StmtDDLCreateTable * createTableNode =
        ddlNode->castToStmtDDLNode()->castToStmtDDLCreateTable();
      
      ElemDDLColDefArray &colArray = createTableNode->getColDefArray();
      ElemDDLColRefArray &keyArray = createTableNode->getPrimaryKeyColRefArray();
      
      numCols = colArray.entries();
      numKeys = keyArray.entries();
      colInfoArray = new(CTXTHEAP) ComTdbVirtTableColumnInfo[numCols];

      keyInfoArray = new(CTXTHEAP) ComTdbVirtTableKeyInfo[numKeys];

      if (buildColInfoArray(COM_BASE_TABLE_OBJECT,
                            TRUE, // this is a metadata, histogram or repository object
                            &colArray, colInfoArray, FALSE, FALSE, NULL, NULL, NULL, NULL, 
                            CTXTHEAP))
        {
          return resetCQDs(hbaseSerialization, hbVal, -1);
        }

      if (buildKeyInfoArray(&colArray, NULL, &keyArray, colInfoArray, keyInfoArray, FALSE,
			    &keyLength, CTXTHEAP))
	{
	  return resetCQDs(hbaseSerialization, hbVal, -1);
	}

      // if index table defn, append "@" to the hbase col qual.
      if (isIndexTable)
        {
          for (Lng32 i = 0; i < numCols; i++)
            {
              ComTdbVirtTableColumnInfo &ci = colInfoArray[i];

              char hcq[100];
              strcpy(hcq, ci.hbaseColQual);
              
              ci.hbaseColQual = new(CTXTHEAP) char[strlen(hcq) + 1 +1];
              strcpy((char*)ci.hbaseColQual, (char*)"@");
              strcat((char*)ci.hbaseColQual, hcq);
            } // for

          for (Lng32 i = 0; i < numKeys; i++)
            {
              ComTdbVirtTableKeyInfo &ci = keyInfoArray[i];

              ci.hbaseColQual = new(CTXTHEAP) char[10];
              str_sprintf((char*)ci.hbaseColQual, "@%d", ci.keySeqNum);
            }
        } // if
    }
  else if (ddlNode->getOperatorType() == DDL_CREATE_INDEX)
    {
      StmtDDLCreateIndex * createIndexNode =
        ddlNode->castToStmtDDLNode()->castToStmtDDLCreateIndex();
      
      ComObjectName tableName(createIndexNode->getTableName());
      NAString extTableName = tableName.getExternalName(TRUE);
      
      NAString extIndexName = TRAFODION_SYSCAT_LIT;
      extIndexName += ".";
      extIndexName += "\"";
      extIndexName += SEABASE_MD_SCHEMA;
      extIndexName += "\"";
      extIndexName += ".";
      extIndexName += createIndexNode->getIndexName();
      
      ElemDDLColRefArray & indexColRefArray = createIndexNode->getColRefArray();
      
      NAColumnArray btNAColArray;
      NAColumnArray btNAKeyArr;

      if (convertColAndKeyInfoArrays(btNumCols, btColInfoArray,
                                     btNumKeys, btKeyInfoArray,
                                     &btNAColArray, &btNAKeyArr))
        return resetCQDs(hbaseSerialization, hbVal, -1);

      Lng32 keyColCount = 0;
      Lng32 nonKeyColCount = 0;
      Lng32 totalColCount = 0;
      
      Lng32 numIndexCols = 0;
      Lng32 numIndexKeys = 0;
      Lng32 numIndexNonKeys = 0;

      ComTdbVirtTableColumnInfo * indexColInfoArray = NULL;
      ComTdbVirtTableKeyInfo * indexKeyInfoArray = NULL;
      ComTdbVirtTableKeyInfo * indexNonKeyInfoArray = NULL;
      
      NAList<NAString> selColList(STMTHEAP);
      NAString defaultColFam(SEABASE_DEFAULT_COL_FAMILY);
      if (createIndexColAndKeyInfoArrays(indexColRefArray,
                                         createIndexNode->isUniqueSpecified(),
                                         FALSE, // no syskey
                                         FALSE, // not alignedFormat
                                         defaultColFam,
                                         btNAColArray, btNAKeyArr,
                                         numIndexKeys, numIndexNonKeys, numIndexCols,
                                         indexColInfoArray, indexKeyInfoArray,
                                         selColList,
                                         keyLength,
                                         CTXTHEAP))
        return resetCQDs(hbaseSerialization, hbVal, -1);

      numIndexNonKeys = numIndexCols - numIndexKeys;
      
      if (numIndexNonKeys > 0)
        {
          indexNonKeyInfoArray = 
            new(CTXTHEAP) ComTdbVirtTableKeyInfo[numIndexNonKeys];
        }

      Lng32 ink = 0;
      for (Lng32 i = numIndexKeys; i < numIndexCols; i++)
        {
          ComTdbVirtTableColumnInfo &indexCol = indexColInfoArray[i];
          
          ComTdbVirtTableKeyInfo &ki = indexNonKeyInfoArray[ink];
          ki.colName = indexCol.colName;

          NAColumn * nc = btNAColArray.getColumn(ki.colName);
          Lng32 colNumber = nc->getPosition();

          ki.tableColNum = colNumber;
          ki.keySeqNum = i+1;
          ki.ordering = ComTdbVirtTableKeyInfo::ASCENDING_ORDERING;
          ki.nonKeyCol = 1;
          
          ki.hbaseColFam = new(CTXTHEAP) char[strlen(SEABASE_DEFAULT_COL_FAMILY) + 1];
          strcpy((char*)ki.hbaseColFam, SEABASE_DEFAULT_COL_FAMILY);
          
          char qualNumStr[40];
          str_sprintf(qualNumStr, "@%d", ki.keySeqNum);
          
          ki.hbaseColQual = new(CTXTHEAP) char[strlen(qualNumStr)+1];
          strcpy((char*)ki.hbaseColQual, qualNumStr);

          ink++;
        } // for
      
      indexInfo = new(CTXTHEAP) ComTdbVirtTableIndexInfo[1];
      indexInfo->baseTableName = new(CTXTHEAP) char[extTableName.length()+ 1];
      strcpy((char*)indexInfo->baseTableName, extTableName.data());

      indexInfo->indexName = new(CTXTHEAP) char[extIndexName.length()+ 1];
      strcpy((char*)indexInfo->indexName, extIndexName.data());

      indexInfo->keytag = 1;
      indexInfo->isUnique =  createIndexNode->isUniqueSpecified() ? 1 : 0;
      indexInfo->isExplicit = 1;

      indexInfo->keyColCount = numIndexKeys;
      indexInfo->nonKeyColCount = numIndexNonKeys;
      indexInfo->keyInfoArray = indexKeyInfoArray;
      indexInfo->nonKeyInfoArray = indexNonKeyInfoArray;

      indexInfo->hbaseCreateOptions = NULL;
      indexInfo->numSaltPartns = 0;

      numCols = 0;
      colInfoArray = NULL;
      numKeys = 0;
      keyInfoArray = NULL;
    }
  else
    return resetCQDs(hbaseSerialization, hbVal, -1);

  return resetCQDs(hbaseSerialization, hbVal, 0);
}

// ----------------------------------------------------------------------------
// Method: createMDdescs
// 
// This method is called when the compiler context is instantiated to create
// a cache of system and privmgr metadata. 
// Metadata definitions are stored as an array of MDDescsInfo structs.  
//
// This method extracts hardcoded definitions of each metadata table, creates
// an MDDescsInfo struct and appends it to the list of entries. 
//
// The list of MDDescsInfo structs is organized as follows:
//    Tables in "_MD_" schema ordered by list defined in allMDtablesInfo
//    Tables in "_PRIVMGR_MGR_" schema order by list defined in PrivMgrTables 
//
// Parameters:
//  input/output:
//    trafMDDescsInfo - returns the list of MDDescsInfo structs for metadata
//      the list of structures will be allocated out of the CNTXHEAP
//    
// RETURN: -1, error.  0, all ok.
// ----------------------------------------------------------------------------
short CmpSeabaseDDL::createMDdescs(MDDescsInfo *&trafMDDescsInfo)
{
  int breadCrumb = -1;  // useful for debugging purposes

  // if structure is already allocated, just return
  // Question - will trafMDDescsInfo ever be NOT NULL?
  if (trafMDDescsInfo)
    return 0;

  size_t numMDTables = sizeof(allMDtablesInfo) / sizeof(MDTableInfo);
  size_t numPrivTables = sizeof(privMgrTables)/sizeof(PrivMgrTableStruct);

  // Allocate an array of MDDescsInfo structs to handle all system and
  // privmgr metadata tables.  Authorization may not be enabled but
  // go ahead and load privmgr metadata definitions anyway - the current
  // session may enable authorization so these entries will be available.
  trafMDDescsInfo = (MDDescsInfo*) 
    new(CTXTHEAP) char[(numMDTables + numPrivTables) * sizeof(MDDescsInfo)];

  // Initialize the SQL parser - it is called to get table details
  Parser parser(CmpCommon::context());

  // Load definitions of system metadata tables
  for (size_t i = 0; i < numMDTables; i++)
    {
      const MDTableInfo &mdti = allMDtablesInfo[i];

      const char * oldName = NULL;
      const QString * oldDDL = NULL;
      Lng32 sizeOfoldDDL = 0;
      if (getOldMDInfo(mdti, oldName, oldDDL, sizeOfoldDDL) == FALSE)
        goto label_error;

      MDDescsInfo &mddi = trafMDDescsInfo[i];
      
      if (!mdti.newDDL)
        continue;
      
      Lng32 numCols = 0;
      Lng32 numKeys = 0;

      ComTdbVirtTableColumnInfo * colInfoArray = NULL;
      ComTdbVirtTableKeyInfo * keyInfoArray = NULL;
      ComTdbVirtTableIndexInfo * indexInfo = NULL;

      breadCrumb = 1;
      if (processDDLandCreateDescs(parser,
                                   mdti.newDDL, mdti.sizeOfnewDDL,
                                   (mdti.isIndex ? TRUE : FALSE),
                                   0, NULL, 0, NULL,
                                   numCols, colInfoArray,
                                   numKeys, keyInfoArray,
                                   indexInfo))
        goto label_error;

      mddi.numNewCols = numCols;
      mddi.newColInfo = colInfoArray;
      
      mddi.numNewKeys = numKeys;
      mddi.newKeyInfo = keyInfoArray;
      
      if (oldDDL)
        {
          breadCrumb = 2;
          if (processDDLandCreateDescs(parser,
                                       oldDDL, sizeOfoldDDL,
                                       (mdti.isIndex ? TRUE : FALSE),
                                       0, NULL, 0, NULL,
                                       numCols, colInfoArray,
                                       numKeys, keyInfoArray,
                                       indexInfo))
            goto label_error;
        }
      
      mddi.numOldCols = numCols;
      mddi.oldColInfo = colInfoArray;
      
      mddi.numOldKeys = numKeys;
      mddi.oldKeyInfo = keyInfoArray;

      mddi.numIndexes = 0;
      mddi.indexInfo = NULL;
      mddi.tableInfo = NULL;

      if (mdti.indexDDL)
        {
          mddi.numIndexes = 1;
          mddi.indexInfo = NULL;

          ComTdbVirtTableIndexInfo * indexInfo = NULL;
          Lng32 numIndexCols = 0;
          Lng32 numIndexKeys = 0;
          ComTdbVirtTableColumnInfo * indexColInfoArray = NULL;
          ComTdbVirtTableKeyInfo * indexKeyInfoArray = NULL;
          
          breadCrumb = 3;
          if (processDDLandCreateDescs(parser,
                                       mdti.indexDDL, mdti.sizeOfIndexDDL,
                                       FALSE,
                                       numCols, colInfoArray,
                                       numKeys, keyInfoArray,
                                       numIndexCols, indexColInfoArray,
                                       numIndexKeys, indexKeyInfoArray,
                                       indexInfo))
            goto label_error;

          mddi.indexInfo = indexInfo;
        }
    } // for

  // Load descs for privilege metadata
  for (size_t i = 0; i < numPrivTables; i++)
    {
      const PrivMgrTableStruct &tableDefinition = privMgrTables[i];
      MDDescsInfo &mddi = trafMDDescsInfo[numMDTables + i];

      Lng32 numCols = 0;
      Lng32 numKeys = 0;

      ComTdbVirtTableColumnInfo * colInfoArray = NULL;
      ComTdbVirtTableKeyInfo * keyInfoArray = NULL;
      ComTdbVirtTableIndexInfo * indexInfo = NULL;

      // Set up create table ddl
      NAString tableDDL("CREATE TABLE ");
      NAString privMgrMDLoc;
      CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);

      tableDDL += privMgrMDLoc.data() + NAString('.') + tableDefinition.tableName; 
      tableDDL += tableDefinition.tableDDL->str;

      QString ddlString; 
      ddlString.str = tableDDL.data();

      breadCrumb = 4;
      if (processDDLandCreateDescs(parser,
                                   &ddlString, sizeof(QString),
                                   FALSE,
                                   0, NULL, 0, NULL,
                                   numCols, colInfoArray,
                                   numKeys, keyInfoArray,
                                   indexInfo))
        goto label_error;

       // Privmgr metadata is not needed to upgrade trafodion metadata so
       // it uses standard SQL to perform upgrade operations.  That means
       // this code does not have to differenciate between old and new
       // definitions.
       mddi.numNewCols = numCols;
       mddi.numOldCols = numCols;

       mddi.newColInfo = colInfoArray;
       mddi.oldColInfo = colInfoArray;

       mddi.numNewKeys = numKeys;
       mddi.numOldKeys = numKeys;

       mddi.newKeyInfo = keyInfoArray;
       mddi.oldKeyInfo = keyInfoArray;
 
       mddi.numIndexes = 0;
       mddi.indexInfo = NULL;
       mddi.tableInfo = NULL;
    }

  return 0;

 label_error:

  // When debugging, you can look at the breadCrumb variable to figure out
  // why you got here.

  if (trafMDDescsInfo)
    NADELETEBASIC(trafMDDescsInfo, CTXTHEAP);
  trafMDDescsInfo = NULL;

  char msg[80];
  str_sprintf(msg,"CmpSeabaseDDL::createMDdescs failed, breadCrumb = %d",breadCrumb);
  SQLMXLoggingArea::logSQLMXDebugEvent(msg, -1, __LINE__);

  return -1;
}
                                              
NABoolean CmpSeabaseDDL::isHbase(const NAString &catName)
{
  if ((CmpCommon::getDefault(MODE_SEABASE) == DF_ON) &&
      (NOT catName.isNull()))
    {
      NAString hbaseDefCatName = "";
      CmpCommon::getDefault(HBASE_CATALOG, hbaseDefCatName, FALSE);
      hbaseDefCatName.toUpper();
      
       if ((catName == HBASE_SYSTEM_CATALOG) ||
           (catName == hbaseDefCatName))
         return TRUE;
    }
  
  return FALSE;
}

ComBoolean CmpSeabaseDDL::isHbase(const ComObjectName &name) 
{
  return isHbase(name.getCatalogNamePartAsAnsiString());
}

bool CmpSeabaseDDL::isHistogramTable(const NAString &name) 
{

  if (name == HBASE_HIST_NAME || 
      name == HBASE_HISTINT_NAME ||
      name == HBASE_PERS_SAMP_NAME )
    return true;
    
  return false;

}

bool CmpSeabaseDDL::isSampleTable(const NAString &name)
{
  if (name(0,min((sizeof(TRAF_SAMPLE_PREFIX)-1), name.length())) == TRAF_SAMPLE_PREFIX)
    return true;

  return false;
}

NABoolean CmpSeabaseDDL::isLOBDependentNameMatch(const NAString &name)
{
  if ((name(0,min((sizeof(LOB_MD_PREFIX)-1), name.length())) == LOB_MD_PREFIX) ||
      (name(0,min((sizeof(LOB_DESC_CHUNK_PREFIX)-1), name.length()))==LOB_DESC_CHUNK_PREFIX)||
      (name(0,min((sizeof(LOB_DESC_HANDLE_PREFIX)-1), name.length()))==LOB_DESC_HANDLE_PREFIX)
      )
    return true;
  else
    return false;
}

NABoolean CmpSeabaseDDL::isSeabase(const NAString &catName)
{
  if ((CmpCommon::getDefault(MODE_SEABASE) == DF_ON) &&
      (NOT catName.isNull()))
    {
      NAString seabaseDefCatName = "";
      CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
      seabaseDefCatName.toUpper();
      
      if (catName == seabaseDefCatName)
         return TRUE;
    }
  
  return FALSE;
}

ComBoolean CmpSeabaseDDL::isSeabase(const ComObjectName &name) 
{
  return isSeabase(name.getCatalogNamePartAsAnsiString());
}

NABoolean CmpSeabaseDDL::isSeabaseMD(
                                     const NAString &catName,
                                     const NAString &schName,
                                     const NAString &objName)
{
  if ((CmpCommon::getDefault(MODE_SEABASE) == DF_ON) &&
      (NOT catName.isNull()))
    {
      NAString seabaseDefCatName = "";
      CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
      seabaseDefCatName.toUpper();
      
      if ((catName == seabaseDefCatName) &&
          (schName == SEABASE_MD_SCHEMA ))
        {
          return TRUE;
        }
    }

  return FALSE;
}

NABoolean CmpSeabaseDDL::isSeabasePrivMgrMD(
                                            const NAString &catName,
                                            const NAString &schName)
{
  if ((CmpCommon::getDefault(MODE_SEABASE) == DF_ON) &&
      (NOT catName.isNull()))
    {
      NAString seabaseDefCatName = "";
      CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
      seabaseDefCatName.toUpper();

      if ((catName == seabaseDefCatName) &&
          (schName == SEABASE_PRIVMGR_SCHEMA))
        {
          return TRUE;
        }
    }

  return FALSE;
}

NABoolean CmpSeabaseDDL::isSeabaseReservedSchema(
                                                 const NAString &catName,
                                                 const NAString &schName)
{
  if (catName.isNull())
    return FALSE;

  NAString seabaseDefCatName = "";
  CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
  seabaseDefCatName.toUpper();
  
  return ComIsTrafodionReservedSchema(seabaseDefCatName, catName, schName);
}

NABoolean CmpSeabaseDDL::isSeabaseReservedSchema(
                                                 const ComObjectName &name)
{
  const NAString &catName = name.getCatalogNamePartAsAnsiString(TRUE);
  const NAString &schName = name.getSchemaNamePartAsAnsiString(TRUE);

  return isSeabaseReservedSchema(catName, schName);
}

NABoolean CmpSeabaseDDL::isSeabaseExternalSchema(
                                  const NAString &catName,
                                  const NAString &schName)
{
  if (catName.isNull())
    return FALSE;

  NAString seabaseDefCatName = "";
  CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
  seabaseDefCatName.toUpper();

  if (catName != seabaseDefCatName)
    return FALSE;

  return ComIsTrafodionExternalSchemaName(schName);
}
 
// ----------------------------------------------------------------------------
// Method:  isUserUpdatableSeabaseMD
//
// This method returns TRUE if it is an updatable metadata table.
// For the most part metadata tables are no allowed to be updated directly.
// However, there is a subset of tables that can be updated directly.
//
// Since only a few tables are updatable, we will check the names directly
// instead of adding a table attribute.
// ----------------------------------------------------------------------------
NABoolean CmpSeabaseDDL::isUserUpdatableSeabaseMD(const NAString &catName,
                                                  const NAString &schName,
                                                  const NAString &objName)
{
  if ((CmpCommon::getDefault(MODE_SEABASE) == DF_ON) &&
      (NOT catName.isNull()))
    {
      NAString seabaseDefCatName = "";
      CmpCommon::getDefault(SEABASE_CATALOG, seabaseDefCatName, FALSE);
      seabaseDefCatName.toUpper();
      
      if ((catName == seabaseDefCatName) &&
          (schName == SEABASE_MD_SCHEMA) &&
          (objName == SEABASE_DEFAULTS))
        {
          return TRUE;
        }
    }

  return FALSE;
}

std::vector<std::string> CmpSeabaseDDL::getHistogramTables()
{
  Int32 numHistTables = sizeof(allMDHistInfo) / sizeof(MDTableInfo);
  std::vector<std::string> histTables;
  for (Int32 i = 0; i < numHistTables; i++)
  {
    const MDTableInfo &mdh = allMDHistInfo[i];
    std::string tableName(mdh.newName);
    histTables.push_back(tableName);
  }
  return histTables;
}

ExpHbaseInterface* CmpSeabaseDDL::allocEHI(const char * server, 
                                           const char * zkPort,
                                           NABoolean raiseError)
{
  ExpHbaseInterface * ehi =  NULL;

  ehi = ExpHbaseInterface::newInstance
    (heap_, server, zkPort);
    
  Lng32 retcode = ehi->init(NULL);
  if (retcode < 0)
    {
      if (raiseError) {
        *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::init()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());
      }

      deallocEHI(ehi); 
        
      return NULL;
    }
    
  return ehi;
}

ExpHbaseInterface* CmpSeabaseDDL::allocEHI(NADefaults * defs)
{
  ExpHbaseInterface * ehi =  NULL;

  NADefaults *defsL = defs;
  if (!defsL)
    defsL = &ActiveSchemaDB()->getDefaults();
  
  const char * server = defsL->getValue(HBASE_SERVER);
  const char* zkPort = defsL->getValue(HBASE_ZOOKEEPER_PORT);

  ehi = allocEHI(server, zkPort, TRUE);
    
  return ehi;
}

void CmpSeabaseDDL::deallocEHI(ExpHbaseInterface* &ehi)
{
  if (ehi)
    delete ehi;

  ehi = NULL;
}

ComBoolean CmpSeabaseDDL::isSeabaseMD(const ComObjectName &name) 
{
  return isSeabaseMD(name.getCatalogNamePartAsAnsiString(),
                   name.getSchemaNamePartAsAnsiString(TRUE),
                   name.getObjectNamePartAsAnsiString());
}

ComBoolean CmpSeabaseDDL::isSeabasePrivMgrMD(const ComObjectName &name)
{
  return isSeabasePrivMgrMD(name.getCatalogNamePartAsAnsiString(),
                            name.getSchemaNamePartAsAnsiString(TRUE));
}

void CmpSeabaseDDL::getColName(const char * colFam, const char * colQual,
                               NAString &colName)
{
  char c;

  colName.resize(0);

  colName = colFam;
  colName += ":";
  c = str_atoi(colQual, strlen(colQual));
  colName += c;
}

short CmpSeabaseDDL::readAndInitDefaultsFromSeabaseDefaultsTable
(NADefaults::Provenance overwriteIfNotYet, Int32 errOrWarn,
 NADefaults *defs)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  if (defs->seabaseDefaultsTableRead())
    return 0;

  const char * server = defs->getValue(HBASE_SERVER);
  const char * zkPort = defs->getValue(HBASE_ZOOKEEPER_PORT);

  HbaseStr hbaseDefaults;
  NAString hbaseDefaultsStr(getSystemCatalog());
  hbaseDefaultsStr += ".";
  hbaseDefaultsStr += SEABASE_MD_SCHEMA;
  hbaseDefaultsStr += ".";
  hbaseDefaultsStr += SEABASE_DEFAULTS;
  hbaseDefaults.val = (char*)hbaseDefaultsStr.data();
  hbaseDefaults.len = hbaseDefaultsStr.length();

  NAString col1NameStr(heap_);
  NAString col2NameStr(heap_);

  getColName(SEABASE_DEFAULT_COL_FAMILY, "1", col1NameStr);
  getColName(SEABASE_DEFAULT_COL_FAMILY, "2", col2NameStr);

  LIST(NAString) col1ValueList(heap_);
  LIST(NAString) col2ValueList(heap_);
  LIST(NAString) listUnused(heap_);
  HbaseStr col1TextStr;
  HbaseStr col2TextStr;
  HbaseStr colUnused;
  char *col1 = NULL;
  char *col2 = NULL;

  ExpHbaseInterface * ehi = allocEHI(server, zkPort, FALSE);
  if (! ehi)
    {
      retcode = -1398;
      goto label_return;
    }

  retcode = existsInHbase(hbaseDefaultsStr, ehi);
  if (retcode != 1) // does not exist
    {
      retcode = -1394;
      goto label_return;
    }

  col1 = (char *) heap_->allocateMemory(col1NameStr.length() + 1, FALSE);
  col2 = (char *) heap_->allocateMemory(col2NameStr.length() + 1, FALSE);
  if (col1 == NULL || col2 == NULL)
    {
      retcode = -EXE_NO_MEM_TO_EXEC;  // error -8571
      goto label_return;
    }

  memcpy(col1, col1NameStr.data(), col1NameStr.length());
  col1[col1NameStr.length()] = 0;
  col1TextStr.val = col1;
  col1TextStr.len = col1NameStr.length();

  memcpy(col2, col2NameStr.data(), col2NameStr.length());
  col2[col2NameStr.length()] = 0;
  col2TextStr.val = col2;
  col2TextStr.len = col2NameStr.length();

  colUnused.val = NULL;
  colUnused.len = 0;

  retcode = ehi->fetchAllRows(hbaseDefaults, 
                              2, // numCols
                              col1TextStr, col2TextStr, colUnused,
                              col1ValueList, col2ValueList, listUnused);
  if (retcode != HBASE_ACCESS_SUCCESS)
    {
      retcode = -1394;

      goto label_return;
    }

  retcode = 0;

  defs->setSeabaseDefaultsTableRead(TRUE);

  for (Lng32 i = 0; i < col1ValueList.entries(); i++)
    {
      NAString attrName(col1ValueList[i].data(), col1ValueList[i].length());
      NAString attrValue(col2ValueList[i].data(), col2ValueList[i].length());

      defs->validateAndInsert(attrName, attrValue, FALSE, errOrWarn, overwriteIfNotYet);
    }
 label_return:
  deallocEHI(ehi);

  if (col1)
    heap_->deallocateMemory(col1);
  if (col2)
    heap_->deallocateMemory(col2);

  return retcode;
}   

#define VERS_CV_MAJ 1
#define VERS_CV_MIN 0
#define VERS_CV_UPD 1
VERS_BIN(xx) // get rid of warning

short CmpSeabaseDDL::getSystemSoftwareVersion(Int64 &softMajVers, 
                                              Int64 &softMinVers,
                                              Int64 &softUpdVers)
{
  //  int cmaj, cmin, cupd;
  int pmaj, pmin, pupd;
  CALL_COMP_GET_PROD_VERS(xx,&pmaj,&pmin,&pupd);
  softMajVers = pmaj;
  softMinVers = pmin;
  softUpdVers = pupd;
  //  CALL_COMP_GET_COMP_VERS(xx,cmaj,cmin,cupd);
  //  printf("pvers=%d.%d.%d\n", pmaj, pmin, pupd);
  //  printf("cvers=%d.%d.%d\n", cmaj, cmin, cupd);

  return 0;
}

short CmpSeabaseDDL::validateVersions(NADefaults *defs, 
                                      ExpHbaseInterface * inEHI,
                                      Int64 * mdMajorVersion,
                                      Int64 * mdMinorVersion,
                                      Int64 * mdUpdateVersion,
                                      Int64 * sysSWMajorVersion,
                                      Int64 * sysSWMinorVersion,
                                      Int64 * sysSWUpdVersion,
                                      Int64 * mdSWMajorVersion,
                                      Int64 * mdSWMinorVersion,
                                      Int64 * mdSWUpdateVersion,
                                      Lng32 * hbaseErrNum,
                                      NAString * hbaseErrStr)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  processSystemCatalog(defs);

  Int64 sysMajorVersion = 0;
  Int64 sysMinorVersion = 0;
  Int64 sysUpdVersion = 0;

  HbaseStr hbaseVersions;

  NAString col1NameStr(heap_);
  NAString col2NameStr(heap_);
  NAString col3NameStr(heap_);

  LIST(NAString) col1ValueList(heap_);
  LIST(NAString) col2ValueList(heap_);
  LIST(NAString) col3ValueList(heap_);

  getColName(SEABASE_DEFAULT_COL_FAMILY, "1", col1NameStr);
  getColName(SEABASE_DEFAULT_COL_FAMILY, "2", col2NameStr);
  getColName(SEABASE_DEFAULT_COL_FAMILY, "3", col3NameStr);

  char * col1 = NULL;
  char * col2 = NULL;
  char * col3 = NULL;
  HbaseStr col1TextStr;
  HbaseStr col2TextStr;
  HbaseStr col3TextStr;

  NAString hbaseVersionsStr(getSystemCatalog());
  hbaseVersionsStr += ".";
  hbaseVersionsStr += SEABASE_MD_SCHEMA;
  hbaseVersionsStr += ".";
  hbaseVersionsStr += SEABASE_VERSIONS;
  hbaseVersions.val = (char*)hbaseVersionsStr.data();
  hbaseVersions.len = hbaseVersionsStr.length();

  NABoolean mdVersionFound = FALSE;
  NABoolean invalidMD = FALSE;
  ExpHbaseInterface * ehi = inEHI;
  if (! ehi)
    {
      const char * server = defs->getValue(HBASE_SERVER);
      const char * zkPort = defs->getValue(HBASE_ZOOKEEPER_PORT);
      
      ehi = allocEHI(server, zkPort, TRUE);
      if (! ehi)
        {
          // extract error info from diags area.
          if ((CmpCommon::diags()) &&
              (CmpCommon::diags()->getNumber() > 0))
            {
              ComCondition &cc = (*CmpCommon::diags())[1];
              if (cc.getSQLCODE() == -8448)
                {
                  if (hbaseErrNum)
                    *hbaseErrNum = cc.getOptionalInteger(0);
                  if (hbaseErrStr)
                    *hbaseErrStr = cc.getOptionalString(2);
                }

              CmpCommon::diags()->clear();
            }

          retcode = -1398;
          goto label_return;
        }
    }

  retcode = isMetadataInitialized(ehi);
  if (retcode < 0)
    {
      if (hbaseErrNum)
        *hbaseErrNum = retcode;

      if (hbaseErrStr)
        *hbaseErrStr = (char*)GetCliGlobals()->getJniErrorStr();

      retcode = -1398;
      goto label_return;
    }

  getSystemSoftwareVersion(sysMajorVersion, sysMinorVersion, sysUpdVersion);
  if (sysSWMajorVersion || sysSWMinorVersion || sysSWUpdVersion)
    {
      if (sysSWMajorVersion)
        *sysSWMajorVersion = sysMajorVersion;
      if (sysSWMinorVersion)
        *sysSWMinorVersion = sysMinorVersion;
      if (sysSWUpdVersion)
        *sysSWUpdVersion = sysUpdVersion;
    }

  if (retcode == 0) // not initialized
    {
      if ((sysMajorVersion != SOFTWARE_MAJOR_VERSION) ||
          (sysMinorVersion != SOFTWARE_MINOR_VERSION) ||
          (sysUpdVersion != SOFTWARE_UPDATE_VERSION))
        {
          retcode = -1397;
          goto label_return;
        }
      
      retcode = -1393;
      goto label_return;
    }

  if (retcode == 2)
    invalidMD = TRUE;

  retcode = existsInHbase(hbaseVersionsStr, ehi);
  if (retcode != 1) // does not exist
    {
      retcode = -1394;
      goto label_return;
    }

  col1 = (char *) heap_->allocateMemory(col1NameStr.length() + 1, FALSE);
  col2 = (char *) heap_->allocateMemory(col2NameStr.length() + 1, FALSE);
  col3 = (char *) heap_->allocateMemory(col3NameStr.length() + 1, FALSE);
  if (col1 == NULL || col2 == NULL || col3 == NULL)
    {
      retcode = -EXE_NO_MEM_TO_EXEC;  // error -8571
      goto label_return;
    }

  memcpy(col1, col1NameStr.data(), col1NameStr.length());
  col1[col1NameStr.length()] = 0;
  col1TextStr.val = col1;
  col1TextStr.len = col1NameStr.length();

  memcpy(col2, col2NameStr.data(), col2NameStr.length());
  col2[col2NameStr.length()] = 0;
  col2TextStr.val = col2;
  col2TextStr.len = col2NameStr.length();

  memcpy(col3, col3NameStr.data(), col3NameStr.length());
  col3[col3NameStr.length()] = 0;
  col3TextStr.val = col3;
  col3TextStr.len = col3NameStr.length();

  retcode = ehi->fetchAllRows(hbaseVersions, 
                              3, // numCols
                              col1TextStr, col2TextStr, col3TextStr,
                              col1ValueList, col2ValueList, col3ValueList);
  if (retcode != HBASE_ACCESS_SUCCESS)
    {
      if (hbaseErrNum)
        *hbaseErrNum = retcode;

      if (hbaseErrStr)
        *hbaseErrStr = (char*)GetCliGlobals()->getJniErrorStr();

      retcode = -1398;
      goto label_return;
    }
  else
    retcode = 0;

  if ((col1ValueList.entries() == 0) ||
      (col2ValueList.entries() == 0) ||
      (col3ValueList.entries() == 0))      
    {
      retcode = -1394;
      goto label_return;
    }

  for (Lng32 i = 0; i < col1ValueList.entries(); i++)
    {
      NAString versionType(col1ValueList[i].data(), col1ValueList[i].length());
      Int64 majorVersion = *(Int64*)col2ValueList[i].data();
      Int64 minorVersion = *(Int64*)col3ValueList[i].data();

      NAString temp = versionType.strip(NAString::trailing, ' ');
      if (temp == "METADATA")
        {
          Int64 updateVersion = minorVersion - (minorVersion / 10) * 10;
          if (mdMajorVersion)
            *mdMajorVersion = majorVersion;
          if (mdMinorVersion)
            *mdMinorVersion = minorVersion / 10;
          if (mdUpdateVersion)
            *mdUpdateVersion = updateVersion;

          mdVersionFound = TRUE;
          if ((majorVersion != METADATA_MAJOR_VERSION) ||
              (minorVersion/10 != METADATA_MINOR_VERSION) ||
              (updateVersion != METADATA_UPDATE_VERSION))
            {
              // version mismatch. Check if metadata is corrupt or need to be upgraded.
              if (isOldMetadataInitialized(ehi))
                {
                  retcode = -1395;
                }
              else
                {
                  retcode = -1394;
                }
              goto label_return;
            }
        }

      if (temp == "DATAFORMAT")
        {
          if ((majorVersion != DATAFORMAT_MAJOR_VERSION) ||
              (minorVersion != DATAFORMAT_MINOR_VERSION))
            {
              retcode = -1396;
              goto label_return;
            }
        }

      if (temp == "SOFTWARE")
        {
          Int64 sysMajorVersion = 0;
          Int64 sysMinorVersion = 0;
          Int64 sysUpdVersion = 0;

          getSystemSoftwareVersion(sysMajorVersion, sysMinorVersion, sysUpdVersion);
          if (sysSWMajorVersion)
            *sysSWMajorVersion = sysMajorVersion;
          if (sysSWMinorVersion)
            *sysSWMinorVersion = sysMinorVersion;
          if (sysSWUpdVersion)
            *sysSWUpdVersion = sysUpdVersion;

          if (mdSWMajorVersion)
            *mdSWMajorVersion = majorVersion;
          if (mdSWMinorVersion)
            *mdSWMinorVersion = minorVersion / 10;
          if (mdSWUpdateVersion)
            *mdSWUpdateVersion = minorVersion - (minorVersion / 10)*10;

          if ((sysMajorVersion != SOFTWARE_MAJOR_VERSION) ||
              (sysMinorVersion != SOFTWARE_MINOR_VERSION) ||
              (sysUpdVersion != SOFTWARE_UPDATE_VERSION))
            {
              retcode = -1397;
              goto label_return;
            }
        }
    }

  if ((NOT mdVersionFound) ||
      (invalidMD))
    {
      retcode = -1394;
      goto label_return;
    }
 label_return:
  if (! inEHI)
    deallocEHI(ehi);
  if (col1)
    heap_->deallocateMemory(col1);
  if (col2)
    heap_->deallocateMemory(col2);
  if (col3)
    heap_->deallocateMemory(col3);
  return retcode;
}   

#define CQD_SENT_MAX 7
short CmpSeabaseDDL::sendAllControlsAndFlags(CmpContext* prevContext,
					     Int32 cntxtType)
{
  const NAString * val =
    ActiveControlDB()->getControlSessionValue("SHOWPLAN");
  NABoolean sendCSs = TRUE;
  if ((val) && (*val == "ON"))
    {
      // we are within a showplan session.
      // Do not send the SHOWPLAN control session or it will cause problems
      // in generation of metadata plans.
      sendCSs = FALSE;
    }

  // save the current parserflags setting from this compiler and executor context
  savedCmpParserFlags_ = Get_SqlParser_Flags (0xFFFFFFFF);
  SQL_EXEC_GetParserFlagsForExSqlComp_Internal(savedCliParserFlags_);

  Int32 cliRC;
  CmpContext *cmpctxt = CmpCommon::context();

  CMPASSERT(cmpctxt->getCntlCount() >= 0 && cmpctxt->getCntlCount() <= CQD_SENT_MAX);

  ExeCliInterface cliInterface(STMTHEAP);
  cliRC = cliInterface.executeImmediate("control query shape hold;");
  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cmpctxt->getCntlCount() < CQD_SENT_MAX)
    {
      if (cmpctxt->getCntlCount() < 1)
        {
          cliRC = cliInterface.holdAndSetCQD("volatile_schema_in_use", "OFF");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 1
        }

      if (cmpctxt->getCntlCount() < 2)
        {
          cliRC = cliInterface.holdAndSetCQD("hbase_filter_preds", "OFF");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 2
        }

      if (cmpctxt->getCntlCount() < 3)
        {
          // We have to turn NJ on for meta query compilation.
          cliRC = cliInterface.holdAndSetCQD("nested_joins", "ON");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 3
        }

      if (cmpctxt->getCntlCount() < 4)
        {
          // turn off esp parallelism until optimizer fixes esp plan issue pbm.
          cliRC = cliInterface.holdAndSetCQD("attempt_esp_parallelism", "OFF");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 4
        }

      if (cmpctxt->getCntlCount() < 5)
        {
          // this cqd causes problems when internal indexes are created.
          // disable it here for ddl operations.
          // Not sure if this cqd is used anywhere or is needed.
          // Maybe we should remove it.
          cliRC = cliInterface.holdAndSetCQD("hide_indexes", "NONE");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 5
        }

      if (cmpctxt->getCntlCount() < 6)
        {
          cliRC = cliInterface.holdAndSetCQD("traf_no_dtm_xn", "OFF");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 6
        }

      if (cmpctxt->getCntlCount() < 7)  // CQD_SENT_MAX is 7
        {
          cliRC = cliInterface.holdAndSetCQD("hbase_rowset_vsbb_opt", "OFF");
          if (cliRC < 0)
            return -1;
          else
            cmpctxt->incCntlCount();  // = 7
        }
    }

  SQL_EXEC_SetParserFlagsForExSqlComp_Internal(INTERNAL_QUERY_FROM_EXEUTIL);

  Set_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);
  
  SQL_EXEC_SetParserFlagsForExSqlComp_Internal(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);

  return 0;
}

void CmpSeabaseDDL::restoreAllControlsAndFlags()
{
  Lng32 cliRC;
  ExeCliInterface cliInterface(STMTHEAP);

  cliRC = cliInterface.executeImmediate("control query shape restore;");

  if (CmpCommon::context()->getCntlCount() > 0 &&
      CmpCommon::context()->getCntlCount() <= CQD_SENT_MAX)
    {
  cliRC = cliInterface.restoreCQD("volatile_schema_in_use");

  cliRC = cliInterface.restoreCQD("hbase_filter_preds");

  cliRC = cliInterface.restoreCQD("nested_joins");

  cliRC = cliInterface.restoreCQD("hide_indexes");

  cliRC = cliInterface.restoreCQD("attempt_esp_parallelism");

  cliRC = cliInterface.restoreCQD("traf_no_dtm_xn");

  cliRC = cliInterface.restoreCQD("hbase_rowset_vsbb_opt");
    }

  // Restore parser flags settings of cmp and exe context to what they originally were
  Set_SqlParser_Flags (savedCmpParserFlags_);
  SQL_EXEC_AssignParserFlagsForExSqlComp_Internal(savedCliParserFlags_);
  
  return;
}

void CmpSeabaseDDL::processReturn(Lng32 retcode)
{
  return;
}

// Return value:
//   0: no metadata tables exist, metadata is not initialized
//   1: all metadata tables exists, metadata is initialized
//   2: some metadata tables exist, metadata is corrupted
//  -ve: error code
short CmpSeabaseDDL::isMetadataInitialized(ExpHbaseInterface * ehi)
{
  short retcode ;

  ExpHbaseInterface * ehil = ehi;
  if (ehil == NULL)
    {
      ehil = allocEHI();
      if (ehil == NULL)
        return 0;
    }

  // check to see if VERSIONS table exist. If it exist, then metadata is initialized.
  // This is a quick check.
  // We may still run into an issue where other metadata tables are missing or
  // corrupted. That will cause an error to be returned when that table is actually
  // accessed.
  HbaseStr hbaseVersions;
  NAString hbaseVersionsStr(getSystemCatalog());
  hbaseVersionsStr += ".";
  hbaseVersionsStr += SEABASE_MD_SCHEMA;
  hbaseVersionsStr += ".";
  hbaseVersionsStr += SEABASE_VERSIONS;
  hbaseVersions.val = (char*)hbaseVersionsStr.data();
  hbaseVersions.len = hbaseVersionsStr.length();
  retcode = ehi->exists(hbaseVersions);
  if (retcode == -1) // already exists
    {
      return 1; // metadata is initialized
    }
  else if (retcode != 0)
    {
      return retcode; // error accesing hbase
    }

  Lng32 numTotal = 0;
  Lng32 numExists = 0;
  retcode = 0;
  for (Int32 i = 0; 
       (((retcode == 0) || (retcode == -1)) && (i < sizeof(allMDtablesInfo)/sizeof(MDTableInfo))); i++)
    {
      const MDTableInfo &mdi = allMDtablesInfo[i];
      
      numTotal++;
      HbaseStr hbaseTables;
      NAString hbaseTablesStr(getSystemCatalog());
      hbaseTablesStr += ".";
      hbaseTablesStr += SEABASE_MD_SCHEMA;
      hbaseTablesStr += ".";
      hbaseTablesStr += mdi.newName;
      hbaseTables.val = (char*)hbaseTablesStr.data();
      hbaseTables.len = hbaseTablesStr.length();
      
      retcode = ehil->exists(hbaseTables);
      if (retcode == -1)
        numExists++;
    }
  
  if (ehi == NULL)
    deallocEHI(ehil); 

  if ((retcode != 0) && (retcode != -1))
    return retcode; // error accessing metadata

  if (numExists == 0) 
    return 0; // metadata not initialized

  if (numExists == numTotal)
    return 1; // metadata is initialized
  
  if (numExists < numTotal)
    return 2; // metadata is corrupt

  return -1;
}

NABoolean CmpSeabaseDDL::isAuthorizationEnabled()
{
  return CmpCommon::context()->isAuthorizationEnabled();
}

// ----------------------------------------------------------------------------
// method: isPrivMgrMetadataInitialized
//
// This method checks to see if the PrivMgr metadata is initialized
//
// Parameters:
//    defs - pointer to the NADefaults class
//    checkAllPrivTables
//         (The call to verify HBase table existence is expensive so for a 
//          performance enhancement, we can optionally check for only one
//          table and assume everything is good)
//       TRUE - make sure all privmgr metadata tables exist
//       FALSE - check for existence of one privmgr metadata tables
//
// returns the result of the request:
//  (return codes based as same values returned for isMetadataInitialized)
//   0: no metadata tables exist, authorization is not enabled
//   1: at least one metadata tables exists, authorization is enabled
//   2: some metadata tables exist, privmgr metadata is corrupted
//  -nnnn: an unexpected error occurred
// ----------------------------------------------------------------------------               
short CmpSeabaseDDL::isPrivMgrMetadataInitialized(NADefaults *defs,
                                                  NABoolean checkAllPrivTables)
{
  CMPASSERT(defs != NULL);

  // We could call the PrivMgr "isAuthorizationEnabled" method but this causes
  // a CLI request to be executed during startup which causes another compiler 
  // process/context to be started which then causes another compiler instance
  // to be started - ad infinitem. So for now Hbase is called directly
   
  // This code verifies that at least one the PrivMgr metadata table exist in 
  // HBase but it does not verify that the tables are defined correctly. A 
  // subsequent call to access a PrivMgr metadata table returns an error if the 
  // Trafodion metadata is corrupted.
  const char * server = defs->getValue(HBASE_SERVER);
  const char * zkPort = defs->getValue(HBASE_ZOOKEEPER_PORT);

  ExpHbaseInterface * ehi = allocEHI(server, zkPort, FALSE);
  if (! ehi)
    {
      // This code is not expected to be called, perhaps a core dump should be
      // generated?
      CmpCommon::diags()->clear();
      deallocEHI(ehi);
      return -1398;
    }

  // Call existsInHbase to check for privmgr metadata tables existence
  NAString hbaseObjPrefix = getSystemCatalog();
  hbaseObjPrefix += ".";
  hbaseObjPrefix += SEABASE_PRIVMGR_SCHEMA;
  hbaseObjPrefix += ".";

  HbaseStr hbaseObjStr;
  NAString hbaseObject;

  int numTablesFound = 0;
  short retcode = 0;
  
  size_t numTables = (checkAllPrivTables) ? 
    sizeof(privMgrTables)/sizeof(PrivMgrTableStruct) : 1;

  for (int ndx_tl = 0; ndx_tl < numTables; ndx_tl++)
    {
      const PrivMgrTableStruct &tableDef = privMgrTables[ndx_tl];

      hbaseObject = hbaseObjPrefix + tableDef.tableName;
      hbaseObjStr.val = (char*)hbaseObject.data();
      hbaseObjStr.len = hbaseObject.length();

      // existsInHbase returns 1 - found, 0 not found, anything else error
      retcode = existsInHbase(hbaseObject, ehi);
      if (retcode == 1) // found the table
         numTablesFound ++;

      // If an unexpected error occurs, just return the error
      if (retcode < 0)
        {
           deallocEHI(ehi);
           return retcode;
        }
    }
  deallocEHI(ehi);

  if (numTablesFound == 0)
    retcode = 0;
  else if (numTablesFound == numTables)
    retcode = 1;
  else
    retcode = 2;

  return retcode;
}

short CmpSeabaseDDL::existsInHbase(const NAString &objName,
                                   ExpHbaseInterface * ehi)
{
  ExpHbaseInterface * ehil = ehi;
  if (! ehi)
    {
      ehil = allocEHI();
      if (ehil == NULL)
        return -1;
    }

  HbaseStr hbaseObj;
  hbaseObj.val = (char*)objName.data();
  hbaseObj.len = objName.length();
  Lng32 retcode = ehil->exists(hbaseObj);

  if (! ehi)
    {
      deallocEHI(ehil); 
    }

  if (retcode == -1) // already exists
    return 1;
  
  if (retcode == 0)
    return 0; // does not exist

  return retcode; // error
}

// ----------------------------------------------------------------------------
// Method:  processSystemCatalog
//
// This method sets up system catalog name in the CmpSeabaseDDL class
// 
// The system define called SEABASE_CATALOG can be used to overwrite the 
// default name of TRAFODION.
// ----------------------------------------------------------------------------
void CmpSeabaseDDL::processSystemCatalog(NADefaults *defs)
{
  NAString value(TRAFODION_SYSCAT_LIT);

  if (defs)
    defs->validateAndInsert("SEABASE_CATALOG", value, FALSE);
  else
    ActiveSchemaDB()->getDefaults().validateAndInsert(
                                                      "SEABASE_CATALOG", value, FALSE);

  seabaseSysCat_ = value;
  CONCAT_CATSCH(seabaseMDSchema_,seabaseSysCat_,SEABASE_MD_SCHEMA);
  
}

const char * CmpSeabaseDDL::getSystemCatalog()
{
  return seabaseSysCat_.data();
}

NAString CmpSeabaseDDL::getSystemCatalogStatic()
{
  NAString value(TRAFODION_SYSCAT_LIT);

  if (CmpCommon::context() && ActiveSchemaDB())
    {
      const char* sysCat = ActiveSchemaDB()->getDefaults().getValue(SEABASE_CATALOG);

      value = sysCat;
    }

  return value;
}

NABoolean CmpSeabaseDDL::xnInProgress(ExeCliInterface *cliInterface)
{
  if (cliInterface->statusXn() == 0) // xn in progress
    return TRUE;
  else
    return FALSE;
}

short CmpSeabaseDDL::beginXn(ExeCliInterface *cliInterface)
{
  Lng32 cliRC = 0;

  cliRC = cliInterface->beginWork();
  return cliRC;
}

short CmpSeabaseDDL::commitXn(ExeCliInterface *cliInterface)
{
  Lng32 cliRC = 0;

  cliRC = cliInterface->commitWork();
  return cliRC;
}

short CmpSeabaseDDL::rollbackXn(ExeCliInterface *cliInterface)
{
  Lng32 cliRC = 0;

  cliRC = cliInterface->rollbackWork();
  return cliRC;
}

short CmpSeabaseDDL::autoCommit(ExeCliInterface *cliInterface, NABoolean v)
{
  Lng32 cliRC = 0;

  cliRC = cliInterface->autoCommit(v);
  return cliRC;
}

short CmpSeabaseDDL::beginXnIfNotInProgress(ExeCliInterface *cliInterface, 
                                            NABoolean &xnWasStartedHere)
{
  Int32 cliRC = 0;

  xnWasStartedHere = FALSE;
  if (NOT xnInProgress(cliInterface))
    {
      cliRC = cliInterface->beginXn();
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
      
      CmpContext* cmpContext = CmpCommon::context();
      cmpContext->ddlObjsList().clear();

      xnWasStartedHere = TRUE;
    }

  return 0;
}

short CmpSeabaseDDL::endXnIfStartedHere(ExeCliInterface *cliInterface, 
                                        NABoolean &xnWasStartedHere, Int32 cliRC)
{
  if (xnWasStartedHere)
    {
      xnWasStartedHere = FALSE;

      if (NOT xnInProgress(cliInterface))
        return cliRC;

      if (cliRC < 0)
        {
          // rollback transaction and return original error cliRC.
          // Ignore rollback errors.
          cliInterface->rollbackXn();

          return cliRC;
        }
      else
        {
          cliRC = cliInterface->commitXn();
          if (cliRC < 0)
            {
              cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
              return cliRC;
            }

          ddlInvalidateNATables();
        }

      CmpContext* cmpContext = CmpCommon::context();
      cmpContext->ddlObjsList().clear();
    }

  return cliRC;
}

// Invalidate NATables for ddl objects that were affected in
// this transaction.
// DDL objects have already been set in ddlObjsList.
short CmpSeabaseDDL::ddlInvalidateNATables()
{
  CmpContext* cmpContext = CmpCommon::context();
  for (Lng32 i = 0; i < cmpContext->ddlObjsList().entries(); i++)
    {
      CmpContext::DDLObjInfo &ddlObj = cmpContext->ddlObjsList()[i];
      NAString &ddlObjName = ddlObj.ddlObjName;
      ComQiScope &qiScope = ddlObj.qiScope;
      ComObjectType &ot = ddlObj.ot;
      Int64 objUID = ddlObj.objUID;
      ComObjectName tableName(ddlObjName);
      
      const NAString catalogNamePart = 
        tableName.getCatalogNamePartAsAnsiString();
      const NAString schemaNamePart =
        tableName.getSchemaNamePartAsAnsiString(TRUE);
      const NAString objectNamePart = 
        tableName.getObjectNamePartAsAnsiString(TRUE);
      
      CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart);

      if (ot == COM_USER_DEFINED_ROUTINE_OBJECT)
        ActiveSchemaDB()->getNARoutineDB()->removeNARoutine(
             cn.getQualifiedNameObj(), 
             qiScope, objUID, TRUE, TRUE);
      else
        ActiveSchemaDB()->getNATableDB()->removeNATable(cn, qiScope, ot, TRUE, TRUE);
    }

  return 0;
}

short CmpSeabaseDDL::populateKeyInfo(ComTdbVirtTableKeyInfo &keyInfo,
                                     OutputInfo * oi, NABoolean isIndex)
{

  // get the column name
  Lng32 len = strlen(oi->get(0));
  keyInfo.colName = new(STMTHEAP) char[len + 1];

  strcpy((char*)keyInfo.colName, (char*)oi->get(0));

  keyInfo.tableColNum = *(Lng32*)oi->get(1);

  keyInfo.keySeqNum = *(Lng32*)oi->get(2);

  keyInfo.ordering = *(Lng32*)oi->get(3);
  
  keyInfo.nonKeyCol = *(Lng32*)oi->get(4);

  if (isIndex)
    {
      keyInfo.hbaseColFam = new(STMTHEAP) char[strlen(SEABASE_DEFAULT_COL_FAMILY) + 1];
      strcpy((char*)keyInfo.hbaseColFam, SEABASE_DEFAULT_COL_FAMILY);
      
      char qualNumStr[40];
      str_sprintf(qualNumStr, "@%d", keyInfo.keySeqNum);
      
      keyInfo.hbaseColQual = new(STMTHEAP) char[strlen(qualNumStr)+1];
      strcpy((char*)keyInfo.hbaseColQual, qualNumStr);
    }
  else
    {
      keyInfo.hbaseColFam = NULL;
      keyInfo.hbaseColQual = NULL;
    }

  return 0;
}

NABoolean CmpSeabaseDDL::enabledForSerialization(NAColumn * nac)
{
  const NAType *givenType = nac->getType();
  if ((nac) &&
      ((NOT givenType->isEncodingNeeded()) ||
       (nac && CmpSeabaseDDL::isSerialized(nac->getHbaseColFlags()))))
    {
      return TRUE;
    }

  return FALSE;
}

// NAColumn in memory is expected to have the correct HbaseColFlags for
// serialization depending on if it belongs to index or table. 
// Index and Table row format can be different now. However, it is
// recommended that the function is called only when it is not aligned
// row format. The existing callers are verified to be working correctly
// even though some callers don't adhere to this recommendation

NABoolean CmpSeabaseDDL::isEncodingNeededForSerialization(NAColumn * nac)
{
  const NAType *givenType = nac->getType();
  if ((nac) &&
      (CmpSeabaseDDL::isSerialized(nac->getHbaseColFlags())) &&
      ((givenType->isEncodingNeeded()) &&
       (NOT DFS2REC::isAnyVarChar(givenType->getFSDatatype()))))
    {
      return TRUE;
    }

  return FALSE;
}

// removing leading and trailing blank pad characters and
// converting characters to upper case is done earlier.
static NABoolean isTrueFalseStr(const NAText& str) 
{
  if (str == "TRUE" || str == "FALSE")
    return TRUE;
  return FALSE;
}
static NABoolean isHBaseCompressionOption(const NAText& str)
{
  if (str == "NONE" || str == "GZ" || str == "LZO" || 
      str == "LZ4" || str == "SNAPPY")
    return TRUE;
  return FALSE;
}
static NABoolean isHBaseDurabilityOption(const NAText& str)
{
  if (str == "ASYNC_WAL" || str == "FSYNC_WAL" || str == "SKIP_WAL" || 
      str == "SYNC" || str == "USE_DEFAULT")
    return TRUE;
  return FALSE;
}
static NABoolean isHBaseEncodingOption(const NAText& str)
{
  if (str == "NONE" || str == "PREFIX" || str == "PREFIX_TREE" || 
      str == "DIFF" || str == "FAST_DIFF")
    return TRUE;
  return FALSE;
}
static NABoolean isHBaseBloomFilterOption(const NAText& str)
{
  if (str == "NONE" || str == "ROW" || str == "ROWCOL")
    return TRUE;
  return FALSE;
}

// note: this function expects hbaseCreateOptionsArray to have
// HBASE_MAX_OPTIONS elements
short CmpSeabaseDDL::generateHbaseOptionsArray(
  NAText * hbaseCreateOptionsArray,
  NAList<HbaseCreateOption*> * hbaseCreateOptions)
{
  if (! hbaseCreateOptions)
    return 0;

  for (CollIndex i = 0; i < hbaseCreateOptions->entries(); i++)
    {
      HbaseCreateOption * hbaseOption = (*hbaseCreateOptions)[i];
      NAText &s = hbaseOption->val();
      NAText valInOrigCase;

      // trim leading and trailing spaces
      size_t startpos = s.find_first_not_of(" ");
      if (startpos != string::npos) // found a non-space character
        {
          size_t endpos = s.find_last_not_of(" ");
          s = s.substr( startpos, endpos-startpos+1 );
        }
          
      // upcase value, save original (now trimmed).
      valInOrigCase = s;

      // Do not upcase column family name as fam name is case sensitive
      if (hbaseOption->key() != "NAME")
        std::transform(s.begin(), s.end(), s.begin(), ::toupper);

      NABoolean isError = FALSE;
      if (hbaseOption->key() == "NAME")
        {
	  if (!hbaseCreateOptionsArray[HBASE_NAME].empty())
	    isError = TRUE;
          hbaseCreateOptionsArray[HBASE_NAME] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "MAX_VERSIONS")
        {
          if ((str_atoi(hbaseOption->val().data(), 
                       hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_MAX_VERSIONS].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_MAX_VERSIONS] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "MIN_VERSIONS")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_MIN_VERSIONS].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_MIN_VERSIONS] = hbaseOption->val();
        }
      else if ((hbaseOption->key() == "TIME_TO_LIVE") ||
               (hbaseOption->key() == "TTL"))
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_TTL].empty()))
	    isError = TRUE;
          hbaseCreateOptionsArray[HBASE_TTL] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "BLOCKCACHE")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_BLOCKCACHE].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_BLOCKCACHE] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "IN_MEMORY")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_IN_MEMORY].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_IN_MEMORY] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "COMPRESSION") 
        {
	  if ((!isHBaseCompressionOption(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_COMPRESSION].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_COMPRESSION] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "BLOOMFILTER")
        {
	  if ((!isHBaseBloomFilterOption(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_BLOOMFILTER].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_BLOOMFILTER] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "BLOCKSIZE")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_BLOCKSIZE].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_BLOCKSIZE] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "DATA_BLOCK_ENCODING")
        {
	  if ((!isHBaseEncodingOption(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_DATA_BLOCK_ENCODING].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_DATA_BLOCK_ENCODING] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "CACHE_BLOOMS_ON_WRITE")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_CACHE_BLOOMS_ON_WRITE].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_CACHE_BLOOMS_ON_WRITE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "CACHE_DATA_ON_WRITE")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_CACHE_DATA_ON_WRITE].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_CACHE_DATA_ON_WRITE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "CACHE_INDEXES_ON_WRITE")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_CACHE_INDEXES_ON_WRITE].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_CACHE_INDEXES_ON_WRITE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "COMPACT_COMPRESSION")
        {
	  if ((!isHBaseCompressionOption(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_COMPACT_COMPRESSION].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_COMPACT_COMPRESSION] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "PREFIX_LENGTH_KEY")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_PREFIX_LENGTH_KEY].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_PREFIX_LENGTH_KEY] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "EVICT_BLOCKS_ON_CLOSE")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_EVICT_BLOCKS_ON_CLOSE].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_EVICT_BLOCKS_ON_CLOSE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "KEEP_DELETED_CELLS")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_KEEP_DELETED_CELLS].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_KEEP_DELETED_CELLS] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "REPLICATION_SCOPE")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_REPLICATION_SCOPE].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_REPLICATION_SCOPE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "MAX_FILESIZE")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_MAX_FILESIZE].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_MAX_FILESIZE] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "COMPACT")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_COMPACT].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_COMPACT] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "DURABILITY")
        {
	  if ((!isHBaseDurabilityOption(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_DURABILITY].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_DURABILITY] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "MEMSTORE_FLUSH_SIZE")
        {
          if ((str_atoi(hbaseOption->val().data(), 
			hbaseOption->val().length()) == -1) ||
	      (!hbaseCreateOptionsArray[HBASE_MEMSTORE_FLUSH_SIZE].empty()))
            isError = TRUE;
          hbaseCreateOptionsArray[HBASE_MEMSTORE_FLUSH_SIZE] = 
            hbaseOption->val();
        }
      else if (hbaseOption->key() == "CACHE_DATA_IN_L1")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_CACHE_DATA_IN_L1].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_CACHE_DATA_IN_L1] = hbaseOption->val();
        }
      else if (hbaseOption->key() == "PREFETCH_BLOCKS_ON_OPEN")
        {
	  if ((!isTrueFalseStr(hbaseOption->val())) ||
	      (!hbaseCreateOptionsArray[HBASE_PREFETCH_BLOCKS_ON_OPEN].empty()))
	    isError = TRUE ;
          hbaseCreateOptionsArray[HBASE_PREFETCH_BLOCKS_ON_OPEN] = 
	    hbaseOption->val();
        }
      else if (hbaseOption->key() == "SPLIT_POLICY")
        {
          // for now, restrict the split policies to some well-known
          // values, because specifying an invalid class gets us into
          // a hang situation in the region server
          if ((valInOrigCase == "org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy" ||
	       valInOrigCase == "org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy"
 ||
	       valInOrigCase == "org.apache.hadoop.hbase.regionserver.KeyPrefixRegionSplitPolicy") &&  (hbaseCreateOptionsArray[HBASE_SPLIT_POLICY].empty()))
            hbaseCreateOptionsArray[HBASE_SPLIT_POLICY] = valInOrigCase;
          else
	      isError = TRUE;
        }
      else
        isError = TRUE;

      if (isError)
        {
          *CmpCommon::diags() << DgSqlCode(-8449)
			      << DgString0(hbaseOption->key().data())
			      << DgString1(valInOrigCase.data());
	  
          return -1;
        }
    } // for

  return 0;
}

short CmpSeabaseDDL::createHbaseTable(ExpHbaseInterface *ehi, 
                                      HbaseStr *table,
                                      std::vector<NAString> &colFamVec,
                                      NAList<HbaseCreateOption*> * hbaseCreateOptions,
                                      const int numSplits,
                                      const int keyLength,
                                      char** encodedKeysBuffer,
                                      NABoolean doRetry,
                                      NABoolean ddlXns)
{
  // this method is called after validating that the table doesn't exist in seabase
  // metadata. It creates the corresponding hbase table.
  short retcode = 0;

  HBASE_NAMELIST colFamList(STMTHEAP);
  HbaseStr colFam;

  retcode = -1;
  Lng32 numTries = 0;
  Lng32 delaySecs = 500; // 5 secs to start with
  if (doRetry)
    {
      while ((numTries < 24) && (retcode == -1)) // max 2 min
        {
          retcode = ehi->exists(*table);
          if (retcode == -1)
            {
              // if this state is reached, it indicates that the table was not found in metadata
              // but exists in hbase. This may be due to that table being dropped from another
              // process or thread in an asynchronous manner.
              // Delay and check again.
              numTries++;
              
              DELAY(delaySecs); 
            }
        } // while
    }
  else
    retcode = ehi->exists(*table);
    
  if (retcode == -1)
    {
      *CmpCommon::diags() << DgSqlCode(-1431)
                          << DgString0(table->val);
      return -1;
    } 
  
  if (retcode < 0)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::exists()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());
      
      return -1;
    }

  NAText hbaseCreateOptionsArray[HBASE_MAX_OPTIONS];
  if (generateHbaseOptionsArray(hbaseCreateOptionsArray,
                                hbaseCreateOptions) < 0)
    {
      // diags already set             
      return -1;
    }

  if (NOT hbaseCreateOptionsArray[HBASE_NAME].empty())
    {
      short retcode = -HBASE_CREATE_OPTIONS_ERROR;
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"CmpSeabaseDDL::generateHbaseOptionsArray()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)"NAME");
      
      return -1;
    }

  NABoolean isMVCC = true;
  if (CmpCommon::getDefault(TRAF_TRANS_TYPE) == DF_SSCC)
    isMVCC = false;

  NAString colFamNames;
  for (int i = 0; i < colFamVec.size(); i++)
    {
      colFamNames += colFamVec[i];
      colFamNames += " ";
    }

  hbaseCreateOptionsArray[HBASE_NAME] = colFamNames.data();

  // TEMPTEMP 
  //  Currently DTM crashes if number of column families goes beyond 5.
  //  Do not use ddl xns if number of explicitly specified column fams
  //  exceed 5. This is not a common case as recommendation from HBase
  //  for good performance is to keep num of col fams small (3 or 4).
  //  Once dtm bug is fixed, this check will be removed.
  if (colFamVec.size() > 5)
    ddlXns = FALSE;
  retcode = ehi->create(*table, hbaseCreateOptionsArray,
                        numSplits, keyLength,
                        (const char **)encodedKeysBuffer,
                        (NOT ddlXns),
                        isMVCC);

  if (retcode < 0)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::create()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());
      
      return -1;
    }
  
  return 0;
}

short CmpSeabaseDDL::createHbaseTable(ExpHbaseInterface *ehi, 
                                      HbaseStr *table,
                                      const char * cf1, 
                                      NAList<HbaseCreateOption*> * inHbaseCreateOptions,
                                      const int numSplits,
                                      const int keyLength,
                                      char** encodedKeysBuffer,
                                      NABoolean doRetry, 
                                      NABoolean ddlXns)
{
  if (! cf1)
    return -1;

  std::vector<NAString> colFamVec;
  colFamVec.push_back(cf1);

  NAList<HbaseCreateOption*> lHbaseCreateOptions(STMTHEAP);
  NAText lHbaseCreateOptionsArray[HBASE_MAX_OPTIONS];

  NAList<HbaseCreateOption*> * hbaseCreateOptions = inHbaseCreateOptions;
  if (! inHbaseCreateOptions)
    hbaseCreateOptions = &lHbaseCreateOptions;

  return createHbaseTable(ehi, table, colFamVec, hbaseCreateOptions,
                          numSplits, keyLength,
                          encodedKeysBuffer, doRetry, ddlXns);
}

short CmpSeabaseDDL::alterHbaseTable(ExpHbaseInterface *ehi,
                                     HbaseStr *table,
                                     NAList<NAString> &allColFams,
                                     NAList<HbaseCreateOption*> * hbaseCreateOptions,
                                     NABoolean ddlXns)
{
  short retcode = 0;
  NAText hbaseCreateOptionsArray[HBASE_MAX_OPTIONS];

  if (generateHbaseOptionsArray(hbaseCreateOptionsArray,
                                hbaseCreateOptions))
    {
      // diags already set             
      retcode = -1;
    } 
  else  
    {
      NABoolean noXn = (NOT ddlXns);
         
      retcode = 0;

      // if col family name passed in, change attrs for that family.
      // Otherwise change it for all user specified families.
      if (hbaseCreateOptionsArray[HBASE_NAME].empty())
        {
          for (int i = 0; ((retcode != -1) && (i < allColFams.entries())); i++)
            {
              NAString colFam = allColFams[i];
              
              hbaseCreateOptionsArray[HBASE_NAME] = colFam;
              retcode = ehi->alter(*table, hbaseCreateOptionsArray, noXn);
            } // for
        } // if
      else
        {
          retcode = ehi->alter(*table, hbaseCreateOptionsArray, noXn);
        }

      if (retcode < 0)
        {
          *CmpCommon::diags() << DgSqlCode(-8448)
                              << DgString0((char*)"ExpHbaseInterface::alter()")
                              << DgString1(getHbaseErrStr(-retcode))
                              << DgInt0(-retcode)
                              << DgString2((char*)GetCliGlobals()->getJniErrorStr());
          retcode = -1;
        } // if
    } // else

  return retcode;
}

short CmpSeabaseDDL::dropHbaseTable(ExpHbaseInterface *ehi, 
                                    HbaseStr *table, NABoolean asyncDrop,
                                    NABoolean ddlXns)
{
  short retcode = 0;

  retcode = ehi->exists(*table);
  if (retcode == -1) // exists
    {    
      if ((CmpCommon::getDefault(HBASE_ASYNC_DROP_TABLE) == DF_ON) ||
          (asyncDrop))
        retcode = ehi->drop(*table, TRUE, (NOT ddlXns));
      else
        retcode = ehi->drop(*table, FALSE, (NOT ddlXns));
      if (retcode < 0)
        {
          *CmpCommon::diags() << DgSqlCode(-8448)
                              << DgString0((char*)"ExpHbaseInterface::drop()")
                              << DgString1(getHbaseErrStr(-retcode))
                              << DgInt0(-retcode)
                              << DgString2((char*)GetCliGlobals()->getJniErrorStr());
          
          return -1;
        }
    }

  if (retcode != 0)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::exists()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());
      
      return -1;
    }
  
  return 0;
}

short CmpSeabaseDDL::copyHbaseTable(ExpHbaseInterface *ehi, 
                                    HbaseStr *currTable, HbaseStr* oldTable)
{
  short retcode = 0;

  retcode = ehi->exists(*currTable);
  if (retcode == -1) // exists
    {       
      retcode = ehi->copy(*currTable, *oldTable);
      if (retcode < 0)
        {
          *CmpCommon::diags() << DgSqlCode(-8448)
                              << DgString0((char*)"ExpHbaseInterface::copy()")
                              << DgString1(getHbaseErrStr(-retcode))
                              << DgInt0(-retcode)
                              << DgString2((char*)GetCliGlobals()->getJniErrorStr());
          
          return -1;
        }
    }

  if (retcode != 0)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::copy()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());
      
      return -1;
    }
  
  return 0;
}

short CmpSeabaseDDL::checkDefaultValue(
                                       const NAString & colExtName,
                                       const NAType   * colType,
                                       ElemDDLColDef   * colNode)
{
  short rc = 0;

  ItemExpr * defExpr = colNode->getDefaultValueExpr();
  ConstValue *cvDefault = (ConstValue *)colNode->getDefaultValueExpr();

  NAType * newType = (NAType *)colType;
  if ((colType->getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (cvDefault->getType()->getTypeQualifier() == NA_CHARACTER_TYPE))
    {
      if (colType->getNominalSize() > cvDefault->getType()->getNominalSize())
        {
          newType = colType->newCopy(STMTHEAP);
          newType->setNominalSize(
                                  MAXOF(cvDefault->getType()->getNominalSize(), 1));
        }
      else if (colType->getNominalSize() < cvDefault->getType()->getNominalSize())
        {
          defExpr = new(STMTHEAP) Cast(defExpr, colType);
          ((Cast*)defExpr)->setCheckTruncationError(TRUE);
        }
    }

  NAString castToTypeStr(newType->getTypeSQLname(TRUE));

  char buf[1000];
  str_sprintf(buf, "CAST(@A1 AS %s)", castToTypeStr.data());

  rc = Generator::genAndEvalExpr(CmpCommon::context(),
                                 buf, 1, defExpr, NULL,
                                 CmpCommon::diags());

  if (rc)
    {
      *CmpCommon::diags() 
        << DgSqlCode(-CAT_INCOMPATIBLE_DATA_TYPE_IN_DEFAULT_CLAUSE)
        << DgColumnName(colExtName)
        << DgString0(castToTypeStr.data())
        << DgString1(cvDefault->getConstStr());
    }

  return rc;
}

short CmpSeabaseDDL::getTypeInfo(const NAType * naType,
                                 NABoolean alignedFormat,
				 Lng32 serializedOption,
				 Lng32 &datatype,
				 Lng32 &length,
				 Lng32 &precision,
				 Lng32 &scale,
				 Lng32 &dtStart,
				 Lng32 &dtEnd,
				 Lng32 &upshifted,
				 Lng32 &nullable,
				 NAString &charset,
				 CharInfo::Collation &collationSequence,
				 ULng32 &hbaseColFlags)
{
  short rc = 0;

  datatype = 0;
  length = 0;
  precision = 0;
  scale = 0;
  dtStart = 0;
  dtEnd = 0;
  nullable = 0;
  upshifted = 0;

  charset = SQLCHARSETSTRING_UNKNOWN;
  collationSequence = CharInfo::DefaultCollation;

  datatype = (Lng32)naType->getFSDatatype();
  length = naType->getNominalSize();
  nullable = naType->supportsSQLnull();

  switch (naType->getTypeQualifier())
    {
    case NA_CHARACTER_TYPE:
      {
        CharType *charType = (CharType *)naType;
        
        scale = 0;

        precision = charType->getPrecisionOrMaxNumChars();
        charset = CharInfo::getCharSetName(charType->getCharSet());
        upshifted = (charType->isUpshifted() ? -1 : 0);

        collationSequence = charType->getCollation();
        if (serializedOption == 1) // option explicitly specified
          {
            setFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
          }
        else if ((serializedOption == -1) && // not specified
                 (CmpCommon::getDefault(HBASE_SERIALIZATION) == DF_ON) &&
                 (NOT alignedFormat))
          {
            setFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
          }
       }
      break;
      
    case NA_NUMERIC_TYPE:
      {
        NumericType *numericType = (NumericType *)naType;
        scale = numericType->getScale();
        
        if (datatype == REC_BPINT_UNSIGNED)
          precision = numericType->getPrecision();
        else if (numericType->binaryPrecision())
          precision = 0;
        else
          precision = numericType->getPrecision();

        if (serializedOption == 1) // option explicitly specified
          {
            if (DFS2REC::isBinary(datatype))
              setFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
            else if (numericType->isEncodingNeeded())
              {
                *CmpCommon::diags() << DgSqlCode(-1191)
                                    << DgString0(numericType->getSimpleTypeName());
                return -1;
              }
          }
        else if ((serializedOption == -1) && // not specified
                 (CmpCommon::getDefault(HBASE_SERIALIZATION) == DF_ON) &&
                 (DFS2REC::isBinary(datatype)) &&
                 (NOT alignedFormat))
          {
            setFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
          }
      }
      break;
      
    case NA_DATETIME_TYPE:
    case NA_INTERVAL_TYPE:
      {
        DatetimeIntervalCommonType *dtiCommonType = 
          (DatetimeIntervalCommonType *)naType;
        
        scale = dtiCommonType->getFractionPrecision();
        precision = dtiCommonType->getLeadingPrecision();
        
        dtStart = dtiCommonType->getStartField();
        dtEnd = dtiCommonType->getEndField();

        if ((serializedOption == 1) &&
            (dtiCommonType->isEncodingNeeded()))
          {
            *CmpCommon::diags() << DgSqlCode(-1191)
                                << DgString0(dtiCommonType->getSimpleTypeName());

            return -1;
          }
      }
      break;
      
     case NA_LOB_TYPE:
      {
	if (datatype == REC_BLOB)
	  {
	    SQLBlob *blobType = (SQLBlob *) naType;
	    
	    precision = (ComSInt32)blobType->getLobLength();
	  }
	else
	  {
	    SQLClob *clobType = (SQLClob *)naType;
	    
	    precision = (ComSInt32)clobType->getLobLength();
	  }
	
      }
      break;
  
    case NA_BOOLEAN_TYPE:
      {
        precision = 0;
      }
      break;
      

    default:
      {
        *CmpCommon::diags() << DgSqlCode(-CAT_INVALID_COLUMN_DATATYPE);
        
        return -1; 
      }

    } // switch

  if ((serializedOption == 1) && (alignedFormat))
    {
      // ignore serialized option on aligned format tables
      resetFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
      
      /*
       *CmpCommon::diags()
       << DgSqlCode(-4222)
       << DgString0("\"SERIALIZED option on ALIGNED format tables\"");
       
       return -1;
      */
    }

  return 0;
}

short CmpSeabaseDDL::getNAColumnFromColDef
(ElemDDLColDef * colNode,
 NAColumn* &naCol)
{
  NAString colFamily;
  NAString colName;
  Lng32 datatype, length, precision, scale, dt_start, dt_end;
  Lng32 nullable, upshifted;
  ComColumnClass colClass;
  ComColumnDefaultClass defaultClass;
  NAString charset, defVal;
  NAString heading;
  ULng32 hbaseColFlags;
  Int64 colFlags;
  LobsStorage lobStorage;
  NABoolean alignedFormat = FALSE;
  if (getColInfo(colNode,
                 FALSE,
                 colFamily,
                 colName,
                 alignedFormat,
                 datatype, length, precision, scale, dt_start, dt_end, 
                 upshifted, nullable,
                 charset, colClass, defaultClass, defVal, heading, lobStorage, 
                 hbaseColFlags, colFlags))
    {
     *CmpCommon::diags() << DgSqlCode(-2004);
     return -1;
    }

  NAType * naType = colNode->getColumnDataType();
  if (! naType)
    {
      *CmpCommon::diags() << DgSqlCode(-2004);
      return -1;
    }

  char * defV = NULL;
  if ((defaultClass != COM_NO_DEFAULT) &&
      (! defVal.isNull()))
    {
      char * data = (char*) defVal.data();
      Lng32 len = defVal.length();
      defV = new(STMTHEAP) char[len + 2];
      str_cpy_all((char*)defV, data, len);
      char * c = (char*)defV;
      c[len] = 0;
      c[len+1] = 0;
    }

  naCol = new(STMTHEAP) NAColumn(colNode->getColumnName().data(),
                                 -1, // position
                                 naType, NULL, NULL,
                                 USER_COLUMN, //colClass, 
                                 defaultClass,
                                 defV);

  naCol->setHbaseColFlags(hbaseColFlags);

  return 0;
}

short CmpSeabaseDDL::getColInfo(ElemDDLColDef * colNode, 
                                NABoolean isMetadataHistOrReposColumn,
                                NAString &colFamily,
                                NAString &colName,
                                NABoolean alignedFormat,
				Lng32 &datatype,
				Lng32 &length,
				Lng32 &precision,
				Lng32 &scale,
				Lng32 &dtStart,
				Lng32 &dtEnd,
				Lng32 &upshifted,
				Lng32 &nullable,
				NAString &charset,
                                ComColumnClass &colClass,
				ComColumnDefaultClass &defaultClass, 
				NAString &defVal,
				NAString &heading,
				LobsStorage &lobStorage,
				ULng32 &hbaseColFlags,
                                Int64 &colFlags)
{
  short rc = 0;

  hbaseColFlags = 0;
  colFlags = 0;

  colFamily = colNode->getColumnFamily();
  colName = colNode->getColumnName();

  if (colNode->isHeadingSpecified())
    heading = colNode->getHeading();

  Lng32 serializedOption = -1; // not specified
  if (colNode->isSerializedSpecified())
    {
      serializedOption = (colNode->isSeabaseSerialized() ? 1 : 0);
    }

  NAType * naType = colNode->getColumnDataType();
  if (! naType)
    {
      *CmpCommon::diags() << DgSqlCode(-2004);
      return -1;
    }

  CharInfo::Collation collationSequence = CharInfo::DefaultCollation;
  rc = getTypeInfo(naType, alignedFormat, serializedOption,
                   datatype, length, precision, scale, dtStart, dtEnd, upshifted, nullable,
                   charset, collationSequence, hbaseColFlags);

  if (colName == "SYSKEY")
    {
      resetFlags(hbaseColFlags, NAColumn::SEABASE_SERIALIZED);
    }

  if  (collationSequence != CharInfo::DefaultCollation)
    {
      // collation not supported
      *CmpCommon::diags() << DgSqlCode(-4069)
                          << DgColumnName(ToAnsiIdentifier(colName))
                          << DgString0(CharInfo::getCollationName(collationSequence));
      rc = -1;
    }
  
  if (rc)
    {
      return rc;
    }

  if ((!isMetadataHistOrReposColumn) &&
      (naType->getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (naType->getNominalSize() > CmpCommon::getDefaultNumeric(TRAF_MAX_CHARACTER_COL_LENGTH)))
    {
      *CmpCommon::diags() << DgSqlCode(-4247)
                          << DgInt0(naType->getNominalSize())
                          << DgInt1(CmpCommon::getDefaultNumeric(TRAF_MAX_CHARACTER_COL_LENGTH))
                          << DgColumnName(ToAnsiIdentifier(colName));
      return -1;
    }

  lobStorage = Lob_Invalid_Storage;
  if (naType->getTypeQualifier() == NA_LOB_TYPE)
    lobStorage = colNode->getLobStorage();

  colClass = colNode->getColumnClass();

  NABoolean negateIt = FALSE;
  if (colNode->getDefaultClauseStatus() == ElemDDLColDef::NO_DEFAULT_CLAUSE_SPEC)
    defaultClass = COM_NO_DEFAULT;
  else if (colNode->getDefaultClauseStatus() == ElemDDLColDef::DEFAULT_CLAUSE_NOT_SPEC)
    {
      if (nullable)
        {
          defaultClass = COM_NULL_DEFAULT;
        }
      else
        defaultClass = COM_NO_DEFAULT;
    }
  else if (colNode->getDefaultClauseStatus() == ElemDDLColDef::DEFAULT_CLAUSE_SPEC)
    {
      ItemExpr * ie = colNode->getDefaultValueExpr();
      if (colNode->getSGOptions())
        {
          if (colNode->getSGOptions()->isGeneratedAlways())
            defaultClass = COM_IDENTITY_GENERATED_ALWAYS;
          else
            defaultClass = COM_IDENTITY_GENERATED_BY_DEFAULT;
        }
      else if (ie == NULL)
        if (colNode->getComputedDefaultExpr().isNull())
          defaultClass = COM_NO_DEFAULT;
        else
          {
            defaultClass = COM_ALWAYS_COMPUTE_COMPUTED_COLUMN_DEFAULT;
            defVal = colNode->getComputedDefaultExpr();
            if (colNode->isDivisionColumn())
              colFlags |= SEABASE_COLUMN_IS_DIVISION;
            else if (colName == ElemDDLSaltOptionsClause::getSaltSysColName())
              colFlags |= SEABASE_COLUMN_IS_SALT;
            else
              CMPASSERT(0);
          }
      else if (!colNode->getDefaultExprString().isNull())
        {
            defaultClass = COM_FUNCTION_DEFINED_DEFAULT;
            defVal = colNode->getDefaultExprString();
        }
      else if (ie->getOperatorType() == ITM_CURRENT_TIMESTAMP)
        {
          defaultClass = COM_CURRENT_DEFAULT;
        }
      else if ((ie->getOperatorType() == ITM_CAST) &&
               (ie->getChild(0)->castToItemExpr()->getOperatorType() == ITM_CURRENT_TIMESTAMP))
        {
          defaultClass = COM_CURRENT_DEFAULT;
        }
      else if (ie->getOperatorType() == ITM_UNIX_TIMESTAMP)
        {
          defaultClass = COM_CURRENT_UT_DEFAULT;
        }
      else if ((ie->getOperatorType() == ITM_CAST) &&
               (ie->getChild(0)->castToItemExpr()->getOperatorType() == ITM_UNIX_TIMESTAMP))
        {
          defaultClass = COM_CURRENT_UT_DEFAULT;
        }
      else if (ie->getOperatorType() == ITM_UNIQUE_ID)
        {
          defaultClass = COM_UUID_DEFAULT;
        }
      else if ((ie->getOperatorType() == ITM_CAST) &&
               (ie->getChild(0)->castToItemExpr()->getOperatorType() == ITM_UNIQUE_ID))
        {
          defaultClass = COM_UUID_DEFAULT;
        }
      else if ((ie->getOperatorType() == ITM_USER) ||
               (ie->getOperatorType() == ITM_CURRENT_USER) ||
               (ie->getOperatorType() == ITM_SESSION_USER))
        {
          defaultClass = COM_USER_FUNCTION_DEFAULT;
        }
      else if (ie->castToConstValue(negateIt) != NULL)
        {
          if (ie->castToConstValue(negateIt)->isNull())
            {
              defaultClass = COM_NULL_DEFAULT;
            }
          else
            {
              defaultClass = COM_USER_DEFINED_DEFAULT;

              const ComString name = colNode->getColumnName();
              const NAType * genericType = colNode->getColumnDataType();
              
              rc = checkDefaultValue(ToAnsiIdentifier(name),
                                     genericType, colNode);
              if (rc)
                return -1;

              ie = colNode->getDefaultValueExpr();

              ConstValue * cv = ie->castToConstValue(negateIt);
              
              if (cv->getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
                {
                  if (((CharType*)(cv->getType()))->getCharSet() == CharInfo::UNICODE)
                    {
                      NAWString naws(CharInfo::UNICODE, (char*)cv->getConstValue(), cv->getStorageSize());
                      NAString * nas = unicodeToChar(naws.data(), naws.length(), 
                                                     CharInfo::UTF8, STMTHEAP);
                      if (nas)
                        {
                          defVal = "_UCS2'";
                          defVal += *nas;
                          defVal += "'";
                        }
                      else
                        {
                          defVal = cv->getConstStr();
                        }
                    } // ucs2
                  else if (((CharType*)(cv->getType()))->getCharSet() == CharInfo::ISO88591)
                    {
                      char * cvalue = (char*)cv->getConstValue();
                      Lng32 cvlen = cv->getStorageSize();
                      if (cv->getType()->isVaryingLen())
                        {
                          cvlen = *(short*)cvalue;
                          cvalue = cvalue + sizeof(short);
                        }

                      // convert iso to utf8
                     NAString * nas = charToChar(CharInfo::UTF8, 
                                                 cvalue, cvlen,
                                                 CharInfo::ISO88591, STMTHEAP);
                      if (nas)
                        {
                          defVal = "_ISO88591'";
                          defVal += *nas;
                          defVal += "'";
                        }
                      else
                        {
                          defVal = cv->getConstStr();
                        }
                    }
                  else
                    defVal = cv->getConstStr();
                }
              else
                defVal = cv->getConstStr();
            }
        }
      else
        defaultClass = COM_NO_DEFAULT;
    }

  return 0;
}

short CmpSeabaseDDL::createRowId(NAString &key,
                                 NAString &part1, Lng32 part1MaxLen,
                                 NAString &part2, Lng32 part2MaxLen,
                                 NAString &part3, Lng32 part3MaxLen,
                                 NAString &part4, Lng32 part4MaxLen)
{
  if (part1.isNull())
    return 0;

  part1MaxLen = part2MaxLen = part3MaxLen = part4MaxLen = 20;

  NAString keyValPadded;

  keyValPadded = part1;
  if (part1.length() < part1MaxLen)
    keyValPadded.append(' ', (part1MaxLen - part1.length()));

  if (NOT part2.isNull())
    {
      keyValPadded += part2;
      if (part2.length() < part2MaxLen)
        keyValPadded.append(' ', (part2MaxLen - part2.length()));
    }

  if (NOT part3.isNull())
    {
      keyValPadded += part3;
      if (part3.length() < part3MaxLen)
        keyValPadded.append(' ', (part3MaxLen - part3.length()));
    }

  if (NOT part4.isNull())
    {
      keyValPadded += part4;
      if (part4.length() < part4MaxLen)
        keyValPadded.append(' ', (part4MaxLen - part4.length()));
    }

  // encode and convertToHex
  key = keyValPadded;

  return 0;
}

///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
static short isValidHbaseName(const char * str)
{
  
  // A valid hbase name must contain 'word characters': [a-zA-Z_0-9-.]

  for (Lng32 i = 0; i < strlen(str); i++)
    {
      char c = str[i];

      if (NOT (((c >= '0') && (c <= '9')) ||
               ((c >= 'a') && (c <= 'z')) ||
               ((c >= 'A') && (c <= 'Z')) ||
               ((c == '_') || (c == '-') || (c == '.'))))
        return 0; // not a valid name
    }

  return -1; // valid name
}

NAString CmpSeabaseDDL::genHBaseObjName(const NAString &catName, 
                                        const NAString &schName,
                                        const NAString &objName)
{
  NAString extNameForHbase =  "" ;
  extNameForHbase += catName + "." + schName + "." + objName;
  return extNameForHbase;
}

// RETURN: 1, exists. 0, does not exists. -1, error.
short CmpSeabaseDDL::existsInSeabaseMDTable(
                                          ExeCliInterface *cliInterface,
                                          const char * catName,
                                          const char * schName,
                                          const char * objName,
                                          const ComObjectType objectType,
                                          NABoolean checkForValidDef,
                                          NABoolean checkForValidHbaseName,
                                          NABoolean returnInvalidStateError)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char cfvd[100];
  strcpy(cfvd, " ");
  if (checkForValidDef)
    strcpy(cfvd, " and valid_def = 'Y' ");

  // Name must be a valid hbase name
  if (checkForValidHbaseName)
    {
      if ((! isValidHbaseName(catName)) ||
          (! isValidHbaseName(schName)) ||
          (! isValidHbaseName(objName)))
        {
          *CmpCommon::diags() << DgSqlCode(-1422);

          return -1;
        }

      // HBase name must not be too long (see jira HDFS-6055)
      // Generated HBase name = catName.schName.objName
      Int32 nameLen = (strlen(catName) + 1 +
                       strlen(schName) + 1 +
                       strlen(objName));
      if (nameLen > MAX_HBASE_NAME_LEN)
        {
          *CmpCommon::diags() << DgSqlCode(-CAT_HBASE_NAME_TOO_LONG)
                              << DgInt0(nameLen)
                              << DgInt1(MAX_HBASE_NAME_LEN);

          return -1;
        }
    }
 
  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);
  
  char objectTypeLit[3] = {0};
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);
  char buf[4000];
  if (objectType == COM_UNKNOWN_OBJECT)
    str_sprintf(buf, "select count(*) from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' %s ",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                catName, quotedSchName.data(), quotedObjName.data(),
                cfvd);
  else
    str_sprintf(buf, "select count(*) from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' %s ",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                catName, quotedSchName.data(), quotedObjName.data(), objectTypeLit,
                cfvd);
    
  Lng32 len = 0;
  Int64 rowCount = 0;
  cliRC = cliInterface->executeImmediate(buf, (char*)&rowCount, &len, FALSE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (rowCount > 0)
    return 1; // exists
  else if (returnInvalidStateError)
    {
      NABoolean validDef = FALSE;
      cliRC = getObjectValidDef(cliInterface,  
                                catName, schName, objName,
                                objectType,
                                validDef);
      if (cliRC < 0)
        return -1;

      if ((cliRC == 1) && (NOT validDef)) // found and not valid
        {
          // invalid object, return error.
          NAString extTableName = NAString(catName) + "." + NAString(schName) + "."
            + NAString(objName);
          CmpCommon::diags()->clear();
          *CmpCommon::diags() << DgSqlCode(-4254)
                              << DgString0(extTableName);
          
          return -1;
        }

      return 0; // does not exist
    }
  else
    return 0; // does not exist
}

Int64 CmpSeabaseDDL::getObjectTypeandOwner(
                                   ExeCliInterface *cliInterface,
                                   const char * catName,
                                   const char * schName,
                                   const char * objName,
                                   ComObjectType & objectType,
                                   Int32 & objectOwner)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  char buf[4000];
  str_sprintf(buf, "select object_type, object_owner, object_UID from %s.\"%s\".%s "
                   "where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' ",
              getSystemCatalogStatic().data(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedObjName.data());
  
  cliRC = cliInterface->fetchRowsPrologue(buf, TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      return -1;
    }

  char * ptr = NULL;
  Lng32 len = 0;
  char objectTypeLit[3] = {0};
  cliInterface->getPtrAndLen(1, ptr, len);
  str_cpy_and_null(objectTypeLit, ptr, len, '\0', ' ', TRUE);
  objectType = PrivMgr::ObjectLitToEnum(objectTypeLit);
  
  cliInterface->getPtrAndLen(2, ptr, len);
  objectOwner = *(Int32*)ptr;
  
  cliInterface->getPtrAndLen(3, ptr, len);
  Int64 objUID = *(Int64*)ptr;

  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return objUID;
  
}


short CmpSeabaseDDL::getObjectName(
                                         ExeCliInterface *cliInterface,
                                         Int64 objUID,
                                         NAString &catName,
                                         NAString &schName,
                                         NAString &objName,
                                         char * outObjType,
                                         NABoolean lookInObjects,
                                         NABoolean lookInObjectsIdx)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  ExeCliInterface cqdCliInterface(STMTHEAP);

  if (lookInObjectsIdx)
    str_sprintf(buf, "select catalog_name, schema_name, object_name, object_type from table(index_table %s.\"%s\".%s) where \"OBJECT_UID@\" = %ld ",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS_UNIQ_IDX,
                objUID);
  else
    {
      str_sprintf(buf, "select catalog_name, schema_name, object_name, object_type from %s.\"%s\".%s where object_uid = %ld ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                  objUID);
    }

  if (lookInObjects)
    {
      char shapeBuf[1000];
      str_sprintf(shapeBuf, "control query shape scan (path '%s.\"%s\".%s')",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS) ;
      if (cqdCliInterface.setCQS(shapeBuf))
        {
          cqdCliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
    }

  cliRC = cliInterface->fetchRowsPrologue(buf, TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
    }

  if (lookInObjects)
    {
      cqdCliInterface.resetCQS();
    }

  if (cliRC < 0)
    {
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(objName);

      return -1389;
    }

  char * ptr = NULL;
  Lng32 len = 0;
  cliInterface->getPtrAndLen(1, ptr, len);
  catName = "";
  catName.append(ptr, len);

  cliInterface->getPtrAndLen(2, ptr, len);
  schName = "";
  schName.append(ptr, len);

  cliInterface->getPtrAndLen(3, ptr, len);
  objName = "";
  objName.append(ptr, len);

  if (outObjType)
    {
      cliInterface->getPtrAndLen(4, ptr, len);
      str_cpy_and_null(outObjType, ptr, len, '\0', ' ', TRUE);
    }

  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return 0;
}

Int64 CmpSeabaseDDL::getObjectUID(
                                   ExeCliInterface *cliInterface,
                                   const char * catName,
                                   const char * schName,
                                   const char * objName,
                                   const char * inObjType,
                                   const char * inObjTypeStr,
                                   char * outObjType,
                                   NABoolean lookInObjectsIdx,
                                   NABoolean reportErrorNow)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  char buf[4000];
  if (inObjType)
    {
      if (lookInObjectsIdx)
        str_sprintf(buf, "select \"OBJECT_UID@\", object_type from table(index_table %s.\"%s\".%s) where catalog_name = '%s' and schema_name = '%s' and object_name = '%s'  and object_type = '%s' ",
                    getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS_UNIQ_IDX,
                    catName, quotedSchName.data(), quotedObjName.data(),
                    inObjType);
      else
        str_sprintf(buf, "select object_uid, object_type from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s'  and object_type = '%s' ",
                    getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                    catName, quotedSchName.data(), quotedObjName.data(),
                    inObjType);
    }
  else if (inObjTypeStr)
    str_sprintf(buf, "select object_uid, object_type from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s'  and ( %s ) ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                catName, quotedSchName.data(), quotedObjName.data(),
                inObjTypeStr);
  else // inObjType == NULL
    {
      if (lookInObjectsIdx)
        str_sprintf(buf, "select \"OBJECT_UID@\", object_type from table(index_table %s.\"%s\".%s) where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' ",
                    getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS_UNIQ_IDX,
                    catName, quotedSchName.data(), quotedObjName.data());
      else
      str_sprintf(buf, "select object_uid, object_type from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                  catName, quotedSchName.data(), quotedObjName.data());
    }
  cliRC = cliInterface->fetchRowsPrologue(buf, TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      if (reportErrorNow)
        *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(objName);

      return -1;
    }

  char * ptr = NULL;
  Lng32 len = 0;
  cliInterface->getPtrAndLen(1, ptr, len);
  Int64 objUID = *(Int64*)ptr;

  if (outObjType)
    {
      cliInterface->getPtrAndLen(2, ptr, len);
      str_cpy_and_null(outObjType, ptr, len, '\0', ' ', TRUE);
    }

  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return objUID;
}

Int64 CmpSeabaseDDL::getObjectInfo(
                                   ExeCliInterface *cliInterface,
                                   const char * catName,
                                   const char * schName,
                                   const char * objName,
                                   const ComObjectType objectType,
                                   Int32 & objectOwner,
                                   Int32 & schemaOwner,
                                   Int64 & objectFlags,
                                   bool reportErrorNow,
                                   NABoolean checkForValidDef,
                                   Int64 *createTime)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);
  char objectTypeLit[3] = {0};
  
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);

  char cfvd[100];
  strcpy(cfvd, " ");
  if (checkForValidDef)
    strcpy(cfvd, " and valid_def = 'Y' ");

  char buf[4000];
  str_sprintf(buf, "select object_uid, object_owner, schema_owner, flags, create_time from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s'  and object_type = '%s' %s ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedObjName.data(),
              objectTypeLit, cfvd);
    
  cliRC = cliInterface->fetchRowsPrologue(buf, TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      if ( reportErrorNow )
         *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(objName);

      return -1;
    }

  char * ptr = NULL;
  Lng32 len = 0;

  // return object_uid
  cliInterface->getPtrAndLen(1, ptr, len);
  Int64 objUID = *(Int64*)ptr;

  // return object_owner
  cliInterface->getPtrAndLen(2, ptr, len);
  objectOwner = *(Int32*)ptr;

  // return schema_owner
  cliInterface->getPtrAndLen(3, ptr, len);
  schemaOwner = *(Int32*)ptr;

  // return flags
  cliInterface->getPtrAndLen(4, ptr, len);
  objectFlags = *(Int64*)ptr;

  // return create_time
  cliInterface->getPtrAndLen(5, ptr, len);
  if (createTime)
    *createTime = *(Int64*)ptr;
  
  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return objUID;
}


short CmpSeabaseDDL::getObjectOwner(ExeCliInterface *cliInterface,
                     const char * catName,
                     const char * schName,
                     const char * objName,
                     const char * objType,
                     Int32 * objectOwner)
{
  Int32 retcode = 0;
  Int32 cliRC = 0;

  NAString stmt;

  stmt = "select object_owner from ";
  stmt += getSystemCatalog();
  stmt += ".\"";
  stmt += SEABASE_MD_SCHEMA;
  stmt += "\".";
  stmt += SEABASE_OBJECTS;
  stmt += " where catalog_name = '";
  stmt += catName;
  stmt += "' and schema_name = '";
  stmt += schName;  
  stmt += "' and object_name = '";
  stmt += objName ;

  if (objType)
    {
      stmt += "' and object_type = '";
      stmt += objType;
    }

  stmt += "' for read uncommitted access"; 

  cliRC = cliInterface->fetchRowsPrologue(stmt.data(), TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      NAString strObjName (catName);
      strObjName += '.';
      strObjName += schName;
      strObjName += '.';
      strObjName += objName;    
      *CmpCommon::diags() << DgSqlCode(-1389)
                          << DgString0(strObjName.data());
      return -1;
    }

  char * ptr = NULL;
  Lng32 len = 0;
  cliInterface->getPtrAndLen(1, ptr, len);
  *objectOwner = *(Int32*)ptr;

  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return 0;
}

short CmpSeabaseDDL::getObjectValidDef(ExeCliInterface *cliInterface,
                                       const char * catName,
                                       const char * schName,
                                       const char * objName,
                                       const ComObjectType objectType,
                                       NABoolean &validDef)
{
  Int32 retcode = 0;
  Int32 cliRC = 0;

  char buf[4000];

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);
 
  char objectTypeLit[3] = {0};
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);

  if (objectType == COM_UNKNOWN_OBJECT)
    str_sprintf(buf, "select valid_def from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' ",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                catName, quotedSchName.data(), quotedObjName.data());
  else
    str_sprintf(buf, "select valid_def from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s'  and object_type = '%s' ",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                catName, quotedSchName.data(), quotedObjName.data(),
                objectTypeLit);
    
  cliRC = cliInterface->fetchRowsPrologue(buf, TRUE/*no exec*/);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  cliRC = cliInterface->clearExecFetchClose(NULL, 0);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (cliRC == 100) // did not find the row
    {
      return 0;
    }

  char * ptr = NULL;
  Lng32 len = 0;
  cliInterface->getPtrAndLen(1, ptr, len);
  validDef =  ((memcmp(ptr, COM_YES_LIT, 1) == 0) ? TRUE : FALSE);

  cliInterface->fetchRowsEpilogue(NULL, TRUE);

  return 1;
}

Int64 CmpSeabaseDDL::getConstraintOnIndex(
                                          ExeCliInterface *cliInterface,
                                          Int64 btUID,
                                          Int64 indexUID,
                                          const char * constrType,
                                          NAString &catName,
                                          NAString &schName,
                                          NAString &objName)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  str_sprintf(buf, "select C.constraint_uid, O.catalog_name, O.schema_name, O.object_name from %s.\"%s\".%s C, %s.\"%s\".%s O where C.table_uid = %ld and C.index_uid = %ld and C.constraint_type = '%s' and C.constraint_uid = O.object_uid",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLE_CONSTRAINTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              btUID, indexUID, constrType);

  Queue * constrsQueue = NULL;
  cliRC = cliInterface->fetchAllRows(constrsQueue, buf, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return cliRC;
    }
 
  if (constrsQueue->numEntries() == 0)
    return 0;

  constrsQueue->position();
  OutputInfo * vi = (OutputInfo*)constrsQueue->getNext(); 
  
  Int64 constrUID = *(Int64*)vi->get(0);
  catName = vi->get(1);
  schName = vi->get(2);
  objName = vi->get(3);

  return constrUID;
}

short CmpSeabaseDDL::getUsingObject(ExeCliInterface *cliInterface,
                                     Int64 objUID,
                                     NAString &usingObjName)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  
  char buf[4000];
  str_sprintf(buf, "select trim(catalog_name) || '.' || trim(schema_name) || '.' || trim(object_name) from %s.\"%s\".%s T, %s.\"%s\".%s VU where VU.used_object_uid = %ld and T.object_uid = VU.using_view_uid  and T.valid_def = 'Y' ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE,
              objUID);

  //Turn off CQDs MERGE_JOINS and HASH_JOINS to avoid a full table scan of 
  //SEABASE_OBJECTS table. Full table scan of SEABASE_OBJECTS table causes
  //simultaneous DDL operations to run into conflict.
  //Make sure to restore the CQDs after this query including error paths.
  cliInterface->holdAndSetCQD("MERGE_JOINS", "OFF");
  cliInterface->holdAndSetCQD("HASH_JOINS", "OFF");

  Queue * usingViewsQueue = NULL;
  cliRC = cliInterface->fetchAllRows(usingViewsQueue, buf, 0, FALSE, FALSE, TRUE);
  
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
    }
  
  //restore CQDs.
  cliInterface->restoreCQD("MERGE_JOINS");
  cliInterface->restoreCQD("HASH_JOINS");
  
  if (cliRC < 0)
     return cliRC; 
  
  if (usingViewsQueue->numEntries() == 0)
    return 100;

  usingViewsQueue->position();
  OutputInfo * vi = (OutputInfo*)usingViewsQueue->getNext(); 
  
  char * viewName = vi->get(0);

  usingObjName = viewName;

  return 0;
}

short CmpSeabaseDDL::getBaseTable(ExeCliInterface *cliInterface,
                                  const NAString &indexCatName,
                                  const NAString &indexSchName,
                                  const NAString &indexObjName,
                                  NAString &btCatName,
                                  NAString &btSchName,
                                  NAString &btObjName,
                                  Int64 &btUID,
                                  Int32 &btObjOwner,
                                  Int32 &btSchemaOwner)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  str_sprintf(buf, "select trim(O.catalog_name), trim(O.schema_name),"
                   " trim(O.object_name), O.object_uid, O.object_owner, O.schema_owner"
                   " from %s.\"%s\".%s O "
                   " where O.object_uid = (select I.base_table_uid from %s.\"%s\".%s I" 
                      " where I.index_uid = (select O2.object_uid from %s.\"%s\".%s O2" 
                          " where O2.catalog_name = '%s' and O2.schema_name = '%s' and"
                               " O2.object_name = '%s' and O2.object_type = 'IX')) ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_INDEXES,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              (char*)indexCatName.data(), (char*)indexSchName.data(),
              (char*)indexObjName.data());

  Queue * usingTableQueue = NULL;
  cliRC = cliInterface->fetchAllRows(usingTableQueue, buf, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return cliRC;
    }
 
  if (usingTableQueue->numEntries() != 1)
    {
      // error
     *CmpCommon::diags() << DgSqlCode(-4082);
 
      return -1;
    }

  usingTableQueue->position();
  OutputInfo * vi = (OutputInfo*)usingTableQueue->getNext(); 
  
  btCatName = vi->get(0);
  btSchName = vi->get(1);
  btObjName = vi->get(2);
  btUID         = *(Int64*)vi->get(3);
  btObjOwner    = *(Int32*)vi->get(4);
  btSchemaOwner = *(Int32*)vi->get(5);

  return 0;
}

short CmpSeabaseDDL::getUsingViews(ExeCliInterface *cliInterface,
                                   Int64 objectUID,
                                   Queue * &usingViewsQueue)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];
              
  str_sprintf(buf, "select '\"' || trim(catalog_name) || '\"' || '.' || '\"' || trim(schema_name) || '\"' || '.' || '\"' || trim(object_name) || '\"' "
                   "from %s.\"%s\".%s T, %s.\"%s\".%s VU "
                   "where T.object_uid = VU.using_view_uid  and "
                   "T.valid_def = 'Y' and VU.used_object_uid = %ld ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE,
              objectUID);
              

  cliRC = cliInterface->fetchAllRows(usingViewsQueue, buf, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return cliRC;
    }
  
  return 0;
}

// finds all views that directly or indirectly(thru another view) contains
// the given object.
// Returns them in ascending order of their create time.
short CmpSeabaseDDL::getAllUsingViews(ExeCliInterface *cliInterface,
                                      NAString &catName,
                                      NAString &schName,
                                      NAString &objName,
                                      Queue * &usingViewsQueue)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];
              
  str_sprintf(buf, "select '\"' || trim(o.catalog_name) || '\"' || '.' || '\"' || trim(o.schema_name) || '\"' || '.' || '\"' || trim(o.object_name) || '\"' "
    ", o.create_time from %s.\"%s\".%s O, "
    " (get all views on table \"%s\".\"%s\".\"%s\") x(a) "
    " where trim(O.catalog_name) || '.' || trim(O.schema_name) || '.' || trim(O.object_name) = x.a "
    " order by 2",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName.data(), schName.data(), objName.data());
  
  cliRC = cliInterface->fetchAllRows(usingViewsQueue, buf, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return cliRC;
    }
  
  return 0;
}

/* 
Get the salt column text for a given table or index.
Returns 0 for object does not have salt column
Returns 1 for object has salt column and it is being returned in saltText
Returns -1 for error, which for now is ignored as we have an alternate code path.
 */

short CmpSeabaseDDL::getSaltText(
                                   ExeCliInterface *cliInterface,
                                   const char * catName,
                                   const char * schName,
                                   const char * objName,
                                   const char * inObjType,
                                   NAString& saltText)
{
  Lng32 cliRC = 0;

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);
  Int64 objUID;
  Lng32 colNum;
  NAString defaultValue;

  char buf[4000];
  char *data;
  Lng32 len;

  // determine object UID and column number of the _SALT_ column in the Trafodion table
  // TBD: Once flags has been updated for older objects, replace predicates on column_name
  //      and default_class with a check for the SEABASE_COLUMN_IS_SALT bit in columns.flags
  str_sprintf(buf, "select object_uid, column_number, cast(default_value as varchar(512) character set iso88591) from %s.\"%s\".%s o, %s.\"%s\".%s c where o.catalog_name = '%s' and o.schema_name = '%s' and o.object_name = '%s'  and o.object_type = '%s'  and o.object_uid = c.object_uid and c.column_name = '%s' and c.default_class = %d",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS,
              catName, quotedSchName.data(), quotedObjName.data(),
              inObjType,
              ElemDDLSaltOptionsClause::getSaltSysColName(),
              (int) COM_ALWAYS_COMPUTE_COMPUTED_COLUMN_DEFAULT);

  Queue * saltQueue = NULL;
  cliRC = cliInterface->fetchAllRows(saltQueue, buf, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }
 
  // did not find row
  if (saltQueue->numEntries() == 0)
    return 0;

  saltQueue->position();
  OutputInfo * vi = (OutputInfo*)saltQueue->getNext(); 
  objUID = *(Int64 *)vi->get(0);
  colNum = *(Lng32 *)vi->get(1);
  defaultValue = vi->get(2);

  // this should be the normal case, salt text is stored in the TEXT table,
  // not the default value
  cliRC = getTextFromMD(cliInterface,
                        objUID,
                        COM_COMPUTED_COL_TEXT,
                        colNum,
                        saltText);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  if (saltText.isNull())
    saltText = defaultValue;

  CMPASSERT(!saltText.isNull());

  return 1;
}

short CmpSeabaseDDL::getAllIndexes(ExeCliInterface *cliInterface,
                                   Int64 objUID,
                                   NABoolean includeInvalidDefs,
                                   Queue * &indexInfoQueue)
{
  Lng32 cliRC = 0;

  char query[4000];
  str_sprintf(query, "select O.catalog_name, O.schema_name, O.object_name, O.object_uid from %s.\"%s\".%s I, %s.\"%s\".%s O ,  %s.\"%s\".%s T where I.base_table_uid = %ld and I.index_uid = O.object_uid %s and I.index_uid = T.table_uid and I.keytag != 0 for read committed access ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_INDEXES,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLES,
              objUID,
              (includeInvalidDefs ? " " : " and O.valid_def = 'Y' "));

  cliRC = cliInterface->fetchAllRows(indexInfoQueue, query, 0, FALSE, FALSE, TRUE);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      processReturn();

      return -1;
    }
  
  return 0;
}


// Convert from hbase options string format to list of structs.
// String format:
//    HBASE_OPTIONS=>0002COMPRESSION='GZ'|BLOCKCACHE='10'|
//
// If beginPos and/or endPos parameters are not null, then the
// beginning and/or ending position of the HBASE_OPTIONS string
// is returned.
//
// Note that the input string may have things other than HBASE_OPTIONS
// in it (such as ROW_FORMAT=>ALIGNED, for example). Those other things
// are ignored by this method.
    
short CmpSeabaseDDL::genHbaseCreateOptions(
                                           const char * hbaseCreateOptionsStr,
                                           NAList<HbaseCreateOption*>* &hbaseCreateOptions,
                                           NAMemory * heap,
                                           size_t * beginPos,
                                           size_t * endPos)
{
  hbaseCreateOptions = NULL;
  if (beginPos)
    *beginPos = 0;
  if (endPos)
    *endPos = 0;

  if (hbaseCreateOptionsStr == NULL)
    return 0;

  const char * hboStr = strstr(hbaseCreateOptionsStr, "HBASE_OPTIONS=>");
  if (! hboStr)
    return 0;

  char  numHBOstr[5];
  const char * startNumHBO = hboStr + strlen("HBASE_OPTIONS=>");
  memcpy(numHBOstr, startNumHBO, 4);
  numHBOstr[4] = 0;
  
  Lng32 numHBO = str_atoi(numHBOstr, 4);
  if (numHBO == 0)
    return 0;

  hbaseCreateOptions = new(heap) NAList<HbaseCreateOption*>(heap);

  const char * optionStart = startNumHBO + 4;
  
  for (Lng32 i = 0; i < numHBO; i++)
    {
      // look for pattern    ='   to find the end of current option.
      const char * optionEnd = strstr(optionStart, "='");
      if (! optionEnd) // this is an error
        { 
          for (CollIndex k = 0; k < hbaseCreateOptions->entries(); k++)
            {
              HbaseCreateOption * hbo = (*hbaseCreateOptions)[k];
              delete hbo;
            }
          delete hbaseCreateOptions;
          return -1;
        }

      const char * valStart = optionEnd + strlen("='");
      const char * valEnd = strstr(valStart, "'|");
      if (! valEnd) // this is an error
        {
          for (CollIndex k = 0; k < hbaseCreateOptions->entries(); k++)
            {
              HbaseCreateOption * hbo = (*hbaseCreateOptions)[k];
              delete hbo;
            }
          delete hbaseCreateOptions;
          return -1;
        }

      NAText key(optionStart, (optionEnd-optionStart));
      NAText val(valStart, (valEnd - valStart));

      HbaseCreateOption * hco = new(heap) HbaseCreateOption(key, val);

      hbaseCreateOptions->insert(hco);

      optionStart = valEnd + strlen("'|");
    }

  if (beginPos)
    *beginPos = hboStr - hbaseCreateOptionsStr;
  if (endPos)
    // + 1 to allow for a space after the last |
    // (this trailing space is always present)
    *endPos = optionStart - hbaseCreateOptionsStr + 1;

  return 0;
}


// The function below is an inverse of CmpSeabaseDDL::genHbaseCreateOptions.
// It takes an NAList of HbaseCreateOption objects and generates the equivalent
// metadata text. Returns 0 if successful (and it is always successful).
// Note that quotes inside the string are not doubled here.

short CmpSeabaseDDL::genHbaseOptionsMetadataString(                                          
                                           const NAList<HbaseCreateOption*> & hbaseCreateOptions,
                                           NAString & hbaseOptionsMetadataString /* out */)
{
  CollIndex numberOfOptions = hbaseCreateOptions.entries();
  if (numberOfOptions == 0)
    {
      hbaseOptionsMetadataString = "";  // no HBase options so return empty string
    }
  else
    {
      hbaseOptionsMetadataString = "HBASE_OPTIONS=>";
  
      // put in a 4-digit text NNNN indicating how many options there are

      if (numberOfOptions > HBASE_OPTIONS_MAX_LENGTH)
        // shouldn't happen; but truncate if it does for safety (note also
        // that HBASE_OPTIONS_MAX_LENGTH happens to be 4 digits)
        numberOfOptions = HBASE_OPTIONS_MAX_LENGTH;

      char inTextForm[5];  // room for NNNN and null terminator

      sprintf(inTextForm,"%04d",numberOfOptions);
      hbaseOptionsMetadataString += inTextForm;

      // now loop through list, appending KEY='VALUE'| for each option
   
      for (CollIndex i = 0; i < numberOfOptions; i++)
        {
          HbaseCreateOption * hbaseOption = hbaseCreateOptions[i];  
          NAText &key = hbaseOption->key();                        
          NAText &val = hbaseOption->val();

          hbaseOptionsMetadataString += key.c_str();
          hbaseOptionsMetadataString += "='";
          hbaseOptionsMetadataString += val.c_str();
          hbaseOptionsMetadataString += "'|";
        }
      
      hbaseOptionsMetadataString += " ";  // add a trailing separator     
    }

  return 0;
}


// This method updates the HBASE_OPTIONS=> text in the metadata with
// new HBase options.

short CmpSeabaseDDL::updateHbaseOptionsInMetadata(
  ExeCliInterface * cliInterface,
  Int64 objectUID,
  ElemDDLHbaseOptions * edhbo)
{
  short result = 0;

  // get the text from the metadata

  ComTextType textType = COM_HBASE_OPTIONS_TEXT;  // to get text containing HBASE_OPTIONS=>
  Lng32 textSubID = 0; // meaning, the text pertains to the object as a whole
  NAString metadataText(STMTHEAP);
  result = getTextFromMD(cliInterface,
                         objectUID,
                         textType,  
                         textSubID,
                         metadataText /* out */);
  if (result != 0)
    return result;

  // convert the text to an NAList <HbaseCreateOption *> representation

  NAList<HbaseCreateOption *> * hbaseCreateOptions = NULL;
  size_t beginHBOTextPos = 0;
  size_t endHBOTextPos = 0;
  result = genHbaseCreateOptions(metadataText.data(),
                                 hbaseCreateOptions /* out */,
                                 STMTHEAP,
                                 &beginHBOTextPos /* out */,
                                 &endHBOTextPos /* out */);
  if (result != 0)
    // genHbaseCreateOptions makes sure hbaseCreateOptions is deleted
    return result; 

  // merge the new HBase options into the old ones, replacing any key
  // value pairs that exist in both with the new one

  // Note: It's likely that the typical case is just one Hbase option
  // so we don't bother with clever optimizations such as what if the
  // old list is empty.

  if (!hbaseCreateOptions)
    hbaseCreateOptions = new(STMTHEAP) NAList<HbaseCreateOption *>(STMTHEAP);

  NAList<HbaseCreateOption *> & newHbaseCreateOptions = edhbo->getHbaseOptions(); 
  for (CollIndex i = 0; i < newHbaseCreateOptions.entries(); i++)
    {
      HbaseCreateOption * newHbaseOption = newHbaseCreateOptions[i];  
      bool notFound = true;
      for (CollIndex j = 0; notFound && j < hbaseCreateOptions->entries(); j++)
        {
          HbaseCreateOption * hbaseOption = (*hbaseCreateOptions)[j];
          if (newHbaseOption->key() == hbaseOption->key())
            {
            hbaseOption->setVal(newHbaseOption->val());
            notFound = false;
            }
        }
      if (notFound)
        {
        HbaseCreateOption * copyOfNew = new(STMTHEAP) HbaseCreateOption(*newHbaseOption);
        hbaseCreateOptions->insert(copyOfNew);
        }
    }
   
  // convert the merged list to text

  NAString hbaseOptionsMetadataString(STMTHEAP);
  result = genHbaseOptionsMetadataString(*hbaseCreateOptions,
                                         hbaseOptionsMetadataString /* out */);
  if (result == 0)
    {
      // edit the old text, removing the present HBASE_OPTIONS=> text if any,
      // and putting the new text in the same spot

      metadataText.replace(beginHBOTextPos, 
                           endHBOTextPos - beginHBOTextPos,
                           hbaseOptionsMetadataString);   
 
      // delete the old text from the metadata

      // Note: It might be tempting to try an upsert instead of a
      // delete followed by an insert, but this won't work. It is
      // possible that the metadata text could shrink and take fewer
      // rows in its new form than the old. So we do the simple thing
      // to avoid such complications.
      Lng32 cliRC = deleteFromTextTable(cliInterface, objectUID, textType, textSubID);
      if (cliRC < 0)
        {
          result = -1;
        }
      else
        {
          // insert the text back into the metadata

          result = updateTextTable(cliInterface,
                                   objectUID,
                                   textType,
                                   textSubID,
                                   metadataText);
        }
    }

  // delete any items we created

  // Note that HbaseCreateOption contains members that allocate
  // storage from the global heap so we must delete HbaseCreateOption
  // explicitly to avoid global heap memory leaks.
  
  for (CollIndex k = 0; k < hbaseCreateOptions->entries(); k++)
    {
      HbaseCreateOption * hbaseOption = (*hbaseCreateOptions)[k];
      delete hbaseOption;
    }
  delete hbaseCreateOptions;

  return result;
}



void CmpSeabaseDDL::handleDDLCreateAuthorizationError(
   int32_t SQLErrorCode,
   const NAString & catalogName, 
   const NAString & schemaName)
   
{

   switch (SQLErrorCode)
   {
      case CAT_INTERNAL_EXCEPTION_ERROR:
         break;
      case CAT_SCHEMA_DOES_NOT_EXIST_ERROR:
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR)
                                  << DgString0(catalogName)
                                  << DgString1(schemaName);
         break;
      }
      case CAT_NOT_AUTHORIZED:
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
         break;
      }
      default:
         SEABASEDDL_INTERNAL_ERROR("Switch statement in handleDDLCreateAuthorizationError");  
   } 
      
}
    

short CmpSeabaseDDL::updateSeabaseMDObjectsTable(
                                         ExeCliInterface *cliInterface,
                                         const char * catName,
                                         const char * schName,
                                         const char * objName,
                                         const ComObjectType & objectType,
                                         const char * validDef, 
                                         Int32 objOwnerID,
                                         Int32 schemaOwnerID,
                                         Int64 objectFlags,
                                         Int64 &inUID)
{

  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  Int64 objUID = 0;
  if (inUID < 0)
    {
      ComUID comUID;
      comUID.make_UID();
      objUID = comUID.get_value();
    }
  else
    objUID = inUID;

  // return the generated objUID
  inUID = objUID;
  
  char objectTypeLit[3] = {0};
  
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);
  
  Int64 createTime = NA_JulianTimestamp();

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  str_sprintf(buf, "insert into %s.\"%s\".%s values ('%s', '%s', '%s', '%s', %ld, %ld, %ld, '%s', '%s', %d, %d, %ld )",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedObjName.data(),
              objectTypeLit,
              objUID,
              createTime, 
              createTime,
              (validDef ? validDef : COM_YES_LIT),
              COM_NO_LIT,
              objOwnerID,
              schemaOwnerID,
              objectFlags);
  cliRC = cliInterface->executeImmediate(buf);
  
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return cliRC;
    }
    
  return 0;
    
}

short CmpSeabaseDDL::deleteFromSeabaseMDObjectsTable(
     ExeCliInterface *cliInterface,
     const char * catName,
     const char * schName,
     const char * objName,
     const ComObjectType & objectType)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);
  char objectTypeLit[3] = {0};
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);

  str_sprintf(buf, "delete from %s.\"%s\".%s where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedObjName.data(), objectTypeLit);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  return 0;
}
  
static short AssignColEntry(ExeCliInterface *cliInterface, Lng32 entry,
                            char * currRWRSptr, const char * srcPtr, 
                            Lng32 firstColOffset)
{
  Lng32 cliRC = 0;

  Lng32 fsDatatype;
  Lng32 length;
  Lng32 indOffset = -1;
  Lng32 varOffset = -1;
  
  cliRC = cliInterface->getAttributes(entry, TRUE, fsDatatype, length, 
                                      &indOffset, &varOffset);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }
  
  if (indOffset != -1)
    *(short*)&currRWRSptr[indOffset] = 0;
  
  if (DFS2REC::isAnyCharacter(fsDatatype))
    {
      if (DFS2REC::isAnyVarChar(fsDatatype))
        {
          if (SQL_VARCHAR_HDR_SIZE == sizeof(short))
            *(short*)&currRWRSptr[firstColOffset + varOffset] = strlen(srcPtr);
          else
            *(Lng32*)&currRWRSptr[firstColOffset + varOffset] = strlen(srcPtr);     
          str_cpy_all(&currRWRSptr[firstColOffset + varOffset + SQL_VARCHAR_HDR_SIZE],
                      srcPtr, strlen(srcPtr));
        }
      else
        {
          str_cpy(&currRWRSptr[firstColOffset + varOffset], srcPtr, length, ' ');
        }
    }
  else
    {
      str_cpy_all(&currRWRSptr[firstColOffset + varOffset], srcPtr, length);
    }

  return 0;
}

short CmpSeabaseDDL::updateSeabaseMDTable(
                                         ExeCliInterface *cliInterface,
                                         const char * catName,
                                         const char * schName,
                                         const char * objName,
                                         const ComObjectType & objectType,
                                         const char * validDef, 
                                         ComTdbVirtTableTableInfo * tableInfo,
                                         Lng32 numCols,
                                         const ComTdbVirtTableColumnInfo * colInfo,
                                         Lng32 numKeys,
                                         const ComTdbVirtTableKeyInfo * keyInfo,
                                         Lng32 numIndexes,
                                         const ComTdbVirtTableIndexInfo * indexInfo,
                                         Int64 &inUID,
                                         NABoolean updPrivs)
{
  NABoolean useRWRS = FALSE;
  if (CmpCommon::getDefault(TRAF_USE_RWRS_FOR_MD_INSERT) == DF_ON)
    {
      useRWRS = TRUE;
    }
  Int32 objOwnerID = (tableInfo) ? tableInfo->objOwnerID : SUPER_USER;
  Int32 schemaOwnerID = (tableInfo) ? tableInfo->schemaOwnerID : SUPER_USER;
  Int64 objectFlags = (tableInfo) ? tableInfo->objectFlags : 0;
  Int64 tablesFlags = (tableInfo) ? tableInfo->tablesFlags : 0;
  
  if (updateSeabaseMDObjectsTable(cliInterface,catName,schName,objName,objectType,
                                  validDef,objOwnerID, schemaOwnerID, objectFlags, inUID))
    return -1;
    
  Int64 objUID = inUID;
  
  Lng32 cliRC = 0;

  char buf[4000];

  Lng32 keyLength = 0;
  Lng32 rowDataLength = 0;
  Lng32 rowTotalLength = 0;
  for (Lng32 i = 0; i < numKeys; i++)
    {
      str_sprintf(buf, "upsert into %s.\"%s\".%s values (%ld, '%s', %d, %d, %d, %d, 0)",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_KEYS,
                  objUID,
                  keyInfo->colName, 
                  keyInfo->keySeqNum,
                  keyInfo->tableColNum,
                  keyInfo->ordering,
                  keyInfo->nonKeyCol);
      
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

          return -1;
        }

      const ComTdbVirtTableColumnInfo * ci = &colInfo[keyInfo->tableColNum];
      keyLength += ci->length + (colInfo->nullable ? 2 : 0);
      keyInfo += 1;
    }

  Lng32 rsParamsLen = 0;
  Lng32 inputRowLen = 0;
  Lng32 inputRWRSlen = 0;
  char * inputRWRSptr = NULL;
  char * currRWRSptr = NULL;
  char * inputRow = NULL;
  Lng32 indOffset = 0;
  Lng32 varOffset = 0;
  Lng32 fsDatatype;
  Lng32 length;
  Lng32 entry = 0;
  Int64 rowsAffected = 0;

  ExeCliInterface rwrsCliInterface(STMTHEAP, 0, NULL, 
                                   CmpCommon::context()->sqlSession()->getParentQid());
  if (useRWRS)
    {
      ExeCliInterface cqdCliInterface;
      cliRC = cqdCliInterface.holdAndSetCQD("ODBC_PROCESS", "ON");

      str_sprintf(buf, "upsert using rowset (max rowset size %d, input rowset size ?, input row max length ?, rowset buffer ?) into %s.\"%s\".%s values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                  numCols,
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS);
      cliRC = rwrsCliInterface.rwrsPrepare(buf, numCols);
      if (cliRC < 0)
        {
          rwrsCliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
          
          cliRC = cqdCliInterface.restoreCQD("ODBC_PROCESS");

          return -1;
        }
      
      cliRC = cqdCliInterface.restoreCQD("ODBC_PROCESS");

      // input rowset size
      rsParamsLen = 0;
      rwrsCliInterface.getAttributes(1, TRUE, fsDatatype, length, &indOffset, &varOffset);
      rsParamsLen += length;

      // input row max length
      rwrsCliInterface.getAttributes(2, TRUE, fsDatatype, length, &indOffset, &varOffset);
      rsParamsLen += length;

      // rowwise rowset buffer addr
      rwrsCliInterface.getAttributes(3, TRUE, fsDatatype, length, &indOffset, &varOffset);
      rsParamsLen += length;

      inputRowLen = rwrsCliInterface.inputDatalen();
      inputRWRSlen = inputRowLen * numCols;

      inputRow = new(heap_) char[inputRowLen];
    }

  for (Lng32 i = 0; i < numCols; i++)
    {
      NAString quotedColHeading;
      if (colInfo->colHeading)
        {
          ToQuotedString(quotedColHeading, colInfo->colHeading, FALSE);
        }

      NAString quotedDefVal;
      NAString computedColumnDefinition;
      NABoolean isComputedColumn = FALSE;
      if (colInfo->defVal)
        {
          NAString defVal = colInfo->defVal;
           if (DFS2REC::isAnyCharacter(colInfo->datatype))
            {
              // double quote any quotes within outer quotes
              TrimNAStringSpace(defVal);
              size_t startPos =  defVal.index("'");
              char endChar = defVal.data()[defVal.length()-1];
              if ((startPos >= 0) && (endChar == '\'') && ((defVal.length()-startPos) > 2))
                {
                  NAString innerStr(&defVal.data()[startPos+1], defVal.length() - startPos - 2);
                  NAString innerQuotedStr;
                  ToQuotedString(innerQuotedStr, innerStr, TRUE);
                  
                  NAString defVal2(defVal.data(), startPos);
                  defVal2 += innerQuotedStr;
                  defVal = defVal2;
                }
            }

           if (colInfo->defaultClass == COM_ALWAYS_COMPUTE_COMPUTED_COLUMN_DEFAULT ||
               colInfo->defaultClass == COM_ALWAYS_DEFAULT_COMPUTED_COLUMN_DEFAULT)
             {
               computedColumnDefinition = defVal;
               // quotedDefVal = "";
               isComputedColumn = TRUE;
             }
           else if (useRWRS)
             {
               quotedDefVal = defVal; // outer quotes not needed when inserting using rowsets
             }
           else
             ToQuotedString(quotedDefVal, defVal, FALSE);

        } // colInfo->defVal

      const char *colClassLit = NULL;

      switch (colInfo->columnClass)
        {
        case COM_UNKNOWN_CLASS:
          colClassLit = COM_UNKNOWN_CLASS_LIT;
          break;
        case COM_SYSTEM_COLUMN:
          colClassLit = COM_SYSTEM_COLUMN_LIT;
          break;
        case COM_USER_COLUMN:
          colClassLit = COM_USER_COLUMN_LIT;
          break;
        case COM_ADDED_USER_COLUMN:
          colClassLit = COM_ADDED_USER_COLUMN_LIT;
          break;
        case COM_MV_SYSTEM_ADDED_COLUMN:
          colClassLit = COM_MV_SYSTEM_ADDED_COLUMN_LIT;
          break;
        }

      if (useRWRS)
        {
          Lng32 firstColOffset = 0;
          cliRC = rwrsCliInterface.getAttributes(4, TRUE, fsDatatype, length, 
                                              &indOffset, &firstColOffset);

          entry = 4;
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&objUID, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, colInfo->colName, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->colNumber, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, colClassLit, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->datatype, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, getAnsiTypeStrFromFSType(colInfo->datatype), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->length, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->precision, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->scale, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->dtStart, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->dtEnd, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (colInfo->upshifted ? COM_YES_LIT : COM_NO_LIT), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->hbaseColFlags, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->nullable, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, CharInfo::getCharSetName((CharInfo::CharSet)colInfo->charset), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->defaultClass, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (colInfo->defVal ? quotedDefVal.data() : ""), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow,  (colInfo->colHeading ? quotedColHeading.data() : ""), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (colInfo->hbaseColFam ? colInfo->hbaseColFam : ""), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (colInfo->hbaseColQual ? colInfo->hbaseColQual : ""), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, colInfo->paramDirection, firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (colInfo->isOptional ? COM_YES_LIT : COM_NO_LIT), firstColOffset);
          AssignColEntry(&rwrsCliInterface, entry++, inputRow, (char*)&colInfo->colFlags, firstColOffset);

          cliRC = rwrsCliInterface.rwrsExec(inputRow, inputRowLen, &rowsAffected);
          if (cliRC < 0)
            {
              rwrsCliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
              
              return -1;
            }         
        }
      else
        {
          str_sprintf(buf, "insert into %s.\"%s\".%s values (%ld, '%s', %d, '%s', %d, '%s', %d, %d, %d, %d, %d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %ld)",
                      getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS,
                      objUID,
                      colInfo->colName, 
                      colInfo->colNumber,
                      colClassLit,
                      colInfo->datatype, 
                      getAnsiTypeStrFromFSType(colInfo->datatype),
                      colInfo->length,
                      colInfo->precision, 
                      colInfo->scale, 
                      colInfo->dtStart, 
                      colInfo->dtEnd,
                      (colInfo->upshifted ? "Y" : "N"),
                      colInfo->hbaseColFlags,
                      colInfo->nullable,
                      CharInfo::getCharSetName((CharInfo::CharSet)colInfo->charset),
                      (Lng32)colInfo->defaultClass,
                      (colInfo->defVal ? quotedDefVal.data() : ""),
                      (colInfo->colHeading ? quotedColHeading.data() : ""),
                      colInfo->hbaseColFam ? colInfo->hbaseColFam : "" , 
                      colInfo->hbaseColQual ? colInfo->hbaseColQual : "",
                      colInfo->paramDirection,
                      colInfo->isOptional ? "Y" : "N",
                      colInfo->colFlags);
          
          cliRC = cliInterface->executeImmediate(buf);
          if (cliRC < 0)
            {
              cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
              
              return -1;
            }
        }

      if (isComputedColumn)
        {
          cliRC = updateTextTable(cliInterface,
                                  objUID,
                                  COM_COMPUTED_COL_TEXT,
                                  colInfo->colNumber,
                                  computedColumnDefinition);

          if (cliRC < 0)
            {
              cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

              return -1;
            }
        }

      rowDataLength += colInfo->length + (colInfo->nullable ? 1 : 0);

      // compute HBase cell overhead.
      // For each stored cell/column, overhead is:
      //  timestamp, colFam, colQual, rowKey
      // For aligned format tables, only one cell is stored.
      // The overhead will be computed after exiting the 'for' loop.
      if ((!tableInfo) || 
          (tableInfo->rowFormat != COM_ALIGNED_FORMAT_TYPE))
        {
          rowTotalLength +=  colInfo->length + (colInfo->nullable ? 1 : 0) +
            keyLength +
            sizeof(Int64)/*timestamp*/ +
            (colInfo->hbaseColFam ? strlen(colInfo->hbaseColFam) : strlen(SEABASE_DEFAULT_COL_FAMILY)) +
            (colInfo->hbaseColQual ? strlen(colInfo->hbaseColQual) : 2);
        }

      colInfo += 1;
    } // for

  if (tableInfo && tableInfo->rowFormat == COM_ALIGNED_FORMAT_TYPE)
    {
      // one cell contains the aligned row
      rowTotalLength = rowDataLength + keyLength +
        sizeof(Int64)/*timestamp*/ +
        strlen(SEABASE_DEFAULT_COL_FAMILY) + 2/* 2 bytes for col qual #1*/;
    }

  if (useRWRS)
    {
      cliRC = rwrsCliInterface.rwrsClose();
      if (cliRC < 0)
        {
          rwrsCliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
          
          return -1;
        }
     }

  if (objectType == COM_BASE_TABLE_OBJECT || objectType == COM_INDEX_OBJECT)
    {
      Lng32 isAudited = 1;
      Lng32 numSaltPartns = 0;
      const char * hbaseCreateOptions = NULL;
      char rowFormat[10];
      strcpy(rowFormat, COM_HBASE_FORMAT_LIT);
      if (tableInfo)
        {
          isAudited = tableInfo->isAudited;
          if (tableInfo->rowFormat == COM_ALIGNED_FORMAT_TYPE)
            strcpy(rowFormat, COM_ALIGNED_FORMAT_LIT);
          else if (tableInfo->rowFormat == COM_HBASE_STR_FORMAT_TYPE)
            strcpy(rowFormat, COM_HBASE_STR_FORMAT_LIT);
          numSaltPartns = tableInfo->numSaltPartns;
          hbaseCreateOptions = tableInfo->hbaseCreateOptions;
        }

      str_sprintf(buf, "upsert into %s.\"%s\".%s values (%ld, '%s', '%s', %d, %d, %d, %d, %ld) ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLES,
                  objUID, 
                  rowFormat,
                  (isAudited ? "Y" : "N"),
                  rowDataLength,
                  rowTotalLength,
                  keyLength,
                  numSaltPartns,
                  tablesFlags);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }

      if (hbaseCreateOptions)
        {
          NAString nas(hbaseCreateOptions);
          if (updateTextTable(cliInterface, objUID, COM_HBASE_OPTIONS_TEXT, 0, nas))
            {
              return -1;
            }
        }

    } // BT
  if (objectType == COM_INDEX_OBJECT && numIndexes > 0)
    {
      // this is an index, update the INDEXES table
      ComObjectName baseTableName(indexInfo->baseTableName);
      const NAString catalogNamePart = 
        baseTableName.getCatalogNamePartAsAnsiString();
      const NAString schemaNamePart = 
        baseTableName.getSchemaNamePartAsAnsiString(TRUE);
      const NAString objectNamePart = 
        baseTableName.getObjectNamePartAsAnsiString(TRUE);

      Int64 baseTableUID = 
        getObjectUID(cliInterface,
                     catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(),
                     COM_BASE_TABLE_OBJECT_LIT);
                        
      str_sprintf(buf, "insert into %s.\"%s\".%s values (%ld, %d, %d, %d, %d, %d, %ld, 0) ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_INDEXES,
                  baseTableUID,
                  indexInfo->keytag,
                  indexInfo->isUnique,
                  indexInfo->keyColCount,
                  indexInfo->nonKeyColCount,
                  indexInfo->isExplicit, 
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

          return -1;
        }
    } // is an index

   // Grant owner privileges
  if ((isAuthorizationEnabled()) &&
      (updPrivs))
    {
      NAString fullName (catName);
      fullName += ".";
      fullName += schName;
      fullName += ".";
      fullName += objName;
      if (!insertPrivMgrInfo(objUID,
                             fullName,
                             objectType,
                             objOwnerID,
                             schemaOwnerID,
                             ComUser::getCurrentUser()))
        {
          *CmpCommon::diags()
            << DgSqlCode(-CAT_UNABLE_TO_GRANT_PRIVILEGES)
            << DgTableName(objName);
          return -1;
        }

    }
  return 0;
}

short CmpSeabaseDDL::updateSeabaseMDSPJ(
                                        ExeCliInterface *cliInterface,
                                        const char * catName,
                                        const char * schName,
                                        const char * libName,
                                        const char * libPath,
                                        const Int32 ownerID,
                                        const Int32 schemaOwnerID,
                                        const ComTdbVirtTableRoutineInfo * routineInfo,
                                        Lng32 numCols,
                                        const ComTdbVirtTableColumnInfo * colInfo)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  ComUID libUID;
  libUID.make_UID();
  Int64 libObjUID = libUID.get_value();
  
  Int64 createTime = NA_JulianTimestamp();

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedLibObjName;
  ToQuotedString(quotedLibObjName, NAString(libName), FALSE);

  str_sprintf(buf, "insert into %s.\"%s\".%s values ('%s', '%s', '%s', '%s', %ld, %ld, %ld, '%s', '%s', %d, %d, 0 )",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedLibObjName.data(),
              COM_LIBRARY_OBJECT_LIT,
              libObjUID,
              createTime, 
              createTime,
              COM_YES_LIT,
              COM_NO_LIT,
              ownerID,
              schemaOwnerID);
  cliRC = cliInterface->executeImmediate(buf);
  
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  str_sprintf(buf, "insert into %s.\"%s\".%s values (%ld, '%s', %d, 0)",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES,
              libObjUID, libPath, routineInfo->library_version);
  
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  NAString catalogNamePart(getSystemCatalog());
  NAString schemaNamePart;
  ToQuotedString(schemaNamePart, NAString(SEABASE_MD_SCHEMA), FALSE);
  NAString quotedSpjObjName;
  ToQuotedString(quotedSpjObjName, NAString(routineInfo->routine_name), FALSE);
  Int64 objUID = -1;

  ComTdbVirtTableTableInfo * tableInfo = new(STMTHEAP) ComTdbVirtTableTableInfo[1];
  tableInfo->tableName = NULL,
  tableInfo->createTime = 0;
  tableInfo->redefTime = 0;
  tableInfo->objUID = 0;
  tableInfo->objOwnerID = ownerID;
  tableInfo->schemaOwnerID = schemaOwnerID;
  tableInfo->isAudited = 1;
  tableInfo->validDef = 1;
  tableInfo->hbaseCreateOptions = NULL;
  tableInfo->numSaltPartns = 0;
  tableInfo->rowFormat = COM_UNKNOWN_FORMAT_TYPE;
  tableInfo->objectFlags = 0;

  if (updateSeabaseMDTable(cliInterface, 
                           catalogNamePart, schemaNamePart, quotedSpjObjName,
                           COM_USER_DEFINED_ROUTINE_OBJECT,
                           "Y",
                           tableInfo,
                           numCols,
                           colInfo,
                           0, NULL,
                           0, NULL, 
                           objUID))
    {
      return -1;
    }

  Int64 spjObjUID = getObjectUID(cliInterface, 
                           catalogNamePart, schemaNamePart, quotedSpjObjName,
                           COM_USER_DEFINED_ROUTINE_OBJECT_LIT);
  if (spjObjUID == -1)
    return -1;
                                 

  str_sprintf(buf, "insert into %s.\"%s\".%s values (%ld, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', %ld, '%s', 0 )",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_ROUTINES,
              spjObjUID,
              routineInfo->UDR_type,
              routineInfo->language_type,
              routineInfo->deterministic ? "Y" : "N" ,
              routineInfo->sql_access,
              routineInfo->call_on_null ? "Y" : "N" ,
              routineInfo->isolate ? "Y" : "N" ,
              routineInfo->param_style,
              routineInfo->transaction_attributes,
              routineInfo->max_results,
              routineInfo->state_area_size,
              routineInfo->external_name,
              routineInfo->parallelism,
              routineInfo->user_version,
              routineInfo->external_security,
              routineInfo->execution_mode,
              libObjUID,
              routineInfo->signature);

  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  str_sprintf(buf, "insert into %s.\"%s\".%s values (%ld, %ld, 0)",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES_USAGE,
              libObjUID, spjObjUID);

  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  return 0;

}


short CmpSeabaseDDL::deleteFromSeabaseMDTable(
                                              ExeCliInterface *cliInterface,
                                              const char * catName,
                                              const char * schName,
                                              const char * objName,
                                              const ComObjectType objType)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];
  char objectTypeLit[3] = {0};
  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objType),2);
  Int64 objUID = getObjectUID(cliInterface, catName, schName, objName, objectTypeLit);

  if (objUID < 0)
     return -1;

  cliRC = deleteFromSeabaseMDObjectsTable(cliInterface,
                                          catName, schName, objName,
                                          objType);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  if (objType == COM_LIBRARY_OBJECT) 
    {
      str_sprintf(buf, "delete from %s.\"%s\".%s where library_uid = %ld",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }

      // delete comment from TEXT table for library
      str_sprintf(buf, "delete from %s.\"%s\".%s where text_uid = %ld",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TEXT,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
        
          return -1;
        }

      return 0; // nothing else to do for libraries
    }
  
  if (objType == COM_SEQUENCE_GENERATOR_OBJECT) 
    {
      str_sprintf(buf, "delete from %s.\"%s\".%s where seq_uid = %ld",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_SEQ_GEN,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
    }
  
  str_sprintf(buf, "delete from %s.\"%s\".%s where object_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_COLUMNS,
              objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  // delete data from TEXT table
  str_sprintf(buf, "delete from %s.\"%s\".%s where text_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TEXT,
              objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
    
      return -1;
    }

  if (objType == COM_USER_DEFINED_ROUTINE_OBJECT)
  {
    str_sprintf(buf, "delete from %s.\"%s\".%s where udr_uid = %ld",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_ROUTINES,
                objUID);
    cliRC = cliInterface->executeImmediate(buf);
    if (cliRC < 0)
      {
        cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
        return -1;
      }
    str_sprintf(buf, "delete from %s.\"%s\".%s where used_udr_uid = %ld",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES_USAGE,
                objUID);
    cliRC = cliInterface->executeImmediate(buf);
    if (cliRC < 0)
      {
        cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
        return -1;
      }
    return 0;  // nothing else to do for routines
  }

  str_sprintf(buf, "delete from %s.\"%s\".%s where object_uid = %ld ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_KEYS,
              objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %ld ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLES,
              objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  if (objType == COM_INDEX_OBJECT)
    {
      str_sprintf(buf, "delete from %s.\"%s\".%s where index_uid = %ld ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_INDEXES,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

          return -1;
        }
    }

  if (objType == COM_VIEW_OBJECT)
    {
      str_sprintf(buf, "delete from %s.\"%s\".%s where view_uid  = %ld ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

          return -1;
        }

      str_sprintf(buf, "delete from %s.\"%s\".%s where using_view_uid  = %ld ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE,
                  objUID);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

          return -1;
        }
    }

   return 0;
}

short CmpSeabaseDDL::deleteConstraintInfoFromSeabaseMDTables(
                                              ExeCliInterface *cliInterface,
                                              Int64 tableUID,
                                              Int64 otherTableUID, // valid for ref constrs
                                              Int64 constrUID,
                                              Int64 otherConstrUID, // valid for ref constrs
                                              const char * constrCatName,
                                              const char * constrSchName,
                                              const char * constrObjName,
                                              const ComObjectType constrType)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  if (deleteFromSeabaseMDTable(cliInterface, 
                               constrCatName, constrSchName, constrObjName, 
                               constrType))
    return -1;
  
  // delete data from table constraints MD
  str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid  = %ld and constraint_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLE_CONSTRAINTS,
              tableUID, constrUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }
  
  // delete data from ref constraints MD
  str_sprintf(buf, "delete from %s.\"%s\".%s where ref_constraint_uid  = %ld and unique_constraint_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_REF_CONSTRAINTS,
              constrUID, otherConstrUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }

  // delete data from unique ref constraints usage MD
  str_sprintf(buf, "delete from %s.\"%s\".%s where unique_constraint_uid = %ld and foreign_constraint_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_UNIQUE_REF_CONSTR_USAGE,
              otherConstrUID, constrUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }

  // delete data from TEXT table
  str_sprintf(buf, "delete from %s.\"%s\".%s where text_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TEXT,
              constrUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }
  
  return 0;
}

short CmpSeabaseDDL::checkAndGetStoredObjectDesc(
     ExeCliInterface *cliInterface,
     Int64 objUID,
     TrafDesc* *retDesc)
{
  Lng32 cliRC = 0;

  NAString packedDesc;
  cliRC = getTextFromMD(
       cliInterface, objUID, COM_STORED_DESC_TEXT, 0, packedDesc, TRUE);
  if (cliRC < 0)
    {
      *CmpCommon::diags() << DgSqlCode(-4493)
                          << DgString0("Error reading from metadata.");
      
      processReturn();
      return -1;
    }
  
  if (packedDesc.length() == 0)
    {
      // stored desc doesn't exist
      *CmpCommon::diags() << DgSqlCode(-4493)
                          << DgString0("Does not exist. It needs to be regenerated.");
      
      processReturn();
      return -2;
    }
  
  char * descBuf = new(STMTHEAP) char[packedDesc.length()];
  str_cpy_all(descBuf, packedDesc.data(), packedDesc.length());
  
  TrafDesc * desc = (TrafDesc*)descBuf;
  TrafDesc dummyDesc;
  desc = (TrafDesc*)desc->driveUnpack((void*)desc, &dummyDesc, NULL);
  
  if (! desc)
    {
      NADELETEBASIC(descBuf, STMTHEAP);

      // error during unpack. Desc need to be regenerated.
      *CmpCommon::diags() << DgSqlCode(-4493)
                          << DgString0("Error during unpacking due to change in stored structures. It needs to be regenerated.");
      
      processReturn();
      return -3;
    }
  
  // all good
  *CmpCommon::diags() << DgSqlCode(4493)
                      << DgString0("Uptodate and current.");

  if (retDesc)
    *retDesc = desc;
  else
    NADELETEBASIC(descBuf, STMTHEAP);

  return 0;
}

// rt = -1, generate redef time. rt = -2, dont update redef time.
// otherwise use provided redef time.
//
// Also generate and update object descriptor in metadata.
short CmpSeabaseDDL::updateObjectRedefTime(
                                         ExeCliInterface *cliInterface,
                                         const NAString &catName,
                                         const NAString &schName,
                                         const NAString &objName,
                                         const char * objType,
                                         Int64 rt,
                                         Int64 objUID,
                                         NABoolean force)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  char buf[4000];

  Int64 redefTime = ((rt == -1) ? NA_JulianTimestamp() : rt);

  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  Int64 flags = 0;
  if (((CmpCommon::getDefault(TRAF_STORE_OBJECT_DESC) == DF_ON) ||
       (force)) &&
      (objUID > 0) &&
      (NOT isSeabaseReservedSchema(catName, schName)) &&
      ((strcmp(objType, COM_BASE_TABLE_OBJECT_LIT) == 0) ||
       (strcmp(objType, COM_VIEW_OBJECT_LIT) == 0)))
    {
      Int32 ctlFlags = GEN_PACKED_DESC | GET_SNAPSHOTS;
      Int32 packedDescLen = 0;
      TrafDesc * ds = 
        getSeabaseUserTableDesc(catName, schName, objName,
                                (strcmp(objType, COM_BASE_TABLE_OBJECT_LIT) == 0
                                 ? COM_BASE_TABLE_OBJECT : COM_VIEW_OBJECT),
                                FALSE, ctlFlags, packedDescLen);
      if (! ds)
        {
          processReturn();
          return -1;
        }

      cliRC = updateTextTableWithBinaryData
        (cliInterface, objUID, 
         COM_STORED_DESC_TEXT, 0,
         (char*)ds, packedDescLen, 
         TRUE /*delete existing data*/);
      if (cliRC < 0)
        {
          processReturn();
          return -1;
        }
      
      CmpSeabaseDDL::setMDflags(flags, MD_OBJECTS_STORED_DESC);
    }

  buf[0] = 0;
  if ((flags & MD_OBJECTS_STORED_DESC) != 0)
    {
      if (rt == -2)
        str_sprintf(buf, "update %s.\"%s\".%s set flags = bitor(flags, %ld) where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' ", 
                    getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                    flags,
                    catName.data(), quotedSchName.data(), quotedObjName.data(),
                    objType);
      else
        str_sprintf(buf, "update %s.\"%s\".%s set redef_time = %ld, flags = bitor(flags, %ld) where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' ",
                    getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                    redefTime,
                    flags,
                    catName.data(), quotedSchName.data(), quotedObjName.data(),
                    objType);
    }
  else if (rt != -2)
    {
      str_sprintf(buf, "update %s.\"%s\".%s set redef_time = %ld where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' ",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                  redefTime,
                  catName.data(), quotedSchName.data(), quotedObjName.data(),
                  objType);
    }

  if (strlen(buf) > 0)
    {
      cliRC = cliInterface->executeImmediate(buf);
      
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
    }

  return 0;
}

short CmpSeabaseDDL::updateObjectValidDef(
                                           ExeCliInterface *cliInterface,
                                           const char * catName,
                                           const char * schName,
                                           const char * objName,
                                           const char * objType,
                                           const char * validDef)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  
  char buf[4000];
  
  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  str_sprintf(buf, "update %s.\"%s\".%s set valid_def = '%s' where catalog_name = '%s' and schema_name = '%s' and object_name = '%s' and object_type = '%s' ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              validDef,
              catName, quotedSchName.data(), quotedObjName.data(),
              objType);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  return 0;
}

short CmpSeabaseDDL::updateObjectName(
                                           ExeCliInterface *cliInterface,
                                           Int64 objUID,
                                           const char * catName,
                                           const char * schName,
                                           const char * objName)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  
  char buf[4000];
  
  NAString quotedSchName;
  ToQuotedString(quotedSchName, NAString(schName), FALSE);
  NAString quotedObjName;
  ToQuotedString(quotedObjName, NAString(objName), FALSE);

  str_sprintf(buf, "update %s.\"%s\".%s set catalog_name = '%s', schema_name = '%s', object_name = '%s' where object_uid = %ld ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catName, quotedSchName.data(), quotedObjName.data(),
              objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  return 0;
}

short CmpSeabaseDDL::updateObjectAuditAttr(
                                           ExeCliInterface *cliInterface,
                                           const char * catName,
                                           const char * schName,
                                           const char * objName,
                                           NABoolean audited,
                                           const NAString &objType)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  
  char buf[4000];
  
  Int64 objectUID = getObjectUID(cliInterface, catName, schName, objName, objType);
  
  if (objectUID < 0)
     return -1;
  str_sprintf(buf, "update %s.\"%s\".%s set is_audited = '%s' where  table_uid = %ld ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TABLES,
              (audited ? "Y" : "N"),
              objectUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());

      return -1;
    }

  return 0;
}

short CmpSeabaseDDL::updateObjectFlags(
     ExeCliInterface *cliInterface,
     const Int64 objUID,
     const Int64 inFlags,
     NABoolean reset)
{
  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  
  char buf[4000];
  
  Int64 flags = inFlags;
  if (reset)
    flags = ~inFlags;

  if (reset)
    str_sprintf(buf, "update %s.\"%s\".%s set flags = bitand(flags, %ld) where object_uid = %ld",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                flags, objUID);
  else
    str_sprintf(buf, "update %s.\"%s\".%s set flags = bitor(flags, %ld) where object_uid = %ld",
                getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
                flags, objUID);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      
      return -1;
    }
  
  return 0;
}

void CmpSeabaseDDL::cleanupObjectAfterError(
                                            ExeCliInterface &cliInterface,
                                            const NAString &catName, 
                                            const NAString &schName,
                                            const NAString &objName,
                                            const ComObjectType objectType,
                                            NABoolean dontForceCleanup)
{

  //if ddlXns are being used, no need of additional cleanup.
  //transactional rollback will take care of cleanup.
  if (dontForceCleanup)
    return;
    
  Lng32 cliRC = 0;
  char buf[1000];

  // save current diags area
  ComDiagsArea * tempDiags = ComDiagsArea::allocate(heap_);
  tempDiags->mergeAfter(*CmpCommon::diags());
  
  CmpCommon::diags()->clear();
  if (objectType == COM_BASE_TABLE_OBJECT)
    str_sprintf(buf, "cleanup table \"%s\".\"%s\".\"%s\" ",
                catName.data(), schName.data(), objName.data());
  else if (objectType == COM_INDEX_OBJECT)
    str_sprintf(buf, "cleanup index \"%s\".\"%s\".\"%s\" ",
                catName.data(), schName.data(), objName.data());
  else 
    str_sprintf(buf, "cleanup object \"%s\".\"%s\".\"%s\" ",
                catName.data(), schName.data(), objName.data());
    
  cliRC = cliInterface.executeImmediate(buf);
  CmpCommon::diags()->clear();
  CmpCommon::diags()->mergeAfter(*tempDiags);

  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
    }

  tempDiags->clear();
  tempDiags->deAllocate();

  return;
}

void CmpSeabaseDDL::purgedataObjectAfterError(
                                            ExeCliInterface &cliInterface,
                                            const NAString &catName, 
                                            const NAString &schName,
                                            const NAString &objName,
                                            const ComObjectType objectType,
                                            NABoolean dontForceCleanup)
{

  //if ddlXns are being used, no need of additional cleanup.
  //transactional rollback will take care of cleanup.
  if (dontForceCleanup)
    return;

  PushAndSetSqlParserFlags savedParserFlags(INTERNAL_QUERY_FROM_EXEUTIL);
    
  Lng32 cliRC = 0;
  char buf[1000];

  // save current diags area
  ComDiagsArea * tempDiags = ComDiagsArea::allocate(heap_);
  tempDiags->mergeAfter(*CmpCommon::diags());
  
  CmpCommon::diags()->clear();
  if (objectType == COM_BASE_TABLE_OBJECT)
    str_sprintf(buf, "purgedata \"%s\".\"%s\".\"%s\" ",
                catName.data(), schName.data(), objName.data());
  else if (objectType == COM_INDEX_OBJECT)
    str_sprintf(buf, "purgedata table(index_table \"%s\".\"%s\".\"%s\" ) ",
                catName.data(), schName.data(), objName.data());
  else 
    ex_assert(0, "purgedata object is not supported");
    
  cliRC = cliInterface.executeImmediate(buf);
  CmpCommon::diags()->clear();
  CmpCommon::diags()->mergeAfter(*tempDiags);

  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
    }

  tempDiags->clear();
  tempDiags->deAllocate();

  return;
}


// user created traf stored col fam is of the form:  #<1-byte-num>
//  1-byte-num is character '2' through '9', or 'a' through 'x'.
// This allows for 32 column families and
// is the index of user specified col family stored in naTable.allColFam().
//
// Family "#1" is reserved for system default column family name. This is also
// the name that was used priori to multi-col fam support.
short CmpSeabaseDDL::genTrafColFam(int index, NAString &trafColFamily)
{
  trafColFamily = "#";
  unsigned char v;
  
  if (index >= 0 && index <= 7)
    v = (unsigned char)('2' + index);
  else if (index >= 8 && index <= 32)
    v = (unsigned char)('a' + (index - 8));
  else
    return -1; // error
  
  trafColFamily.append((char*)&v, 1);

  return 0;
}

short CmpSeabaseDDL::extractTrafColFam(const NAString &trafColFam, int &index)
{
  unsigned char v = (unsigned char)trafColFam.data()[1];
  index = 0;
  if (v >= '2' && v <= '9')
    index = v - '2';
  else if (v >= 'a' && v <= 'x')
    index = ((v - 'a') + 8);
  else
    return -1;
 
  return 0;
}

// inColFamily:       user specified column family
// trafColFamily:     col fam stored in traf tables 
// userColFamVec:  unique array of user col families
// trafColFamVec:   unique array of traf col families 
short CmpSeabaseDDL::processColFamily(NAString &inColFamily,
                                      NAString &trafColFamily,
                                      std::vector<NAString> *userColFamVec,
                                      std::vector<NAString> *trafColFamVec)
{
  if (inColFamily.isNull())
    return 0;
  
  if (! userColFamVec)
    {
      trafColFamily = inColFamily;
      return 0;
    }

  int i = 0;
  NABoolean found = FALSE;
  while ((NOT found) && (i < userColFamVec->size()))
    {
      NAString &nas = (*userColFamVec)[i];
      if (nas == inColFamily)
        {
          found = TRUE;
        }
      else
        i++;
    }

  // add this user col fam to user fam array if not already there.
  if (NOT found)
    {
      userColFamVec->push_back(inColFamily);
    }

  if (inColFamily == SEABASE_DEFAULT_COL_FAMILY)
    trafColFamily = SEABASE_DEFAULT_COL_FAMILY;
  else
    {
      genTrafColFam(i, trafColFamily);
    }

  if (trafColFamVec)
    {
      found = FALSE;
      i = 0;
      while ((NOT found) && (i < trafColFamVec->size()))
        {
          NAString &nas = (*trafColFamVec)[i];
          if (nas == trafColFamily)
            {
              found = TRUE;
            }
          else
            i++;
        }

      if (not found)
        trafColFamVec->push_back(trafColFamily);
    }

  return 0;
}

short CmpSeabaseDDL::buildColInfoArray(
                                       ComObjectType objType,
                                       NABoolean isMetadataHistOrReposObject,
                                       ElemDDLColDefArray *colArray,
                                       ComTdbVirtTableColumnInfo * colInfoArray,
                                       NABoolean implicitPK,
                                       NABoolean alignedFormat,
                                       Lng32 *identityColPos, // IN_OUT
                                       std::vector<NAString> *userColFamVec, // IN_OUT
                                       std::vector<NAString> *trafColFamVec, // IN_OUT
                                       const char * inColFam, // IN
                                       NAMemory * heap)
{
  std::vector<NAString> myvector;

  if (identityColPos)
    *identityColPos = -1;

  NAString defaultColFam = (inColFam ? inColFam : SEABASE_DEFAULT_COL_FAMILY);

  NABoolean nullColFamFound = FALSE;
  size_t index = 0;
  for (index = 0; index < colArray->entries(); index++)
    {
      ElemDDLColDef *colNode = (*colArray)[index];
      
      NAString colFamily;
      NAString colName;
      Lng32 datatype, length, precision, scale, dt_start, dt_end, nullable, upshifted;
      ComColumnClass colClass;
      ComColumnDefaultClass defaultClass;
      NAString charset, defVal;
      NAString heading;
      ULng32 hbaseColFlags;
      Int64 colFlags;
      LobsStorage lobStorage;
      if (getColInfo(colNode,
                     isMetadataHistOrReposObject,
                     colFamily,
                     colName,
                     alignedFormat,
                     datatype, length, precision, scale, dt_start, dt_end, upshifted, nullable,
                     charset, colClass, defaultClass, defVal, heading, lobStorage, hbaseColFlags, colFlags))
        return -1;

      colInfoArray[index].hbaseColFlags = hbaseColFlags;
      
      char * col_name = new((heap ? heap : STMTHEAP)) char[colName.length() + 1];
      strcpy(col_name, (char*)colName.data());

      myvector.push_back(col_name);

      colInfoArray[index].colName = col_name;
      colInfoArray[index].colNumber = index;
      colInfoArray[index].columnClass = colClass;
      colInfoArray[index].datatype = datatype;
      colInfoArray[index].length = length;
      colInfoArray[index].nullable = nullable;
      colInfoArray[index].charset = (SQLCHARSET_CODE)CharInfo::getCharSetEnum(charset); 
      
      colInfoArray[index].precision = precision;
      colInfoArray[index].scale = scale;
      colInfoArray[index].dtStart = dt_start;
      colInfoArray[index].dtEnd = dt_end;
      colInfoArray[index].upshifted = upshifted;
      colInfoArray[index].defaultClass = defaultClass;
      colInfoArray[index].defVal = NULL;

      if (defVal.length() > 0)
        {
          char * def_val = new((heap ? heap : STMTHEAP)) char[defVal.length() +1];
          str_cpy_all(def_val, (char*)defVal.data(), defVal.length());
          def_val[defVal.length()] = 0;
          colInfoArray[index].defVal = def_val;
        }

      if ((identityColPos) &&
          ((defaultClass == COM_IDENTITY_GENERATED_BY_DEFAULT) ||
           (defaultClass == COM_IDENTITY_GENERATED_ALWAYS)))
        {
          if ((objType == COM_BASE_TABLE_OBJECT) &&
              (*identityColPos >= 0)) // previously found
            {
              // cannot have more than one identity cols
              *CmpCommon::diags() << DgSqlCode(-1511);
              return -1;
            }

          *identityColPos = index;
        }

      colInfoArray[index].colHeading = NULL;
      if (heading.length() > 0)
        {
          char * head_val = new((heap ? heap : STMTHEAP)) char[heading.length() +1];
          str_cpy_all(head_val, (char*)heading.data(), heading.length());
          head_val[heading.length()] = 0;
          colInfoArray[index].colHeading = head_val;
        }

      if (colFamily.isNull())
        {
          colFamily = defaultColFam;

          nullColFamFound = TRUE;
        }
      else 
        {
          if (alignedFormat)
            {
              *CmpCommon::diags() << DgSqlCode(-4223)
                                  << DgString0("Column Family specification on columns of an aligned format table is");
              return -1;
            }
        }

      NAString storedColFamily;
      processColFamily(colFamily, storedColFamily, userColFamVec, trafColFamVec);

      colInfoArray[index].hbaseColFam = 
        new((heap ? heap : STMTHEAP)) char[storedColFamily.length() +1];
      strcpy((char*)colInfoArray[index].hbaseColFam, (char*)storedColFamily.data());

      char idxNumStr[40];
      str_itoa(index+1, idxNumStr);

      colInfoArray[index].hbaseColQual =
        new((heap ? heap : STMTHEAP)) char[strlen(idxNumStr) + 1];
      strcpy((char*)colInfoArray[index].hbaseColQual, idxNumStr);

      strcpy(colInfoArray[index].paramDirection, COM_UNKNOWN_PARAM_DIRECTION_LIT);
      colInfoArray[index].isOptional = FALSE;
      colInfoArray[index].colFlags = colFlags;
    }
  
  if ((objType == COM_BASE_TABLE_OBJECT) ||
      (objType == COM_VIEW_OBJECT))
    {
      // find duplicate colname references. If found, return error and first dup colname.
      std::sort (myvector.begin(), myvector.end()); 
      std::vector<NAString>::iterator it = adjacent_find(myvector.begin(), myvector.end());
      if (it != myvector.end())
        {
          *CmpCommon::diags() << DgSqlCode(-1080)
                              << DgColumnName(*it);
          return -1;
        }
    }

  if (userColFamVec && (userColFamVec->size() > 32))
    {
      *CmpCommon::diags() << DgSqlCode(-4225);

      return -1;
    }

  return 0;
}

short CmpSeabaseDDL::buildColInfoArray(
                                       ElemDDLParamDefArray *paramArray,
                                       ComTdbVirtTableColumnInfo * colInfoArray
                                       )
{
  size_t index = 0;
  for (index = 0; index < paramArray->entries(); index++)
    {
      ElemDDLParamDef *paramNode = (*paramArray)[index];
      ElemDDLColDef colNode(NULL, &paramNode->getParamName(), 
                            paramNode->getParamDataType(),
                            NULL, STMTHEAP);

      NAString colFamily;
      NAString colName;
      Lng32 datatype, length, precision, scale, dt_start, dt_end, nullable, upshifted;
      ComColumnClass colClass;
      ComColumnDefaultClass defaultClass;
      NAString charset, defVal;
      NAString heading;
      ULng32 hbaseColFlags;
      Int64 colFlags;
      LobsStorage lobStorage;
      if (getColInfo(&colNode,
                     FALSE,
                     colFamily,
                     colName,
                     FALSE,
                     datatype, length, precision, scale, dt_start, dt_end, 
                     upshifted, nullable, charset, colClass, defaultClass, defVal, 
                     heading, lobStorage, hbaseColFlags, colFlags))
        return -1;

      colInfoArray[index].hbaseColFlags = hbaseColFlags;
      
      char * col_name = NULL;
      if (colName.length() == 0) {
        char idxNumStr[10];
        idxNumStr[0] = '#' ;
        idxNumStr[1] = ':' ;
        str_itoa(index, &(idxNumStr[2]));
        col_name = new(STMTHEAP) char[strlen(idxNumStr) + 1];
        strcpy(col_name, idxNumStr);
      }
      else {
        col_name = new(STMTHEAP) char[colName.length() + 1];
        strcpy(col_name, (char*)colName.data());
      }

      colInfoArray[index].colName = col_name;
      colInfoArray[index].colNumber = index;
      colInfoArray[index].columnClass = colClass;
      colInfoArray[index].datatype = datatype;
      colInfoArray[index].length = length;
      colInfoArray[index].nullable = nullable;
      colInfoArray[index].charset = (SQLCHARSET_CODE)
        CharInfo::getCharSetEnum(charset); 
      colInfoArray[index].precision = precision;
      colInfoArray[index].scale = scale;
      colInfoArray[index].dtStart = dt_start;
      colInfoArray[index].dtEnd = dt_end;
      colInfoArray[index].upshifted = upshifted;
      colInfoArray[index].defaultClass = defaultClass;
      colInfoArray[index].defVal = NULL;
      colInfoArray[index].colHeading = NULL;
      colInfoArray[index].hbaseColFam = NULL;
      colInfoArray[index].hbaseColQual = NULL;
      
      if (paramNode->getParamDirection() == COM_INPUT_PARAM)
        strcpy(colInfoArray[index].paramDirection, COM_INPUT_PARAM_LIT);
      else if (paramNode->getParamDirection() == COM_OUTPUT_PARAM)
        strcpy(colInfoArray[index].paramDirection, COM_OUTPUT_PARAM_LIT);
      else if (paramNode->getParamDirection() == COM_INOUT_PARAM)
        strcpy(colInfoArray[index].paramDirection, COM_INOUT_PARAM_LIT);
      else
        strcpy(colInfoArray[index].paramDirection, 
               COM_UNKNOWN_PARAM_DIRECTION_LIT);

      colInfoArray[index].isOptional = 0; // Aways FALSE for now
      colInfoArray[index].colFlags = colFlags;
    }

  return 0;
}

short CmpSeabaseDDL::buildKeyInfoArray(
                                       ElemDDLColDefArray *colArray,
                                       NAColumnArray * nacolArray,
                                       ElemDDLColRefArray *keyArray,
                                       ComTdbVirtTableColumnInfo * colInfoArray,
                                       ComTdbVirtTableKeyInfo * keyInfoArray,
                                       NABoolean allowNullableUniqueConstr,
                                       Lng32 *keyLength,
                                       NAMemory * heap)
{
  if (keyLength)
    *keyLength = 0;

  size_t index = 0;
  for ( index = 0; index < keyArray->entries(); index++)
    {
      char * col_name = new((heap ? heap : STMTHEAP)) 
        char[strlen((*keyArray)[index]->getColumnName()) + 1];
      strcpy(col_name, (*keyArray)[index]->getColumnName());

      keyInfoArray[index].colName = col_name; //(*keyArray)[index]->getColumnName();

      keyInfoArray[index].keySeqNum = index+1;

      if ((! colArray) && (! nacolArray))
        {
          // this col doesn't exist. Return error.
          *CmpCommon::diags() << DgSqlCode(-1009)
                              << DgColumnName(keyInfoArray[index].colName);
          
          return -1;
        }
 
      NAString nas((*keyArray)[index]->getColumnName());
      keyInfoArray[index].tableColNum = (Lng32)
        (colArray ?
         colArray->getColumnIndex((*keyArray)[index]->getColumnName()) :
         nacolArray->getColumnPosition(nas));

      if (keyInfoArray[index].tableColNum == -1)
        {
          // this col doesn't exist. Return error.
          *CmpCommon::diags() << DgSqlCode(-1009)
                              << DgColumnName(keyInfoArray[index].colName);
          
          return -1;
        }
        
      keyInfoArray[index].ordering = 
        ((*keyArray)[index]->getColumnOrdering() == COM_ASCENDING_ORDER ? 
          ComTdbVirtTableKeyInfo::ASCENDING_ORDERING : 
          ComTdbVirtTableKeyInfo::DESCENDING_ORDERING);
      keyInfoArray[index].nonKeyCol = 0;

      if ((colInfoArray) &&
          (colInfoArray[keyInfoArray[index].tableColNum].nullable != 0) &&
          (NOT allowNullableUniqueConstr))
        {
          *CmpCommon::diags() << DgSqlCode(-CAT_CLUSTERING_KEY_COL_MUST_BE_NOT_NULL_NOT_DROP)
                              << DgColumnName(keyInfoArray[index].colName);
          
          return -1;
        }

      keyInfoArray[index].hbaseColFam = NULL;
      keyInfoArray[index].hbaseColQual = NULL;

      if (keyLength)
        {
          NAType *colType = 
            (*colArray)[keyInfoArray[index].tableColNum]->getColumnDataType();
          *keyLength += colType->getEncodedKeyLength();
        }
    }

  return 0;
}

// subID: 0, for text that belongs to table. colNumber, for column based text.
short CmpSeabaseDDL::updateTextTable(ExeCliInterface *cliInterface,
                                     Int64 objUID, 
                                     ComTextType textType, 
                                     Lng32 subID, 
                                     NAString &textInputData,
                                     char * binaryInputData,
                                     Lng32 binaryInputDataLen,
                                     NABoolean withDelete)
{
  Lng32 cliRC = 0;
  if (withDelete)
    {
      // Note: It might be tempting to try an upsert instead of a
      // delete followed by an insert, but this won't work. It is
      // possible that the metadata text could shrink and take fewer
      // rows in its new form than the old. So we do the simple thing
      // to avoid such complications.
       cliRC = deleteFromTextTable(cliInterface, objUID, textType, subID);
      if (cliRC < 0)
        {
          return -1;
        }
    }

  char * dataToInsert = NULL;
  Lng32 dataLen = -1;
  if (binaryInputData)
    {
      Lng32 encodedMaxLen = str_encoded_len(binaryInputDataLen);
      char * encodedData = new(STMTHEAP) char[encodedMaxLen];
      Lng32 encodedLen = 
        str_encode(encodedData, encodedMaxLen, binaryInputData, binaryInputDataLen);

      dataToInsert = encodedData;
      dataLen =  encodedLen;
    }
  else
    {
      dataToInsert = (char*)textInputData.data();
      dataLen =  textInputData.length();
    }

  Int32 maxLen = TEXTLEN;
  char queryBuf[1000];
  Lng32 numRows = ((dataLen -1) / maxLen) + 1;
  Lng32 currPos = 0;
  Lng32 currDataLen = 0;

  for (Lng32 i = 0; i < numRows; i++)
    {
      if (i < numRows-1)
        currDataLen = maxLen;
      else
        currDataLen = dataLen - currPos;

      str_sprintf(queryBuf, "insert into %s.\"%s\".%s values (%ld, %d, %d, %d, 0, cast(? as char(%d bytes) not null))",
                  getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TEXT,
                  objUID,
                  textType,
                  subID,
                  i,
                  currDataLen);
      cliRC = cliInterface->executeImmediateCEFC
        (queryBuf, &dataToInsert[currPos], currDataLen, NULL, NULL, NULL);
      
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }

      currPos += maxLen;
    }

  return 0;
}

short CmpSeabaseDDL::updateTextTableWithBinaryData
(ExeCliInterface *cliInterface,
 Int64 objUID, 
 ComTextType textType, 
 Lng32 subID, 
 char * inputData,
 Int32 inputDataLen,
 NABoolean withDelete)
{
  NAString dummy;
  return updateTextTable(cliInterface, objUID, textType, subID, dummy,
                         inputData, inputDataLen, withDelete);
}

short CmpSeabaseDDL::deleteFromTextTable(ExeCliInterface *cliInterface,
                                         Int64 objUID, 
                                         ComTextType textType, 
                                         Lng32 subID)
{
  Lng32 cliRC = 0;

  char buf[1000];
  str_sprintf(buf, "delete from %s.\"%s\".%s where text_uid = %ld and text_type = %d and sub_id = %d",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_TEXT,
              objUID, static_cast<int>(textType), subID);
  cliRC = cliInterface->executeImmediate(buf);
  
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  return 0;
}

ItemExpr *CmpSeabaseDDL::bindDivisionExprAtDDLTime(ItemExpr *expr,
                                                   NAColumnArray *availableCols,
                                                   NAHeap *heap)
{
  // This doesn't fully "bind" the ItemExpr like ItemExpr::bindNode() would do it.
  // Instead, it will find column references in the expression, validate that they
  // refer to columns passed in as available columns and replace them with
  // NamedTypeToItem ItemExprs that contain the column name and the type. This
  // will allow us to do type synthesis for this expression later. We can
  // also unparse the expression but the result isn't any good for any other
  // purpose.

  ItemExpr *retval = expr;
  CollIndex nc = expr->getArity();

  // call the method recursively on the children, this may modify the
  // expression passed in
  for (CollIndex c=0; c<nc; c++)
    {
      ItemExpr *boundChild =
        bindDivisionExprAtDDLTime(expr->child(c), availableCols, heap);

      if (boundChild)
        expr->child(c) = boundChild;
      else
        retval = NULL;
    }

  if (retval)
    switch (expr->getOperatorType())
      {
      case ITM_REFERENCE:
        {
          const NAType *colType = NULL;
          const NAString &colName = ((ColReference *) expr)->getColRefNameObj().getColName();

          // look up column name and column type in availableCols
          for (CollIndex c=0; c<availableCols->entries() && colType == NULL; c++)
            if (colName == (*availableCols)[c]->getColName())
              colType = (*availableCols)[c]->getType();

          if (colType)
            {
              retval = new(heap) NamedTypeToItem(colName.data(),
                                                 colType->newCopy(heap),
                                                 heap);
            }
          else
            {
              // column not found
              NAString unparsed;
              expr->unparse(unparsed, PARSER_PHASE, COMPUTED_COLUMN_FORMAT);
              *CmpCommon::diags() << DgSqlCode(-4240)
                                  << DgString0(unparsed);
              retval = NULL;
            }
        }
        break;

      case ITM_NAMED_TYPE_TO_ITEM:
      case ITM_CONSTANT:
        // these are leaf operators that are allowed without further check
        break;

      default:
        // we want to control explicitly what types of leaf operators we allow
        if (nc == 0)
          {
            // general error, this expression is not supported in DIVISION BY
            NAString unparsed;
            
            expr->unparse(unparsed, PARSER_PHASE, COMPUTED_COLUMN_FORMAT);
            *CmpCommon::diags() << DgSqlCode(-4243) << DgString0(unparsed);
            retval = NULL;
          }
      }

  return retval;
}

short CmpSeabaseDDL::validateDivisionByExprForDDL(ItemExpr *divExpr)
{
  // Validate a DIVISION BY expression in a DDL statement
  // Check that the DIVISION BY expression conforms to the
  // supported types of expressions. This assumes that we
  // already verified that the expression refers only to
  // key columns

  short result                 = 0;
  NABoolean exprIsValid        = TRUE;
  ItemExpr  *missingConstHere  = NULL;
  ItemExpr  *missingColHere    = NULL;
  ItemExpr  *unsupportedExpr   = NULL;

  ItemExpr  *topLevelCast      = NULL;
  NABoolean topLevelCastIsOk   = FALSE;
  const OperatorTypeEnum leafColType = ITM_NAMED_TYPE_TO_ITEM;
  const NAType &origDivType    = divExpr->getValueId().getType();

  if (divExpr->getOperatorType() == ITM_CAST)
    {
      // a cast on top of the divisioning expr is allowed
      // in limited cases
      topLevelCast = divExpr;
      divExpr = topLevelCast->child(0).getPtr();
    }

  // check the shape of the divisioning expression
  switch (divExpr->getOperatorType())
    {
    case leafColType:
      {
        // a simple column is not allowed
        exprIsValid = FALSE;
        unsupportedExpr = divExpr;
      }
      break;

    case ITM_EXTRACT:       // for all variants except YEAR
    case ITM_EXTRACT_ODBC:  // for YEAR
      {
        // Allowed are:
        // date_part('year',         <arg>)
        // date_part('yearquarter',  <arg>)
        // date_part('yearmonth',    <arg>)
        // date_part('yearquarterd', <arg>)
        // date_part('yearmonthd',   <arg>)
        //
        // <arg> can be one of the following:
        //   <col>
        //   add_months(<col>, <const> [, 0])
        //   <col> + <const>
        //   <col> - <const>
        enum rec_datetime_field ef = ((Extract *) divExpr)->getExtractField();

        if (ef == REC_DATE_YEAR ||
            ef == REC_DATE_YEARQUARTER_EXTRACT ||
            ef == REC_DATE_YEARMONTH_EXTRACT ||
            ef == REC_DATE_YEARQUARTER_D_EXTRACT ||
            ef == REC_DATE_YEARMONTH_D_EXTRACT)
          {
            // check for the <arg> syntax shown above
            // Note that the parser changes ADD_MONTHS(a, b [,c]) into
            // a + cast(b as interval)
            if (divExpr->child(0)->getOperatorType() != leafColType)
              {
                if ((divExpr->child(0)->getOperatorType() == ITM_PLUS ||
                     divExpr->child(0)->getOperatorType() == ITM_MINUS) &&
                    divExpr->child(0)->child(0)->getOperatorType() == leafColType)
                  {
                    BiArith *plusMinus = (BiArith *) divExpr->child(0).getPtr();
                    ItemExpr *addedValue = plusMinus->child(1);

                    if (plusMinus->isKeepLastDay())
                      {
                        // we don't support keep last day normalization
                        // (1 as third argument to ADD_MONTHS)
                        exprIsValid = FALSE;
                        unsupportedExpr = plusMinus;
                      }
                    if (addedValue->getOperatorType() == ITM_CAST)
                      addedValue = addedValue->child(0);
                    if (addedValue->getOperatorType() == ITM_CAST)
                      addedValue = addedValue->child(0); // sometimes 2 casts are stacked here
                    if (NOT(addedValue->getOperatorType() == ITM_CONSTANT))
                      {
                        exprIsValid = FALSE;
                        missingConstHere = addedValue;
                      }
                  }
                else
                  {
                    exprIsValid = FALSE;
                    missingColHere = divExpr->child(0);
                  }
              }
          }
        else
          {
            // invalid type of extract field
            exprIsValid = FALSE;
            *CmpCommon::diags() << DgSqlCode(-4244);
          }
      }
      break;

    case ITM_DATE_TRUNC_MINUTE:
    case ITM_DATE_TRUNC_SECOND:
    case ITM_DATE_TRUNC_MONTH:
    case ITM_DATE_TRUNC_HOUR:
    case ITM_DATE_TRUNC_CENTURY:
    case ITM_DATE_TRUNC_DECADE:
    case ITM_DATE_TRUNC_YEAR:
    case ITM_DATE_TRUNC_DAY:
      {
        // Allowed are:
        // DATE_TRUNC(<string>, <col>)
        if (divExpr->child(0)->getOperatorType() != leafColType)
          {
            exprIsValid = FALSE;
            missingColHere = divExpr->child(0);
          }
      }
      break;

    case ITM_DATEDIFF_YEAR:
    case ITM_DATEDIFF_QUARTER:
    case ITM_DATEDIFF_WEEK:
    case ITM_DATEDIFF_MONTH:
      // Allowed are:
      // DATEDIFF(<date-part>, <const>, <col>)
      if (divExpr->child(0)->getOperatorType() != ITM_CONSTANT)
        {
          exprIsValid = FALSE;
          missingConstHere = divExpr->child(1);
        }
      if (divExpr->child(1)->getOperatorType() != leafColType)
        {
          exprIsValid = FALSE;
          missingColHere = divExpr->child(0);
        }
      break;

    case ITM_YEARWEEK:
    case ITM_YEARWEEKD:
      {
        // Allowed are:
        // DATE_PART('YEARWEEK',  <col>)
        // DATE_PART('YEARWEEKD', <col>)
        if (divExpr->child(0)->getOperatorType() != leafColType)
          {
            exprIsValid = FALSE;
            missingColHere = divExpr->child(0);
          }
      }
      break;

    case ITM_DIVIDE:
      {
        // Allowed are:
        //      <col> [ + <const> ] / <const>
        // cast(<col> [ + <const> ] / <const> as <numeric-type>)
        //
        // Note: cast (if present) is stored in topLevelCast, not divExpr
        if (divExpr->child(0)->getOperatorType() != leafColType)
          {
            if (divExpr->child(0)->getOperatorType() == ITM_PLUS)
              {
                if (divExpr->child(0)->child(0)->getOperatorType() != leafColType)
                  {
                    exprIsValid = FALSE;
                    missingColHere = divExpr->child(0)->child(0);
                  }
                if (divExpr->child(0)->child(1)->getOperatorType() != ITM_CONSTANT)
                  {
                    exprIsValid = FALSE;
                    missingConstHere = divExpr->child(0)->child(1);
                  }
              }
            else
              {
                exprIsValid = FALSE;
                missingColHere = divExpr->child(0);
              }
          }

        if (divExpr->child(1)->getOperatorType() != ITM_CONSTANT)
          {
            exprIsValid = FALSE;
            missingConstHere = divExpr->child(1);
          }
        if (topLevelCast)
          {
            topLevelCastIsOk = 
              (topLevelCast->getValueId().getType().getTypeQualifier() == NA_NUMERIC_TYPE);
          }
      }
      break;

    case ITM_SUBSTR:
    case ITM_LEFT:
      {
        // Allowed are:
        // SUBSTRING(<col>, 1, <const>)
        // SUBSTRING(<col> FROM 1 FOR <const>)  (which is the same thing)
        // LEFT(<col>, <const>)
        if (divExpr->child(0)->getOperatorType() != leafColType)
          {
            if (divExpr->child(0)->getOperatorType() == ITM_CAST &&
                divExpr->child(0)->child(0)->getOperatorType() == leafColType)
              {
                // tolerate a CAST(<basecolumn>), as long as it doesn't
                // alter the data type
                const CharType& tgtType =
                  (const CharType &) divExpr->child(0)->getValueId().getType();
                const CharType& srcType =
                  (const CharType &) divExpr->child(0)->child(0)->getValueId().getType();

                if (NOT(
                         srcType.getTypeQualifier() == NA_CHARACTER_TYPE &&
                         tgtType.getTypeQualifier() == NA_CHARACTER_TYPE &&
                         srcType.getCharSet() == tgtType.getCharSet() &&
                         srcType.getFSDatatype() == tgtType.getFSDatatype() &&
                         srcType.isVaryingLen() == tgtType.isVaryingLen()))
                  {
                    exprIsValid = FALSE;
                    // show the whole expression, the cast itself may
                    // not tell the user much, it may have been inserted
                    unsupportedExpr = divExpr;
                  }
              }
            else
              {
                exprIsValid = FALSE;
                missingColHere = divExpr->child(0);
              }
          }
        if (divExpr->child(1)->getOperatorType() != ITM_CONSTANT)
          {
            exprIsValid = FALSE;
            missingConstHere = divExpr->child(1);
          }

        if (exprIsValid)
          {
            if (divExpr->getOperatorType() == ITM_LEFT)
              {
                // condition for LEFT: child 1 must be a constant
                if (divExpr->child(1)->getOperatorType() != ITM_CONSTANT)
                  {
                    exprIsValid = FALSE;
                    missingConstHere = divExpr->child(2);
                  }
              }
            else
              {
                // additional conditions for SUBSTR: Second argument must be a
                // constant and evaluate to 1, third argument needs to
                // be present and be a constant
                NABoolean negate = FALSE;
                ConstValue *child1 = divExpr->child(1)->castToConstValue(negate);
                Int64 child1Value = 0;

                if (child1 && child1->canGetExactNumericValue())
                  child1Value = child1->getExactNumericValue();

                if (child1Value != 1 OR
                    divExpr->getArity() != 3)
                  {
                    exprIsValid = FALSE;
                    unsupportedExpr = divExpr;
                  }
                else if (divExpr->child(2)->getOperatorType() != ITM_CONSTANT)
                  {
                    exprIsValid = FALSE;
                    missingConstHere = divExpr->child(2);
                  }
              }
          }
      }
      break;

    default:
      {
        // everything else is not allowed in DIVISION BY
        exprIsValid = FALSE;
        unsupportedExpr = divExpr;
      }
    }

  if (topLevelCast && !topLevelCastIsOk)
    {
      exprIsValid = FALSE;
      if (!missingConstHere && !missingColHere && !unsupportedExpr)
        unsupportedExpr = topLevelCast;
    }

  if (NOT exprIsValid)
    {
      // common code for error handling
      NAString unparsed;

      result = -1;
      if (missingConstHere)
        {
          missingConstHere->unparse(unparsed, BINDER_PHASE, COMPUTED_COLUMN_FORMAT);
          *CmpCommon::diags() << DgSqlCode(-4241) << DgString0(unparsed);
        }
      if (missingColHere)
        {
          missingColHere->unparse(unparsed, BINDER_PHASE, COMPUTED_COLUMN_FORMAT);
          *CmpCommon::diags() << DgSqlCode(-4242) << DgString0(unparsed);
        }
      if (unsupportedExpr)
        {
          // general error, this expression is not supported in DIVISION BY
          unsupportedExpr->unparse(unparsed, BINDER_PHASE, COMPUTED_COLUMN_FORMAT);
          *CmpCommon::diags() << DgSqlCode(-4243) << DgString0(unparsed);
        }
    }

  if (origDivType.getTypeQualifier() == NA_NUMERIC_TYPE &&
      !((NumericType &) origDivType).isExact())
    {
      // approximate numeric data types are not supported, since
      // rounding errors could lead to incorrect computation of
      // divisioning keys
      result = -1;
      *CmpCommon::diags() << DgSqlCode(-4257);
    }

  return result;
}

short CmpSeabaseDDL::createEncodedKeysBuffer(char** &encodedKeysBuffer,
                                             int &numSplits,
                                             TrafDesc * colDescs, 
                                             TrafDesc * keyDescs,
                                             int numSaltPartitions,
                                             Lng32 numSaltSplits,
                                             NAString *splitByClause,
                                             Lng32 numKeys, 
                                             Lng32 keyLength,
                                             NABoolean isIndex)
{
  encodedKeysBuffer = NULL;
  numSplits = 0;

  if (numSaltSplits <= 0)
    return 0;

  // make a list of NAStrings with the default values for start keys
  NAString ** defaultSplits = createInArrayForLowOrHighKeys(
       colDescs,
       keyDescs,
       numKeys,
       FALSE,
       isIndex,
       STMTHEAP );
  NAString **splitValuesAsText = new(STMTHEAP) NAString *[numKeys];
  ElemDDLPartitionList * pPartitionList = NULL;
  ElemDDLPartitionRange *pPartitionRange = NULL;

      numSplits = numSaltSplits;

      // for salt splits, only the first key column value
      // is variable, the rest use the default values
      for (int k=1; k<numKeys; k++)
        splitValuesAsText[k] = defaultSplits[k];

  // allocate the result buffers, numSplits buffers of length keyLength
  encodedKeysBuffer = new (STMTHEAP) char*[numSplits];
  for(int i =0; i < numSplits; i++)
    encodedKeysBuffer[i] = new (STMTHEAP) char[keyLength];

  char splitNumCharStr[10];
  NAString splitNumString;

  // loop over the splits, HBase will create 1 more region than the
  // number of rows in the split array
  for(Int32 i =0; i < numSplits; i++)
    {
          /* We are splitting along salt partitions. In the example below we have a 
             salt column and an integer column as the key. KeyLength is 4 + 4 = 8.
             encodedKeysBuffer will have 4 elements, each of length 8. When this
             buffer is given to HBase through the Java API we get a table with 5 
             regions (4 splits) and begin/end keys as shown below

             Start Key                             End Key
                                                   \x00\x00\x00\x01\x00\x00\x00\x00
             \x00\x00\x00\x01\x00\x00\x00\x00      \x00\x00\x00\x02\x00\x00\x00\x00   
             \x00\x00\x00\x02\x00\x00\x00\x00      \x00\x00\x00\x03\x00\x00\x00\x00
             \x00\x00\x00\x03\x00\x00\x00\x00      \x00\x00\x00\x04\x00\x00\x00\x00   
             \x00\x00\x00\x04\x00\x00\x00\x00

             When we have more salt partitions than regions, the salt values
             will be distributed across the regions as evenly as possible
          */

          snprintf(splitNumCharStr, sizeof(splitNumCharStr), "%d",
                  ((i+1)*numSaltPartitions)/(numSaltSplits+1));
          splitNumString = splitNumCharStr;
          splitValuesAsText[0] = &splitNumString;

      short retVal = 0;

      // convert the array of NAStrings with textual values into
      // an encoded binary key buffer
      retVal = encodeKeyValues(colDescs,
                               keyDescs,
                               splitValuesAsText, // INPUT
                               isIndex,
                               FALSE,             // encoding for Min Key
                               encodedKeysBuffer[i],  // OUTPUT
                               STMTHEAP,
                               CmpCommon::diags());

      if (retVal)
        return -1;

      // check whether the encoded keys are ascending
      if (i > 0 &&
          memcmp(encodedKeysBuffer[i-1],
                 encodedKeysBuffer[i],
                 keyLength) >= 0)
        {
          *CmpCommon::diags() << DgSqlCode(-1211)
                              << DgInt0(i+1);
          return -1;
        }

    } // loop over splits

  return 0;
}

short CmpSeabaseDDL::dropSeabaseObject(ExpHbaseInterface * ehi,
                                       const NAString &objName,
                                       NAString &currCatName, NAString &currSchName,
                                       const ComObjectType objType,
                                       NABoolean ddlXns,
                                       NABoolean dropFromMD,
                                       NABoolean dropFromHbase)
{
  Lng32 retcode = 0;

  ComObjectName tableName(objName);
  ComAnsiNamePart currCatAnsiName(currCatName);
  ComAnsiNamePart currSchAnsiName(currSchName);
  tableName.applyDefaults(currCatAnsiName, currSchAnsiName);

  const NAString catalogNamePart = tableName.getCatalogNamePartAsAnsiString();
  const NAString schemaNamePart = tableName.getSchemaNamePartAsAnsiString(TRUE);
  const NAString objectNamePart = tableName.getObjectNamePartAsAnsiString(TRUE);
  NAString extTableName = tableName.getExternalName(TRUE);
  const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
   CmpCommon::context()->sqlSession()->getParentQid() );

  if (dropFromMD)
    {
      if (isAuthorizationEnabled())
        {
          NABoolean isHive = FALSE;
          NAString hiveNativeName;
          Int32 objOwnerID = 0;
          Int32 schemaOwnerID = 0;
          Int64 objectFlags = 0;
          Int64 objUID = -1;

          // remove priv info if this hive table is not registered in traf
          // metadata. Could happen for hive external tables created prior
          // to hive registration support.
          if ((ComIsTrafodionExternalSchemaName(schemaNamePart, &isHive)) &&
              (isHive))
            {
              NAString quotedSchemaName;
              
              quotedSchemaName = '\"';
              quotedSchemaName += schemaNamePart;
              quotedSchemaName += '\"';

              hiveNativeName = ComConvertTrafNameToNativeName(
                   catalogNamePart, quotedSchemaName, objectNamePart);
              
              // see if this hive table has been registered in traf metadata
              ComObjectName hiveTableName(hiveNativeName);
              const NAString hiveCatName = hiveTableName.getCatalogNamePartAsAnsiString();
              const NAString hiveSchName = hiveTableName.getSchemaNamePartAsAnsiString();
              const NAString hiveObjName = hiveTableName.getObjectNamePartAsAnsiString();           
              CorrName cn(hiveObjName, STMTHEAP, hiveSchName, hiveCatName);
              BindWA bindWA(ActiveSchemaDB(),CmpCommon::context(),FALSE/*inDDL*/);
              NATable *naTable = bindWA.getNATableInternal(cn);
              if ((naTable) && (naTable->isHiveTable()))
                {
                  if (NOT naTable->isRegistered())
                    {
                      objUID = naTable->objectUid().get_value();
                      extTableName = hiveTableName.getExternalName(TRUE);

                      objOwnerID = naTable->getOwner();
                      schemaOwnerID = naTable->getSchemaOwner();
                    }
                }
            }
          
          
          // Revoke owner privileges for object
          //   it would be more efficient to pass in the object owner and UID
          //   than to do an extra I/O.
          if (objUID < 0)
            {
              objUID = getObjectInfo(&cliInterface,
                                     catalogNamePart.data(), schemaNamePart.data(),
                                     objectNamePart.data(), objType,
                                     objOwnerID,schemaOwnerID,objectFlags);
            }
          if (objUID < 0 || objOwnerID == 0)
            { //TODO: Internal error?
              return -1;
            }
          
          if (!deletePrivMgrInfo ( extTableName, objUID, objType )) 
            {
              return -1;
            }
        }
      
      if (deleteFromSeabaseMDTable(&cliInterface, 
                                   catalogNamePart, schemaNamePart, objectNamePart, objType ))
        return -1;
    }

  if (dropFromHbase)
    {
      if (objType != COM_VIEW_OBJECT)
        {
          HbaseStr hbaseTable;
          hbaseTable.val = (char*)extNameForHbase.data();
          hbaseTable.len = extNameForHbase.length();

          retcode = dropHbaseTable(ehi, &hbaseTable, FALSE, ddlXns);
          if (retcode < 0)
            {
              return -1;
            }
        }
    }

  return 0;
}

short CmpSeabaseDDL::dropSeabaseStats(ExeCliInterface *cliInterface,
                                      const char * catName,
                                      const char * schName,
                                      Int64 tableUID)
{
  Lng32 cliRC = 0;
  char buf[4000];

  // delete any histogram statistics
  
  str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %ld",
              catName, schName, HBASE_HIST_NAME, tableUID);

  cliRC = cliInterface->executeImmediate(buf);

  // If the histogram table does not exist, don't bother checking
  // the histogram intervals table. 
  //
  // Note: cliRC == 100 happens when we delete some histogram rows
  // and also when there are no histogram rows to delete, so we
  // can't decide based on that.
 
  if (cliRC != -4082)
    {

      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }

      str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %ld",
                  catName, schName, HBASE_HISTINT_NAME, tableUID);
      cliRC = cliInterface->executeImmediate(buf);

      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
    }

  // Drop any persistent sample tables also. (It is possible that these
  // might exist even if the histograms table does not exist.)

  // Delete the row in the persistent_samples table if one exists

  str_sprintf(buf, "select translate(sample_name using ucs2toutf8) from "
                   " (delete from %s.\"%s\".%s where table_uid = %ld) as t",
              catName, schName, HBASE_PERS_SAMP_NAME, tableUID);
    
  Lng32 len = 0;
  char sampleTableName[1000];

  cliRC = cliInterface->executeImmediate(buf, (char*)&sampleTableName, &len, FALSE);
  if (cliRC == -4082)  // if persistent_samples table does not exist
    cliRC = 0;         // then there isn't a persistent sample table
  else if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }
  else if ((len > 0) && (sampleTableName[0])) // if we got a sample table name back
    {
      // try to drop the sample table
      sampleTableName[len] = '\0';
      str_sprintf(buf, "drop table %s", sampleTableName);
      cliRC = cliInterface->executeImmediate(buf);
      if (cliRC < 0)
        {
          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
          return -1;
        }
    }

  return 0;
}

short CmpSeabaseDDL::updateSeabaseVersions(
                                           ExeCliInterface *cliInterface,
                                           const char* sysCat,
                                           Lng32 majorVersion)
{
  Lng32 cliRC = 0;
  char buf[4000];
  
  str_sprintf(buf, "delete from %s.\"%s\".%s ",
              sysCat, SEABASE_MD_SCHEMA, SEABASE_VERSIONS);

  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  Int64 initTime = NA_JulianTimestamp();

  str_sprintf(buf, "insert into %s.\"%s\".%s values ('METADATA', %d, %d, %ld, 'initialize trafodion'), ('DATAFORMAT', %d, %d, %ld, 'initialize trafodion'), ('SOFTWARE', %d, %d, %ld, 'initialize trafodion') ",
              sysCat, SEABASE_MD_SCHEMA, SEABASE_VERSIONS,
              (majorVersion != -1 ? majorVersion : METADATA_MAJOR_VERSION),
              (METADATA_MINOR_VERSION * 10 + METADATA_UPDATE_VERSION), initTime,
              DATAFORMAT_MAJOR_VERSION, DATAFORMAT_MINOR_VERSION, initTime,
              SOFTWARE_MAJOR_VERSION, 
              (SOFTWARE_MINOR_VERSION * 10 + SOFTWARE_UPDATE_VERSION), initTime);
  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  return 0;
}

short CmpSeabaseDDL::updateSeabaseAuths(
                                         ExeCliInterface *cliInterface,
                                         const char* sysCat)
{
  Lng32 cliRC = 0;
  char buf[4000];

  str_sprintf(buf, "delete from %s.\"%s\".%s ",
              sysCat, SEABASE_MD_SCHEMA, SEABASE_AUTHS);

  cliRC = cliInterface->executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }

  Int64 initTime = NA_JulianTimestamp();

  NAString mdLocation;
  CONCAT_CATSCH(mdLocation, getSystemCatalog(), SEABASE_MD_SCHEMA);
  CmpSeabaseDDLuser authOperation(sysCat, mdLocation.data());
  authOperation.registerStandardUser(DB__ROOT, ROOT_USER_ID);
  if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_))
    return -1;

  return 0;
}

void CmpSeabaseDDL::initSeabaseMD(NABoolean ddlXns, NABoolean minimal)
{
  int breadCrumb = -1;  // useful for debugging

  // verify user is authorized
  if (!ComUser::isRootUserID())
    {
       *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
       return;
    }

  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  NABoolean xnWasStartedHere = FALSE;
  Int64 schemaUID = -1;  
  Int64 objectFlags = 0;

  Lng32 numTables = sizeof(allMDtablesInfo) / sizeof(MDTableInfo);

  Queue * tempQueue = NULL;

  // create metadata tables in hbase
  ExpHbaseInterface * ehi = allocEHI();
  if (ehi == NULL)
    return;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL, 
    CmpCommon::context()->sqlSession()->getParentQid());

  const char* sysCat = ActiveSchemaDB()->getDefaults().getValue(SEABASE_CATALOG);

  ComTdbVirtTableTableInfo * tableInfo = new(STMTHEAP) ComTdbVirtTableTableInfo[1];
 
  Lng32 hbaseErrNum = 0;
  NAString hbaseErrStr;
  Lng32 errNum = validateVersions(&ActiveSchemaDB()->getDefaults(), ehi,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                  &hbaseErrNum, &hbaseErrStr);
  if (errNum != 0)
    {
      CmpCommon::context()->setIsUninitializedSeabase(TRUE);
      CmpCommon::context()->uninitializedSeabaseErrNum() = errNum;
      CmpCommon::context()->hbaseErrNum() = hbaseErrNum;
      CmpCommon::context()->hbaseErrStr() = hbaseErrStr;

      if (errNum != -1393) // 1393: metadata is not initialized
        {
          if (errNum == -1398)
            *CmpCommon::diags() << DgSqlCode(errNum)
                                << DgInt0(hbaseErrNum)
                                << DgString0(hbaseErrStr);
          else
            *CmpCommon::diags() << DgSqlCode(errNum);

          deallocEHI(ehi); 
          return;
        }
    }
  else
    {
      CmpCommon::context()->setIsUninitializedSeabase(FALSE);

      *CmpCommon::diags() << DgSqlCode(-1392);

      deallocEHI(ehi); 
      return;
    }

  // drop and recreate DTM table TDDL.
  // Do not do this drop/recreate operation under a dtm transaction.
  // See file core/sqf/src/seatrans/hbase-trx/src/main/java/org/apache/hadoop/hbase/client/transactional/TmDDL.java
  // Keep the name TRAFODION._DTM_.TDDL and col fam "tddlcf" in sync with
  // that file.
  HbaseStr tddlTable;
  const NAString tddlNAS("TRAFODION._DTM_.TDDL");
  tddlTable.val = (char*)tddlNAS.data();
  tddlTable.len = tddlNAS.length();
  if (ehi->exists(tddlTable) == -1) // exists
    {
      ehi->truncate(tddlTable, TRUE, TRUE);
    }

  // create hbase physical objects
  for (Lng32 i = 0; i < numTables; i++)
    {
      const MDTableInfo &mdti = allMDtablesInfo[i];

      HbaseStr hbaseObject;
      NAString hbaseObjectStr(sysCat);
      hbaseObjectStr += ".";
      hbaseObjectStr += SEABASE_MD_SCHEMA;
      hbaseObjectStr += ".";
      hbaseObjectStr += mdti.newName;
      hbaseObject.val = (char*)hbaseObjectStr.data();
      hbaseObject.len = hbaseObjectStr.length();
      if (createHbaseTable(ehi, &hbaseObject, SEABASE_DEFAULT_COL_FAMILY, NULL,
                           0, 0, NULL,
                           FALSE, ddlXns) == -1)
        {
          deallocEHI(ehi); 
          return;
        }

    } // for
 
  deallocEHI(ehi); 
  ehi = NULL;

  // Note that this is not an existing jar file, the class
  // loader will attempt to load the class from the CLASSPATH if
  // it can't find this jar
  NAString installJar(getenv("TRAF_HOME"));
  installJar += "/export/lib/trafodion-sql-currversion.jar";

  breadCrumb = 1;
  if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere))
    goto label_error;

  cliRC = cliInterface.holdAndSetCQD("traf_bootstrap_md_mode", "ON");
  if (cliRC < 0)
    {
      breadCrumb = 2;
      goto label_error;
    }
  breadCrumb = 3;

  // Create Seabase system schema
  if (updateSeabaseMDObjectsTable(&cliInterface,sysCat,SEABASE_SYSTEM_SCHEMA,
                                  SEABASE_SCHEMA_OBJECTNAME,
                                  COM_SHARED_SCHEMA_OBJECT,"Y",SUPER_USER,
                                  SUPER_USER,objectFlags,schemaUID))
  {
    goto label_error;
  }
  breadCrumb = 4;
  
  // Create Seabase metadata schema
  schemaUID = -1;
  if (updateSeabaseMDObjectsTable(&cliInterface,sysCat,SEABASE_MD_SCHEMA,
                                  SEABASE_SCHEMA_OBJECTNAME,
                                  COM_PRIVATE_SCHEMA_OBJECT,"Y",SUPER_USER,
                                  SUPER_USER,objectFlags, schemaUID))
  {
    goto label_error;
  }

  // update MD with information about metadata objects
  for (Lng32 i = 0; i < numTables; i++)
    {
      const MDTableInfo &mdti = allMDtablesInfo[i];
      MDDescsInfo &mddi = CmpCommon::context()->getTrafMDDescsInfo()[i];

      if (mdti.isIndex)
        continue;

      Int64 objUID = -1;
      if (updateSeabaseMDTable(&cliInterface, 
                               sysCat, SEABASE_MD_SCHEMA, mdti.newName,
                               COM_BASE_TABLE_OBJECT,
                               "Y",
                               mddi.tableInfo,
                               mddi.numNewCols,
                               mddi.newColInfo,
                               mddi.numNewKeys,
                               mddi.newKeyInfo,
                               mddi.numIndexes,
                               mddi.indexInfo,
                               objUID))
        {
          breadCrumb = 5;
          goto label_error;
        }

    } // for

  // update metadata with metadata indexes information
  for (Lng32 i = 0; i < numTables; i++)
    {
      const MDTableInfo &mdti = allMDtablesInfo[i];
      MDDescsInfo &mddi = CmpCommon::context()->getTrafMDDescsInfo()[i];

      if (NOT mdti.isIndex)
        continue;

      tableInfo->tableName = NULL,
      tableInfo->createTime = 0;
      tableInfo->redefTime = 0;
      tableInfo->objUID = 0;
      tableInfo->objOwnerID = SUPER_USER;
      tableInfo->schemaOwnerID = SUPER_USER;
      tableInfo->isAudited = 1;
      tableInfo->validDef = 1;
      tableInfo->hbaseCreateOptions = NULL;
      tableInfo->numSaltPartns = 0;
      tableInfo->rowFormat = COM_UNKNOWN_FORMAT_TYPE;
      tableInfo->objectFlags = 0;

      Int64 objUID = -1;
      if (updateSeabaseMDTable(&cliInterface, 
                               sysCat, SEABASE_MD_SCHEMA, mdti.newName,
                               COM_INDEX_OBJECT,
                               "Y",
                               tableInfo,
                               mddi.numNewCols,
                               mddi.newColInfo,
                               mddi.numNewKeys,
                               mddi.newKeyInfo,
                               0, NULL,
                               objUID))
        {
          breadCrumb = 6;
          goto label_error;
        }
    } // for

  // update SPJ info
  if (updateSeabaseMDSPJ(&cliInterface, sysCat, SEABASE_MD_SCHEMA, 
                         SEABASE_VALIDATE_LIBRARY,
                         installJar.data(),SUPER_USER,SUPER_USER,
                         &seabaseMDValidateRoutineInfo,
                         sizeof(seabaseMDValidateRoutineColInfo) / sizeof(ComTdbVirtTableColumnInfo),
                         seabaseMDValidateRoutineColInfo))
    {
      breadCrumb = 7;
      goto label_error;
    }

  updateSeabaseVersions(&cliInterface, sysCat);
  updateSeabaseAuths(&cliInterface, sysCat);

  if (endXnIfStartedHere(&cliInterface, xnWasStartedHere, 0) < 0)
    return;

  CmpCommon::context()->setIsUninitializedSeabase(FALSE);
  CmpCommon::context()->uninitializedSeabaseErrNum() = 0;

  if (createSchemaObjects(&cliInterface))
    {
      breadCrumb = 8;
      goto label_error;
    }
 
 if (createMetadataViews(&cliInterface))
    {
      breadCrumb = 9;
      goto label_error;
    }

 // If this is a MINIMAL initialization, don't create the repository
 // or privilege manager tables. (This happens underneath an upgrade,
 // for example, because the repository and privilege manager tables
 // already exist and we will later upgrade them.)
 if (!minimal)  
   {
     if (createRepos(&cliInterface))
       {
         breadCrumb = 10;
         goto label_error;
       }

     if (createPrivMgrRepos(&cliInterface, ddlXns))
       {
         breadCrumb = 11;
         goto label_error;
       }
   }

 if (createSeabaseLibmgr (&cliInterface))
   {   
     breadCrumb = 12;
     goto label_error;
   }

  cliRC = cliInterface.restoreCQD("traf_bootstrap_md_mode");

  return;

 label_error:

  // When debugging, the breadCrumb variable is useful to tell you
  // how you got here.

  endXnIfStartedHere(&cliInterface, xnWasStartedHere, -1);

  char msg[80];
  str_sprintf(msg,"CmpSeabaseDDL::initSeabaseMD failed, breadCrumb = %d",breadCrumb);
  SQLMXLoggingArea::logSQLMXDebugEvent(msg, -1, __LINE__);

  return;
}

void CmpSeabaseDDL::createSeabaseMDviews()
{
  if (!ComUser::isRootUserID())
    {
      *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
      return;
    }

  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1393))
    {
      *CmpCommon::diags() << DgSqlCode(-1393);
      return;
    }

  if (createMetadataViews(&cliInterface))
    {
      return;
    }

}

void CmpSeabaseDDL::dropSeabaseMDviews()
{
  // verify user is authorized
  if (!ComUser::isRootUserID())
    {
       *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
       return;
    }

  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL, 
    CmpCommon::context()->sqlSession()->getParentQid());

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1393))
    {
      *CmpCommon::diags() << DgSqlCode(-1393);
      return;
    }

  if (dropMetadataViews(&cliInterface))
    {
      return;
    }

}

void CmpSeabaseDDL::createSeabaseSchemaObjects()
{
  if (!ComUser::isRootUserID())
    {
      *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
       return;
    }

  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1393))
    {
      *CmpCommon::diags() << DgSqlCode(-1393);
      return;
    }

  if (createSchemaObjects(&cliInterface))
    {
      return;
    }

}


short CmpSeabaseDDL::createSchemaObjects(ExeCliInterface *cliInterface)

{

  Lng32 retcode = 0;
  Lng32 cliRC = 0;
  char buf[4000];
  
  str_sprintf(buf,"SELECT DISTINCT TRIM(CATALOG_NAME), TRIM(SCHEMA_NAME) FROM %s.%s ",
              getMDSchema(),SEABASE_OBJECTS);
  
  Queue * queue = NULL;
  
  cliRC = cliInterface->fetchAllRows(queue,buf,0,false,false,true);
  
  if (cliRC < 0)
    {
      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
      return -1;
    }
  
  if (cliRC == 100) // did not find the row
    {
      cliInterface->clearGlobalDiags();
      return 0;
    }
  
  if (queue == NULL)
    return -1;
  
  std::vector<QualifiedSchema> schemaNames;
  
  queue->position();
  for (size_t r = 0; r < queue->numEntries(); r++)
    {
      OutputInfo * cliInterface = (OutputInfo*)queue->getNext();
      QualifiedSchema qualifiedSchema;
      char *ptr;
      Int32 length;
      char value[ComMAX_ANSI_IDENTIFIER_INTERNAL_LEN + 1];
      
      // column 1:  CATALOG_NAME
      cliInterface->get(0,ptr,length);
      strncpy(value,ptr,length);
      value[length] = 0;
      strcpy(qualifiedSchema.catalogName,value);
      
      // column 2:  SCHEMA_NAME
      cliInterface->get(1,ptr,length);
      strncpy(value,ptr,length);
      value[length] = 0;
      strcpy(qualifiedSchema.schemaName,value);
      
      schemaNames.push_back(qualifiedSchema);
    } 
  
  NABoolean xnWasStartedHere = false;
  
  if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere))
    return -1;

  // save the current parserflags setting
  ULng32 savedParserFlags = Get_SqlParser_Flags(0xFFFFFFFF);
  Set_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL);
  
  for (size_t s = 0; s < schemaNames.size(); s++)
    {
      QualifiedSchema schemaEntry = schemaNames[s];
      // Ignore if entry already exists.
      if (existsInSeabaseMDTable(cliInterface,schemaEntry.catalogName,
                                 schemaEntry.schemaName, 
                                 SEABASE_SCHEMA_OBJECTNAME)) 
        continue;     
      
      // Catalog or schema names could be delimited names.  Surround them
      // in quotes to avoid scanning problems.     
      
      NAString quotedCatalogName;
      
      quotedCatalogName = '\"';
      quotedCatalogName += schemaEntry.catalogName;
      quotedCatalogName += '\"';
      
      NAString quotedSchemaName;
      
      quotedSchemaName = '\"';
      quotedSchemaName += schemaEntry.schemaName;
      quotedSchemaName += '\"';
      
      ComSchemaName schemaName(quotedCatalogName,quotedSchemaName);
      
      if (addSchemaObject(*cliInterface,schemaName,
                          COM_SCHEMA_CLASS_SHARED,SUPER_USER, FALSE)) 
        {
          // Restore parser flags settings to what they originally were
          Assign_SqlParser_Flags(savedParserFlags);
          return -1;
        }
    }
  
  // Restore parser flags settings to what they originally were
  Assign_SqlParser_Flags(savedParserFlags);

  if (endXnIfStartedHere(cliInterface, xnWasStartedHere, 0) < 0)
    return -1;
  
   return 0;  
  
}

// ----------------------------------------------------------------------------
// method: createPrivMgrRepos
//
// This method is called during initialize trafodion to create the privilege
// manager repository.
//
// Params: 
//   cliInterface - pointer to a CLI helper class
//
// returns:
//   0: successful
//  -1: failed
//
//  The diags area is populated with any unexpected errors
// ---------------------------------------------------------------------------- 
short CmpSeabaseDDL::createPrivMgrRepos(ExeCliInterface *cliInterface,
                                        NABoolean ddlXns)
{
  // During install, the customer can choose to enable security features through 
  // an installation option which sets the the environment variable 
  // TRAFODION_ENABLE_AUTHENTICATION to YES. Check to see if security features
  // should be enabled.
  char * env = getenv("TRAFODION_ENABLE_AUTHENTICATION");
  if (strcmp(env, "NO") == 0)
    return 0;

  std::vector<std::string> tablesCreated;
  std::vector<std::string> tablesUpgraded;

  if (initSeabaseAuthorization(cliInterface, ddlXns,
                               tablesCreated, tablesUpgraded) < 0)
    return -1;

  return 0;
}

void  CmpSeabaseDDL::createSeabaseSequence(StmtDDLCreateSequence  * createSequenceNode,
                                           NAString &currCatName, NAString &currSchName)
{
  Lng32 cliRC;
  Lng32 retcode;

  char buf[4000];

  NAString sequenceName = (NAString&)createSequenceNode->getSeqName();

  ComObjectName seqName(sequenceName, COM_TABLE_NAME);
  ComAnsiNamePart currCatAnsiName(currCatName);
  ComAnsiNamePart currSchAnsiName(currSchName);
  seqName.applyDefaults(currCatAnsiName, currSchAnsiName);

  NAString catalogNamePart = seqName.getCatalogNamePartAsAnsiString();
  NAString schemaNamePart = seqName.getSchemaNamePartAsAnsiString(TRUE);
  NAString seqNamePart = seqName.getObjectNamePartAsAnsiString(TRUE);
  const NAString extSeqName = seqName.getExternalName(TRUE);

  ElemDDLSGOptions * sgo = createSequenceNode->getSGoptions();

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());
  

  // Verify that the current user has authority to perform operation
  Int32 objectOwnerID;
  Int32 schemaOwnerID;
  ComSchemaClass schemaClass;
  retcode = verifyDDLCreateOperationAuthorized(&cliInterface,
                                               SQLOperation::CREATE_SEQUENCE,
                                               catalogNamePart, 
                                               schemaNamePart,
                                               schemaClass,
                                               objectOwnerID,
                                               schemaOwnerID);
  if (retcode != 0)
  {
     handleDDLCreateAuthorizationError(retcode,catalogNamePart,schemaNamePart);
     processReturn();
     return;
  }

  if (isSeabaseReservedSchema(seqName))
    {
      *CmpCommon::diags() << DgSqlCode(-CAT_CREATE_TABLE_NOT_ALLOWED_IN_SMD)
                          << DgTableName(extSeqName);
      processReturn();
      return;
    }

  retcode = existsInSeabaseMDTable(&cliInterface, 
                                   catalogNamePart, schemaNamePart, seqNamePart);
  if (retcode < 0)
    {
      processReturn();

      return;
    }
  
  if (retcode == 1) // already exists
    {
      *CmpCommon::diags() << DgSqlCode(-1390)
                                << DgString0(extSeqName);
      
      processReturn();
      
      return;
    }

  ComUID seqUID;
  seqUID.make_UID();
  Int64 seqObjUID = seqUID.get_value();
  
  Int64 createTime = NA_JulianTimestamp();

  NAString quotedSchName;
  ToQuotedString(quotedSchName, schemaNamePart, FALSE);
  NAString quotedSeqObjName;
  ToQuotedString(quotedSeqObjName, seqNamePart, FALSE);

  Int32 objOwner = ComUser::getCurrentUser();
  str_sprintf(buf, "insert into %s.\"%s\".%s values ('%s', '%s', '%s', '%s', %ld, %ld, %ld, '%s', '%s', %d, %d, 0)",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS,
              catalogNamePart.data(), quotedSchName.data(), quotedSeqObjName.data(),
              COM_SEQUENCE_GENERATOR_OBJECT_LIT,
              seqObjUID,
              createTime, 
              createTime,
              COM_YES_LIT,
              COM_NO_LIT,
              objectOwnerID,
              schemaOwnerID);
  cliRC = cliInterface.executeImmediate(buf);
  
  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
    }

  str_sprintf(buf, "insert into %s.\"%s\".%s values ('%s', %ld, %d, %ld, %ld, %ld, %ld, '%s', %ld, %ld, %ld, %ld, %ld, 0)",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_SEQ_GEN,
              (sgo->isExternalSG() ? COM_EXTERNAL_SG_LIT : COM_INTERNAL_SG_LIT),
              seqObjUID, 
              sgo->getFSDataType(), //REC_BIN64_SIGNED, 
              sgo->getStartValue(),
              sgo->getIncrement(),
              sgo->getMaxValue(),
              sgo->getMinValue(),
              (sgo->getCycle() ? COM_YES_LIT : COM_NO_LIT), 
              sgo->getCache(),
              sgo->getStartValue(),
              0L,
              createTime,
              0L);

  cliRC = cliInterface.executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
    }

  // Add privileges for the sequence
  if (!insertPrivMgrInfo(seqObjUID, 
                         extSeqName, 
                         COM_SEQUENCE_GENERATOR_OBJECT, 
                         objectOwnerID,
                         schemaOwnerID,
                         ComUser::getCurrentUser()))
        {
          *CmpCommon::diags()
            << DgSqlCode(-CAT_UNABLE_TO_GRANT_PRIVILEGES)
            << DgTableName(extSeqName);

          processReturn();

          return;
        }

  return;
}

void  CmpSeabaseDDL::alterSeabaseSequence(StmtDDLCreateSequence  * alterSequenceNode,
                                          NAString &currCatName, NAString &currSchName)
{
  Lng32 cliRC;
  Lng32 retcode;

  char buf[4000];

  NAString sequenceName = (NAString&)alterSequenceNode->getSeqName();

  ComObjectName seqName(sequenceName, COM_TABLE_NAME);
  ComAnsiNamePart currCatAnsiName(currCatName);
  ComAnsiNamePart currSchAnsiName(currSchName);
  seqName.applyDefaults(currCatAnsiName, currSchAnsiName);

  NAString catalogNamePart = seqName.getCatalogNamePartAsAnsiString();
  NAString schemaNamePart = seqName.getSchemaNamePartAsAnsiString(TRUE);
  NAString seqNamePart = seqName.getObjectNamePartAsAnsiString(TRUE);
  const NAString extSeqName = seqName.getExternalName(TRUE);

  ElemDDLSGOptions * sgo = alterSequenceNode->getSGoptions();

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());
  
  retcode = existsInSeabaseMDTable(&cliInterface, 
                                   catalogNamePart, schemaNamePart, seqNamePart);
  if (retcode < 0)
    {
      processReturn();

      return;
    }
  
  if (retcode == 0) // does not exist
    {
      CmpCommon::diags()->clear();
      
      *CmpCommon::diags() << DgSqlCode(-1389)
                          << DgString0(extSeqName);

      processReturn();

      return;
    }

  Int32 objectOwnerID = 0;
  Int32 schemaOwnerID = 0;
  Int64 objectFlags = 0;
  Int64 seqUID = getObjectInfo(&cliInterface,
                               catalogNamePart.data(), schemaNamePart.data(),
                               seqNamePart.data(), COM_SEQUENCE_GENERATOR_OBJECT,
                               objectOwnerID,schemaOwnerID,objectFlags);
  
  // Check for error getting metadata information
  if (seqUID == -1 || objectOwnerID == 0)
    {
      if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
        SEABASEDDL_INTERNAL_ERROR("getting object UID and owner for alter sequence");

      processReturn();

      return;
     }

  // Verify that the current user has authority to perform operation
  if (!isDDLOperationAuthorized(SQLOperation::ALTER_SEQUENCE,
                                objectOwnerID,schemaOwnerID))
  {
     *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
 
     processReturn();

     return;
  }

  char setOptions[2000];
  char tmpBuf[1000];

  strcpy(setOptions, " set ");
  if (sgo->isIncrementSpecified())
    {
      str_sprintf(tmpBuf, " increment = %ld,", sgo->getIncrement());
      strcat(setOptions, tmpBuf);
    }

  if (sgo->isMaxValueSpecified())
    {
      str_sprintf(tmpBuf, " max_value = %ld,", sgo->getMaxValue());
      strcat(setOptions, tmpBuf);
    }

  if (sgo->isMinValueSpecified())
    {
      str_sprintf(tmpBuf, " min_value = %ld,", sgo->getMinValue());
      strcat(setOptions, tmpBuf);
    }

  if (sgo->isCacheSpecified())
    {
      str_sprintf(tmpBuf, " cache_size = %ld,", sgo->getCache());
      strcat(setOptions, tmpBuf);
    }

  if (sgo->isCycleSpecified())
    {
      str_sprintf(tmpBuf, " cycle_option = '%s',", (sgo->getCycle() ? "Y" : "N"));
      strcat(setOptions, tmpBuf);
    }

  if (sgo->isResetSpecified())
    {
      str_sprintf(tmpBuf, " next_value = start_value, num_calls = 0, ");
      strcat(setOptions, tmpBuf);
    }
  
  Int64 redefTime = NA_JulianTimestamp();
  str_sprintf(tmpBuf, " redef_ts = %ld", redefTime);
  strcat(setOptions, tmpBuf);

  str_sprintf(buf, "update %s.\"%s\".%s %s where seq_uid = %ld",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_SEQ_GEN,
              setOptions,
              seqUID);

  cliRC = cliInterface.executeImmediate(buf);
  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
    }

  if (updateObjectRedefTime(&cliInterface,
                            catalogNamePart, schemaNamePart, seqNamePart,
                            COM_SEQUENCE_GENERATOR_OBJECT_LIT,
                            redefTime))
    {
      processReturn();

      return;
    }

  CorrName cn(seqNamePart, STMTHEAP, schemaNamePart, catalogNamePart);
  cn.setSpecialType(ExtendedQualName::SG_TABLE);
  ActiveSchemaDB()->getNATableDB()->removeNATable
    (cn, 
     ComQiScope::REMOVE_FROM_ALL_USERS, COM_SEQUENCE_GENERATOR_OBJECT,
     alterSequenceNode->ddlXns(), FALSE);

  return;
}

void  CmpSeabaseDDL::dropSeabaseSequence(StmtDDLDropSequence  * dropSequenceNode,
                                         NAString &currCatName, NAString &currSchName)
{
  Lng32 cliRC = 0;
  Lng32 retcode = 0;

  NAString sequenceName = (NAString&)dropSequenceNode->getSeqName();

  ComObjectName seqName(sequenceName, COM_TABLE_NAME);
  ComAnsiNamePart currCatAnsiName(currCatName);
  ComAnsiNamePart currSchAnsiName(currSchName);
  seqName.applyDefaults(currCatAnsiName, currSchAnsiName);

  NAString catalogNamePart = seqName.getCatalogNamePartAsAnsiString();
  NAString schemaNamePart = seqName.getSchemaNamePartAsAnsiString(TRUE);
  NAString objectNamePart = seqName.getObjectNamePartAsAnsiString(TRUE);
  const NAString extSeqName = seqName.getExternalName(TRUE);

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());

  retcode = existsInSeabaseMDTable(&cliInterface, 
                                   catalogNamePart, schemaNamePart, objectNamePart);
  if (retcode < 0)
    {
      processReturn();

      return;
    }
  
  if (retcode == 0) // does not exist
    {
      CmpCommon::diags()->clear();
      
      *CmpCommon::diags() << DgSqlCode(-1389)
                          << DgString0(extSeqName);

      processReturn();

      return;
    }

  // remove any privileges
  if (isAuthorizationEnabled())
    {
      Int32 objectOwnerID = 0;
      Int32 schemaOwnerID = 0;
      Int64 objectFlags = 0;
      Int64 seqUID = getObjectInfo(&cliInterface,
                                   catalogNamePart.data(), schemaNamePart.data(),
                                   objectNamePart.data(), COM_SEQUENCE_GENERATOR_OBJECT,
                                   objectOwnerID,schemaOwnerID,objectFlags);
  
      // Check for error getting metadata information
      if (seqUID == -1 || objectOwnerID == 0)
        {
          if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
            SEABASEDDL_INTERNAL_ERROR("getting object UID and owner for drop sequence");

          processReturn();

          return;
       }

      // Check to see if the user has the authority to drop the table
      if (!isDDLOperationAuthorized(SQLOperation::DROP_SEQUENCE,objectOwnerID,
                                    schemaOwnerID))
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);

         processReturn ();

         return;
      }

    if (!deletePrivMgrInfo ( objectNamePart, 
                             seqUID, 
                             COM_SEQUENCE_GENERATOR_OBJECT ))
    {
      *CmpCommon::diags() << DgSqlCode(-CAT_NOT_ALL_PRIVILEGES_REVOKED);

      processReturn();

      return;
    }

  }

  if (deleteFromSeabaseMDTable(&cliInterface, 
                               catalogNamePart, schemaNamePart, objectNamePart, 
                               COM_SEQUENCE_GENERATOR_OBJECT))
    return;

  CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart);
  cn.setSpecialType(ExtendedQualName::SG_TABLE);
  ActiveSchemaDB()->getNATableDB()->removeNATable
    (cn,
     ComQiScope::REMOVE_FROM_ALL_USERS, COM_SEQUENCE_GENERATOR_OBJECT,
     dropSequenceNode->ddlXns(), FALSE);
 
  return;
}

short CmpSeabaseDDL::dropSeabaseObjectsFromHbase(const char * pattern,
                                                 NABoolean ddlXns)
{
  ExpHbaseInterface * ehi = allocEHI();
  if (ehi == NULL)
    return -1;

  short retcode = ehi->dropAll(pattern, FALSE, (NOT ddlXns));

  if (retcode < 0)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::dropAll()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());

      return retcode;
    }

  return 0;
}

void CmpSeabaseDDL::dropSeabaseMD(NABoolean ddlXns)
{
  // verify user is authorized
  if (!ComUser::isRootUserID())
    {
       *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
       return;
    }

  Lng32 cliRC;
  Lng32 retcode = 0;
  NABoolean xnWasStartedHere = FALSE;

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1393))
    {
      *CmpCommon::diags() << DgSqlCode(-1393);
      return;
    }

  // drop all objects that match the pattern "TRAFODION.*"
  dropSeabaseObjectsFromHbase("TRAFODION\\..*", ddlXns);

  //drop all lob data and descriptor files
  dropLOBHdfsFiles();

  CmpCommon::context()->setIsUninitializedSeabase(TRUE);
  CmpCommon::context()->uninitializedSeabaseErrNum() = -1393;
  CmpCommon::context()->setIsAuthorizationEnabled(FALSE);

  // kill child arkcmp process. It would ensure that a subsequent
  // query, if sent to arkcmp, doesnt get stale information. After restart,
  // the new arkcmp will cause its context to have uninitialized state.
  // Note: TESTEXIT command only works if issued internally.
  ExeCliInterface cliInterface(STMTHEAP, NULL, NULL);
  cliInterface.executeImmediate("SELECT TESTEXIT;");
  cliInterface.clearGlobalDiags();

  return;
}

void CmpSeabaseDDL::dropLOBHdfsFiles()
{
  NAString lobHdfsServer; 
  CmpCommon::getDefault(LOB_HDFS_SERVER,lobHdfsServer,FALSE);
  Int32 lobHdfsPort = CmpCommon::getDefaultNumeric(LOB_HDFS_PORT);
  NAString lobHdfsLoc;
  CmpCommon::getDefault(LOB_STORAGE_FILE_DIR,lobHdfsLoc,FALSE);
  cleanupLOBDataDescFiles(lobHdfsServer,lobHdfsPort,lobHdfsLoc);
}

NABoolean CmpSeabaseDDL::appendErrorObjName(char * errorObjs, 
                                            const char * objName)
{
  if ((strlen(errorObjs) + strlen(objName)) < 1000)
    {
      strcat(errorObjs, objName);
      strcat(errorObjs, " ");
    }
  else if (strlen(errorObjs) < 1005) // errorObjs maxlen = 1010
    {
      strcat(errorObjs, "...");
    }
  
  return TRUE;
}

// ----------------------------------------------------------------------------
// method:  initSeabaseAuthorization
//
// This method:
//   creates privilege manager metadata, if it does not yet exist
//   upgrades privilege manager metadata, if it already exists
//
// Params:
//   cliInterface - a pointer to a CLI helper class 
//   ddlXns - TRUE if DDL transactions is enabled
//   tablesCreated - the list of tables that were created
//   tablesUpgraded - the list of tables that were upgraded
//
// returns
//   0: successful
//  -1: failed
//
// The diags area is populated with any unexpected errors
// ----------------------------------------------------------------------------
short CmpSeabaseDDL::initSeabaseAuthorization(
  ExeCliInterface *cliInterface,
  NABoolean ddlXns,
  std::vector<std::string> &tablesCreated,
  std::vector<std::string> &tablesUpgraded)
{ 
  Lng32 cliRC = 0;
  NABoolean xnWasStartedHere = FALSE;

  if (!ComUser::isRootUserID())
  {
    *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
    return -1;
  }

  if (NOT ddlXns)
  {
    if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere))
    {
      SEABASEDDL_INTERNAL_ERROR("initialize authorization");
      return -1;
    }
  }

  NAString mdLocation;
  CONCAT_CATSCH(mdLocation, getSystemCatalog(), SEABASE_MD_SCHEMA);

  NAString objectsLocation = mdLocation + NAString(".") + SEABASE_OBJECTS;
  NAString authsLocation   = mdLocation + NAString(".") + SEABASE_AUTHS;  
  NAString colsLocation    = mdLocation + NAString(".") + SEABASE_COLUMNS  ; 

  NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);

  PrivMgrCommands privInterface(std::string(privMgrMDLoc.data()), CmpCommon::diags());
  PrivStatus retcode = privInterface.initializeAuthorizationMetadata
    (std::string(objectsLocation.data()), 
     std::string(authsLocation.data()), 
     std::string(colsLocation.data()),
     tablesCreated, tablesUpgraded); 

  if (retcode == STATUS_ERROR)
  {
    // make sure authorization status is FALSE in compiler context 
    GetCliGlobals()->currContext()->setAuthStateInCmpContexts(FALSE, FALSE);
    
    // If not running in DDL transactions, drop any tables were created
    // Ignore any returned errors
    if (NOT ddlXns)
    {
      bool doCleanup = true;
      retcode = privInterface.dropAuthorizationMetadata(doCleanup);
    }

    // Add an error if none yet defined in the diags area
    if ( CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("initialize authorization");

    return -1;
  }

  // If DDL transactions are not enabled, commit the transaction so privmgr 
  // schema exists in other processes
  if (NOT ddlXns)
  {
    endXnIfStartedHere(cliInterface, xnWasStartedHere, 0);
    if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere))
    {
      SEABASEDDL_INTERNAL_ERROR("initialize authorization");
      return -1;
    }
  }

  // change authorization status in compiler contexts
  //CmpCommon::context()->setAuthorizationState (1);
  GetCliGlobals()->currContext()->setAuthStateInCmpContexts(TRUE, TRUE);

  // change authorization status in compiler processes
  cliRC = GetCliGlobals()->currContext()->updateMxcmpSession();
  if (cliRC == -1)
  {
    if ( CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("initialize authorization - updating authorization state failed");
  }

  NABoolean warnings = FALSE;

  // Adjust hive external table ownership - if someone creates external 
  // tables before initializing authorization, the external schemas are 
  // owned by DB__ROOT -> change to DB__HIVEROLE.  
  // Also if you have initialized authorization and created external tables 
  // before the fix for JIRA 1895, rerunning initialize authorization will 
  // fix the metadata inconsistencies
  if (adjustHiveExternalSchemas(cliInterface) != 0)
    warnings = TRUE;

  // If someone initializes trafodion with library management but does not 
  // initialize authorization, then the role DB__LIBMGRROLE has not been 
  // granted to LIBMGR procedures.  Do this now
  cliRC = existsInSeabaseMDTable(cliInterface,
                                 getSystemCatalog(), SEABASE_LIBMGR_SCHEMA, 
                                 SEABASE_LIBMGR_LIBRARY,
                                 COM_LIBRARY_OBJECT, TRUE, FALSE);
  if (cliRC == 1) // library exists
  {
    cliRC = grantLibmgrPrivs(cliInterface);
    if (cliRC == -1)
      warnings = TRUE;
  }
  if (NOT ddlXns)
    endXnIfStartedHere(cliInterface, xnWasStartedHere, cliRC);
  
  // If not able to adjust hive ownership or grant library management privs
  // allow operation to continue but return issues as warnings.
  if (warnings)
  {
    CmpCommon::diags()->negateAllErrors();
    *CmpCommon::diags() << DgSqlCode(CAT_AUTH_COMPLETED_WITH_WARNINGS); 
  }

  return 0;
}

void CmpSeabaseDDL::dropSeabaseAuthorization(
  ExeCliInterface *cliInterface,
  NABoolean doCleanup)
{
  if (!ComUser::isRootUserID())
  {
    *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
    return;
  }

  NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);
  PrivMgrCommands privInterface(std::string(privMgrMDLoc.data()), CmpCommon::diags());
  PrivStatus retcode = privInterface.dropAuthorizationMetadata(doCleanup); 
  if (retcode == STATUS_ERROR)
  {
    if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("drop authorization");
    return;
  }

  // Turn off authorization in compiler contexts
  GetCliGlobals()->currContext()->setAuthStateInCmpContexts(FALSE, FALSE);

  // Turn off authorization in arkcmp processes
  Int32 cliRC = GetCliGlobals()->currContext()->updateMxcmpSession();
  if (cliRC == -1)
  {
    if ( CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("drop authorization - updating authorization state failed");
  }

  return;
}

// ----------------------------------------------------------------------------
// method: insertPrivMgrInfo
//
// this method calls the privilege manager interface to perform privilege
// grants that are required for the object owner.
//
// input:  the object's UID, name, type, owner, schema owner, and creator 
//       
// returns:
//    TRUE if the privileges were successfully inserted (granted)
//    FALSE if an error occurred (ComDiags is set up with the error)
// ----------------------------------------------------------------------------
NABoolean CmpSeabaseDDL::insertPrivMgrInfo(const Int64 objUID,
                                           const NAString &objName,
                                           const ComObjectType objectType,
                                           const Int32 objOwnerID,
                                           const Int32 schemaOwnerID,
                                           const Int32 creatorID)
{
  if (!PrivMgr::isSecurableObject(objectType))
    return TRUE;

  // Traf view privileges are handled differently than other objects. For views,
  // the creator does not automatically get all privileges.  Therefore, view 
  // owner privileges are not granted through this mechanism - 
  // see gatherViewPrivileges for details on how owner privileges are 
  // calculated and granted.
  // Hive views are created outside of trafodion. They are treated like base 
  // table objects.
  // Return TRUE if traf views.
  if (objectType == COM_VIEW_OBJECT)
    {
      ComObjectName viewName(objName, COM_TABLE_NAME);
      if (viewName.getCatalogNamePartAsAnsiString() == TRAFODION_SYSCAT_LIT)
        return TRUE;
    }

  // If authorization is not enabled, return TRUE, no grants are needed
  if (!isAuthorizationEnabled())
   return TRUE;

  // get the username from the objOwnerID
  char username[MAX_USERNAME_LEN+1];
  Int32 lActualLen = 0;
  Int16 status = ComUser::getAuthNameFromAuthID( (Int32) schemaOwnerID 
                                               , (char *)&username
                                               , MAX_USERNAME_LEN+1
                                               , lActualLen );
  if (status != FEOK)
  {
    *CmpCommon::diags() << DgSqlCode(-20235)
                        << DgInt0(status)
                        << DgInt1(schemaOwnerID);
    return FALSE;
  }
  
std::string schemaOwnerGrantee(username);
std::string ownerGrantee;
std::string creatorGrantee;

   if (schemaOwnerID == objOwnerID)
      ownerGrantee = schemaOwnerGrantee;
   else
   {
      char username[MAX_USERNAME_LEN+1];
      Int32 lActualLen = 0;
      Int16 status = ComUser::getAuthNameFromAuthID( (Int32) objOwnerID 
                                                   , (char *)&username
                                                   , MAX_USERNAME_LEN+1
                                                   , lActualLen );
      if (status != FEOK)
      {
        *CmpCommon::diags() << DgSqlCode(-20235)
                            << DgInt0(status)
                            << DgInt1(objOwnerID);
        return FALSE;
      }
      ownerGrantee = username;
   }   

   if (creatorID == objOwnerID)
      creatorGrantee = ownerGrantee;
   else
   {
      char username[MAX_USERNAME_LEN+1];
      Int32 lActualLen = 0;
      Int16 status = ComUser::getAuthNameFromAuthID( (Int32) creatorID 
                                                   , (char *)&username
                                                   , MAX_USERNAME_LEN+1
                                                   , lActualLen );
      if (status != FEOK)
      {
        *CmpCommon::diags() << DgSqlCode(-20235)
                            << DgInt0(status)
                            << DgInt1(creatorID);
        return FALSE;
      }
      creatorGrantee = username;
   }   

  // Grant the ownership privileges

  NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);
  PrivMgrPrivileges privileges(objUID,std::string(objName),SYSTEM_USER, 
                               std::string(privMgrMDLoc.data()),CmpCommon::diags());
  PrivStatus retcode = privileges.grantToOwners(objectType,schemaOwnerID,
                                                schemaOwnerGrantee,objOwnerID,
                                                ownerGrantee,creatorID,
                                                creatorGrantee);
  if (retcode != STATUS_GOOD && retcode != STATUS_WARNING)
    return FALSE;
  return TRUE;
}

// ----------------------------------------------------------------------------
// method: deletePrivMgrInfo
//
// this method calls the privilege manager interface to perform revokes
// when objects are dropped to remove all privileges
//
// input:  the object's UID, name, and type
//       
// returns:
//    TRUE if the privileges were correctly deleted (revoked)
//    FALSE if an error occurred (ComDiags is set up with the error)
// ----------------------------------------------------------------------------
NABoolean CmpSeabaseDDL::deletePrivMgrInfo(const NAString &objectName,
                                           const Int64 objUID, 
                                           const ComObjectType objectType)
{
  if (!PrivMgr::isSecurableObject(objectType))
   return TRUE;

  // Initiate the privilege manager interface class
  NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);
  PrivMgrCommands privInterface(std::string(privMgrMDLoc.data()), CmpCommon::diags());

  // If authorization is not enabled, return TRUE, no grants are needed
  if (!isAuthorizationEnabled())
    return TRUE;

  const std::string objName(objectName.data());
  PrivStatus retcode = 
    privInterface.revokeObjectPrivilege (objUID, objName, -2);
  if (retcode == STATUS_ERROR)
    return FALSE;
  NegateAllErrors(CmpCommon::diags());
  return TRUE;
}

short CmpSeabaseDDL::dropMDTable(ExpHbaseInterface *ehi, const char * tab)
{
  if (!ComUser::isRootUserID())
  {
     *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
     return -1;
  }

  Lng32 retcode = 0;

  HbaseStr hbaseObjStr;
  NAString hbaseObjPrefix = getSystemCatalog();
  hbaseObjPrefix += ".";
  hbaseObjPrefix += SEABASE_MD_SCHEMA;
  hbaseObjPrefix += ".";
  NAString hbaseObject = hbaseObjPrefix + tab;
  hbaseObjStr.val = (char*)hbaseObject.data();
  hbaseObjStr.len = hbaseObject.length();

  retcode = existsInHbase(hbaseObject, ehi);
  if (retcode == 1) // exists
    {
      retcode = dropHbaseTable(ehi, &hbaseObjStr, FALSE, FALSE);
      return retcode;
    }

  return 0;
}

void CmpSeabaseDDL::updateVersion()
{
  if (!ComUser::isRootUserID())
    {
       *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
       return;
    }

  Lng32 retcode = 0;
  Lng32 cliRC = 0;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1393))
    {
      *CmpCommon::diags() << DgSqlCode(-1393);
      return;
    }

  Int64 softMajorVersion;
  Int64 softMinorVersion;
  Int64 softUpdVersion;
  getSystemSoftwareVersion(softMajorVersion, softMinorVersion, softUpdVersion);

  char queryBuf[5000];
  
  Int64 updateTime = NA_JulianTimestamp();

  str_sprintf(queryBuf, "update %s.\"%s\".%s set major_version = %ld, minor_version = %ld, init_time = %ld, comment = 'update version'  where version_type = 'SOFTWARE' ",
              getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VERSIONS,
              softMajorVersion, softMinorVersion,
              updateTime);

  NABoolean xnWasStartedHere = FALSE;
  if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere))
    return;
  
  cliRC = cliInterface.executeImmediate(queryBuf);
  if (cliRC < 0)
    {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
    }
  
  if (endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC) < 0)
    return;

}

// truncate is a non-transactional operation. Caller need to restore back
// the truncated table if an error occurs.
short CmpSeabaseDDL::truncateHbaseTable(const NAString &catalogNamePart, 
                                        const NAString &schemaNamePart, 
                                        const NAString &objectNamePart,
                                        NATable * naTable,
                                        ExpHbaseInterface * ehi)
{
  Lng32 retcode = 0;

  const NAString extNameForHbase = 
    catalogNamePart + "." + schemaNamePart + "." + objectNamePart;

  HbaseStr hbaseTable;
  hbaseTable.val = (char*)extNameForHbase.data();
  hbaseTable.len = extNameForHbase.length();

  // if salted table, preserve splits.
  if (naTable->hasSaltedColumn())
    retcode = ehi->truncate(hbaseTable, TRUE, TRUE);
  else
    retcode = ehi->truncate(hbaseTable, FALSE, TRUE);
  if (retcode)
    {
      *CmpCommon::diags() << DgSqlCode(-8448)
                          << DgString0((char*)"ExpHbaseInterface::truncate()")
                          << DgString1(getHbaseErrStr(-retcode))
                          << DgInt0(-retcode)
                          << DgString2((char*)GetCliGlobals()->getJniErrorStr());

      processReturn();
      return -1;
    }

  return 0;
}

void CmpSeabaseDDL::purgedataHbaseTable(DDLExpr * ddlExpr,
                                       NAString &currCatName, NAString &currSchName)
{
  Lng32 cliRC;
  Lng32 retcode = 0;
  NABoolean xnWasStartedHere = FALSE;

  CorrName &purgedataTableName = ddlExpr->purgedataTableName();
  NAString tabName = ddlExpr->getQualObjName();

  ComObjectName tableName(tabName, COM_TABLE_NAME);
  ComAnsiNamePart currCatAnsiName(currCatName);
  ComAnsiNamePart currSchAnsiName(currSchName);
  tableName.applyDefaults(currCatAnsiName, currSchAnsiName);

  NAString catalogNamePart = tableName.getCatalogNamePartAsAnsiString();
  NAString schemaNamePart = tableName.getSchemaNamePartAsAnsiString(TRUE);
  NAString objectNamePart = tableName.getObjectNamePartAsAnsiString(TRUE);
  const NAString extTableName = tableName.getExternalName(TRUE);
  const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart;

  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());
  ExpHbaseInterface * ehi = allocEHI();
  if (ehi == NULL)
    {
      processReturn();
      return;
    }

  if ((isSeabaseReservedSchema(tableName)) &&
      (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)))
    {
      *CmpCommon::diags() << DgSqlCode(-CAT_USER_CANNOT_DROP_SMD_TABLE)
                          << DgTableName(extTableName);
      deallocEHI(ehi); 

      processReturn();

      return;
    }

  // special tables, like index, can only be purged in internal mode with special
  // flag settings. Otherwise, it can make database inconsistent.
  if ((purgedataTableName.isSpecialTable()) &&
     (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)))
    {
      *CmpCommon::diags()
        << DgSqlCode(-1010);
      
      processReturn();
      
      return;
    }

  ActiveSchemaDB()->getNATableDB()->useCache();

  BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/);
  CorrName cn(tableName.getObjectNamePart().getInternalName(),
              STMTHEAP,
              tableName.getSchemaNamePart().getInternalName(),
              tableName.getCatalogNamePart().getInternalName());
  cn.setSpecialType(purgedataTableName);
  NATable *naTable = bindWA.getNATable(cn); 
  if (naTable == NULL || bindWA.errStatus())
    {
      processReturn();

      return;
    }

  // Verify that the current user has authority to perform operation
  if (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL) && isAuthorizationEnabled())
    {
      PrivMgrUserPrivs* privs = naTable->getPrivInfo();
      if (privs == NULL)
        {
          *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_RETRIEVE_PRIVS);
          deallocEHI(ehi);
          processReturn();
          return;
        }

      NABoolean privCheckFailed = FALSE;
      if (!privs->hasSelectPriv())
        {
           privCheckFailed = TRUE;
           *CmpCommon::diags() << DgSqlCode( -4481 )
                               << DgString0( "SELECT" )
                               << DgString1( extTableName );
        }

      if (!privs->hasDeletePriv())
        {
          privCheckFailed = TRUE;
          *CmpCommon::diags() << DgSqlCode( -4481 )
                              << DgString0( "DELETE" )
                              << DgString1( extTableName );
        }

      if (privCheckFailed)
        {
          deallocEHI(ehi);
          processReturn();
          return;
        }
    }

  // cannot purgedata a view
  if (naTable->getViewText())
    {
      *CmpCommon::diags()
        << DgSqlCode(-1010);
      
      processReturn();
      
      return;
    }

  if (naTable->getUniqueConstraints().entries() > 0)
    {
      const AbstractRIConstraintList &uniqueList = naTable->getUniqueConstraints();

      for (Int32 i = 0; i < uniqueList.entries(); i++)
        {
          AbstractRIConstraint *ariConstr = uniqueList[i];
          
          if (ariConstr->getOperatorType() != ITM_UNIQUE_CONSTRAINT)
            continue;
          
          UniqueConstraint * uniqConstr = (UniqueConstraint*)ariConstr;

          if (uniqConstr->hasRefConstraintsReferencingMe())
            {
              NAString reason("Reason: Foreign Key constraints from other tables are referencing this table");
 
              *CmpCommon::diags()
                << DgSqlCode(-1425)
                << DgTableName(extTableName)
                << DgString0(reason.data());
              
              deallocEHI(ehi); 
              
              processReturn();
              
              return;
            }

        } // for      
    }

  retcode = updateObjectValidDef(&cliInterface, 
                                 catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(),
                                 COM_BASE_TABLE_OBJECT_LIT, COM_NO_LIT);
  if (retcode)
    {
      deallocEHI(ehi); 
      
      processReturn();
      
      return;
    }
                                 
  NABoolean ddlXns = ddlExpr->ddlXns();
  if (truncateHbaseTable(catalogNamePart, schemaNamePart, objectNamePart,
                         naTable, ehi))
    {
      deallocEHI(ehi); 
      
      processReturn();
      
      return;
    }

  if (naTable->hasSecondaryIndexes()) // user indexes
    {
      const NAFileSetList &indexList = naTable->getIndexList();
      
      // purgedata from all indexes
      for (Int32 i = 0; i < indexList.entries(); i++)
        {
          const NAFileSet * naf = indexList[i];
          if (naf->getKeytag() == 0)
            continue;
          
          const QualifiedName &qn = naf->getFileSetName();
          
          NAString catName = qn.getCatalogName();
          NAString schName = qn.getSchemaName();
          NAString idxName = qn.getObjectName();

          retcode = truncateHbaseTable(catName, schName, idxName,
                                       naTable, ehi);
          if (retcode)
            {
              deallocEHI(ehi); 
              processReturn();
              
              return;
            }
          
        } // for
    } // secondary indexes

  retcode = updateObjectValidDef(&cliInterface, 
                                 catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(),
                                 COM_BASE_TABLE_OBJECT_LIT, COM_YES_LIT);
  if (retcode)
    {
      deallocEHI(ehi); 
      
      processReturn();
      
      return;
    }

  return;
}

short CmpSeabaseDDL::executeSeabaseDDL(DDLExpr * ddlExpr, ExprNode * ddlNode,
                                       NAString &currCatName, NAString &currSchName,
                                       CmpDDLwithStatusInfo *dws)
{
  Lng32 cliRC = 0;
  ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());

  // error accessing hbase. Return.
  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (CmpCommon::context()->uninitializedSeabaseErrNum() == -1398))
    {
      *CmpCommon::diags() << DgSqlCode(CmpCommon::context()->uninitializedSeabaseErrNum())
                          << DgInt0(CmpCommon::context()->hbaseErrNum())
                          << DgString0(CmpCommon::context()->hbaseErrStr());
      
      return -1;
    }

  NABoolean xnWasStartedHere = FALSE;
  NABoolean ignoreUninitTrafErr = FALSE;

  if ((ddlExpr) &&
      ((ddlExpr->initHbase()) ||
       (ddlExpr->createMDViews()) ||
       (ddlExpr->dropMDViews()) ||
       (ddlExpr->createRepos()) ||
       (ddlExpr->dropRepos()) ||
       (ddlExpr->upgradeRepos()) ||
       (ddlExpr->addSchemaObjects()) ||
       (ddlExpr->createLibmgr()) ||
       (ddlExpr->updateVersion())))
    ignoreUninitTrafErr = TRUE;

  if ((Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) &&
      (CmpCommon::context()->isUninitializedSeabase()))
    {
      ignoreUninitTrafErr = TRUE;
    }

  if ((CmpCommon::context()->isUninitializedSeabase()) &&
      (NOT ignoreUninitTrafErr))
    {
      *CmpCommon::diags() << DgSqlCode(CmpCommon::context()->uninitializedSeabaseErrNum());
      return -1;
    }

  if (sendAllControlsAndFlags())
    {
      CMPASSERT(0);
      return -1;
    }
  
  if (dws)
    {
      if (dws->getMDcleanup())
        {
          StmtDDLCleanupObjects * co = 
            (ddlNode ? ddlNode->castToStmtDDLNode()->castToStmtDDLCleanupObjects()
             : NULL);

          CmpSeabaseMDcleanup cmpSBDC(STMTHEAP);

           cmpSBDC.cleanupObjects(co, currCatName, currSchName, dws);

           return 0;
         }
    }

  NABoolean startXn = FALSE;
  NABoolean ddlXns = FALSE;
  if (ddlExpr->ddlXnsInfo(ddlXns, startXn))
    return -1;
  
  if (startXn)
    {
      if (beginXnIfNotInProgress(&cliInterface, xnWasStartedHere))
        goto label_return;
    }

  if (ddlExpr->initHbase()) 
    {
      initSeabaseMD(ddlExpr->ddlXns(), ddlExpr->minimal());
    }
  else if (ddlExpr->dropHbase())
    {
      dropSeabaseMD(ddlExpr->ddlXns());
    }
  else if (ddlExpr->createMDViews())
    {
      createSeabaseMDviews();
    }
  else if (ddlExpr->dropMDViews())
    {
      dropSeabaseMDviews();
    }
  else if (ddlExpr->initAuth())
    {
      std::vector<std::string> tablesCreated;
      std::vector<std::string> tablesUpgraded;

      // Can ignore status returned, diags area contains any unexpected errors
      initSeabaseAuthorization(&cliInterface, ddlExpr->ddlXns(),
                               tablesCreated, tablesUpgraded);

#ifdef _DEBUG
      // Do we want to display this information?  Base it on a cqd or envvar?
      // Do it in debug mode or log it somewhere instead?
      NAString msgBuf ("tables created: ");
      if (tablesCreated.size() == 0)
        msgBuf += "none";
      else
      {
        for (size_t i = 0; i < tablesCreated.size(); i++)
          msgBuf += tablesCreated[i].c_str() + NAString(" ");
      }
    
      msgBuf += "\ntables upgraded: ";
      if (tablesUpgraded.size() == 0)
        msgBuf += "none";
      else
      {
        for (size_t i = 0; i < tablesUpgraded.size(); i++)
          msgBuf += tablesUpgraded[i].c_str() + NAString(" ");
      }
   
      cout << msgBuf.data() << endl;
#endif
    }
  else if (ddlExpr->dropAuth())
    {
      dropSeabaseAuthorization(&cliInterface, FALSE);
    }
  else if (ddlExpr->cleanupAuth())
    {
       dropSeabaseAuthorization(&cliInterface, TRUE);
    }
  else if (ddlExpr->addSchemaObjects())
    {
      createSeabaseSchemaObjects();
    }
  else if (ddlExpr->createLibmgr())
    {
      createSeabaseLibmgr(&cliInterface);
    }
  else if (ddlExpr->dropLibmgr())
    {
      dropSeabaseLibmgr(&cliInterface);
    }
  else if (ddlExpr->upgradeLibmgr())
    {
      upgradeSeabaseLibmgr(&cliInterface);
    }
  else if (ddlExpr->updateVersion())
    {
      updateVersion();
    }
  else if (ddlExpr->purgedata())
    {
      purgedataHbaseTable(ddlExpr, currCatName, currSchName);
    }
  else if ((ddlExpr->createRepos()) ||
           (ddlExpr->dropRepos()) ||
           (ddlExpr->upgradeRepos()))
    {
      if (!ComUser::isRootUserID())
          *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
      else
        processRepository(ddlExpr->createRepos(), 
                          ddlExpr->dropRepos(), 
                          ddlExpr->upgradeRepos());
    }
  else
    {
      CMPASSERT(ddlNode);
      
      if (ddlNode->getOperatorType() == DDL_CREATE_TABLE)
        {
          // create hbase table
          StmtDDLCreateTable * createTableParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateTable();
          
          if ((createTableParseNode->getAddConstraintUniqueArray().entries() > 0) ||
              (createTableParseNode->getAddConstraintRIArray().entries() > 0) ||
              (createTableParseNode->getAddConstraintCheckArray().entries() > 0))
            createSeabaseTableCompound(createTableParseNode, currCatName, currSchName);
          else
            {
              createSeabaseTable(createTableParseNode, currCatName, currSchName);

              if (((getenv("SQLMX_REGRESS")) ||
                   (CmpCommon::getDefault(TRAF_AUTO_CREATE_SCHEMA) == DF_ON)) &&
                  (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_)) &&
                  (CmpCommon::diags()->mainSQLCODE() == -CAT_SCHEMA_DOES_NOT_EXIST_ERROR))
                {
                  ComObjectName tableName(createTableParseNode->getTableName());
                  ComAnsiNamePart currCatAnsiName(currCatName);
                  ComAnsiNamePart currSchAnsiName(currSchName);
                  tableName.applyDefaults(currCatAnsiName, currSchAnsiName);
                  
                  const NAString schemaNamePart = 
                    tableName.getSchemaNamePartAsAnsiString(TRUE);

                  char query[1000];
                  if ((getenv("SQLMX_REGRESS")) &&
                      (schemaNamePart == SEABASE_REGRESS_DEFAULT_SCHEMA))
                    {
                      CmpCommon::diags()->clear();
                      str_sprintf(query, "create shared schema %s.%s",
                                  TRAFODION_SYSCAT_LIT, 
                                  SEABASE_REGRESS_DEFAULT_SCHEMA);
                      cliRC = cliInterface.executeImmediate(query);
                      if (cliRC >= 0)
                        {
                          str_sprintf(query, "upsert into %s.\"%s\".%s values ('SCHEMA ', '%s.%s ', 'inserted during regressions run', 0);",
                                      TRAFODION_SYSCAT_LIT, 
                                      SEABASE_MD_SCHEMA,
                                      SEABASE_DEFAULTS,
                                      TRAFODION_SYSCAT_LIT,
                                      SEABASE_REGRESS_DEFAULT_SCHEMA);
                          cliRC = cliInterface.executeImmediate(query);
                          if (cliRC >= 0)
                            {
                              createSeabaseTable(createTableParseNode, currCatName, currSchName);
                            }
                        }
                    } // if
                  else if (CmpCommon::getDefault(TRAF_AUTO_CREATE_SCHEMA) == DF_ON)
                    {
                      // create this schema
                      CmpCommon::diags()->clear();
                      str_sprintf(query, "create schema %s.\"%s\";",
                                  TRAFODION_SYSCAT_LIT, schemaNamePart.data());
                      cliRC = cliInterface.executeImmediate(query);
                      if (cliRC >= 0)
                        {
                          createSeabaseTable(createTableParseNode, currCatName, currSchName);
                        }
                    }
                }     
            }
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_HBASE_TABLE)
        {
          // create hbase table
          StmtDDLCreateHbaseTable * createTableParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateHbaseTable();
          
          createNativeHbaseTable(&cliInterface, createTableParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_TABLE)
        {
          // drop seabase table
          StmtDDLDropTable * dropTableParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropTable();
          
          dropSeabaseTable(dropTableParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_HBASE_TABLE)
        {
          // drop hbase table
          StmtDDLDropHbaseTable * dropTableParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropHbaseTable();
          
          dropNativeHbaseTable(&cliInterface, dropTableParseNode, currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() == DDL_CREATE_INDEX)
        {
          // create seabase index
          StmtDDLCreateIndex * createIndexParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateIndex();
          
          createSeabaseIndex(createIndexParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_POPULATE_INDEX)
        {
          // populate seabase index
          StmtDDLPopulateIndex * populateIndexParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLPopulateIndex();
          
          populateSeabaseIndex(populateIndexParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_INDEX)
        {
          // drop seabase table
          StmtDDLDropIndex * dropIndexParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropIndex();
          
          dropSeabaseIndex(dropIndexParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ADD_COLUMN)
        {
          StmtDDLAlterTableAddColumn * alterAddColNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableAddColumn();
          
          alterSeabaseTableAddColumn(alterAddColNode, 
                                   currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_DROP_COLUMN)
        {
          StmtDDLAlterTableDropColumn * alterDropColNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableDropColumn();
          
          alterSeabaseTableDropColumn(alterDropColNode, 
                                                    currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY)
        {
          StmtDDLAddConstraint * alterAddConstraint =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAddConstraint();
          
          alterSeabaseTableAddPKeyConstraint(alterAddConstraint, 
                                             currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ADD_CONSTRAINT_UNIQUE)
        {
          StmtDDLAddConstraint * alterAddConstraint =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAddConstraint();
          
          alterSeabaseTableAddUniqueConstraint(alterAddConstraint, 
                                               currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL_INTEGRITY)
        {
          StmtDDLAddConstraint * alterAddConstraint =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAddConstraint();
          
          alterSeabaseTableAddRIConstraint(alterAddConstraint, 
                                           currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ADD_CONSTRAINT_CHECK)
        {
          StmtDDLAddConstraint * alterAddConstraint =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAddConstraint();
          
          alterSeabaseTableAddCheckConstraint(alterAddConstraint, 
                                           currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_DROP_CONSTRAINT)
        {
          StmtDDLDropConstraint * alterDropConstraint =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropConstraint();
          
          alterSeabaseTableDropConstraint(alterDropConstraint, 
                                         currCatName, currSchName);
        }

      else if ((ddlNode->getOperatorType() == DDL_ALTER_TABLE_DISABLE_INDEX) ||
               (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ENABLE_INDEX))
        {

          NABoolean allIndexes = FALSE;
          NABoolean allUniquesOnly = FALSE;
          StmtDDLAlterTableDisableIndex * disableIdx = ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableDisableIndex();
          NAString tabNameNAS ;
          if (disableIdx)
          {
            allIndexes = disableIdx->getAllIndexes();
            tabNameNAS = disableIdx->getTableName();
            allUniquesOnly = disableIdx->getAllUniqueIndexes();
          }
          else
          {
            StmtDDLAlterTableEnableIndex * enableIdx = ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableEnableIndex();
            allIndexes = enableIdx->getAllIndexes() ;
            tabNameNAS = enableIdx->getTableName();
            allUniquesOnly = enableIdx->getAllUniqueIndexes();
          }

          if (!(allIndexes || allUniquesOnly))
            alterSeabaseTableDisableOrEnableIndex(ddlNode,
                                                currCatName,
                                                currSchName);
          else
          {
            alterSeabaseTableDisableOrEnableAllIndexes(ddlNode,
                                                     currCatName,
                                                     currSchName,
                                                       (NAString &) tabNameNAS,
                                                       allUniquesOnly);
          }
        }
     else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_RENAME)
        {
          StmtDDLAlterTableRename * alterRenameTable =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableRename();

          renameSeabaseTable(alterRenameTable,
                                  currCatName, currSchName);
        }
     else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_STORED_DESC)
        {
          StmtDDLAlterTableStoredDesc * alterStoredDesc =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableStoredDesc();

          alterSeabaseTableStoredDesc(alterStoredDesc, currCatName, currSchName);
        }
     else if (ddlNode->getOperatorType() == DDL_ALTER_TABLE_ALTER_HBASE_OPTIONS)
        {
          StmtDDLAlterTableHBaseOptions * athbo =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableHBaseOptions();

          alterSeabaseTableHBaseOptions(athbo, currCatName, currSchName);
        }  
      else if (ddlNode->getOperatorType() == DDL_ALTER_INDEX_ALTER_HBASE_OPTIONS)
        {
          StmtDDLAlterIndexHBaseOptions * aihbo =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterIndexHBaseOptions();

          alterSeabaseIndexHBaseOptions(aihbo, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_VIEW)
        {
          // create seabase view
          StmtDDLCreateView * createViewParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateView();
          
          createSeabaseView(createViewParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_VIEW)
        {
          // drop seabase table
          StmtDDLDropView * dropViewParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropView();
          
          dropSeabaseView(dropViewParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_REGISTER_USER)
        {
         StmtDDLRegisterUser *registerUserParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLRegisterUser();
          StmtDDLRegisterUser::RegisterUserType ruType =
                registerUserParseNode->getRegisterUserType();
          if (ruType == StmtDDLRegisterUser::REGISTER_USER)
            registerSeabaseUser(registerUserParseNode);
          else
            unregisterSeabaseUser(registerUserParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_REG_OR_UNREG_OBJECT)
        {
         StmtDDLRegOrUnregObject *regOrUnregObjectParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLRegOrUnregObject();
         regOrUnregNativeObject(
              regOrUnregObjectParseNode, currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_ROLE)
        {
         StmtDDLCreateRole *createRoleParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateRole();
            
         CmpSeabaseDDLrole role(getSystemCatalog(),getMDSchema());
         
         if (createRoleParseNode->isCreateRole())
            role.createRole(createRoleParseNode);
         else
            role.dropRole(createRoleParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_USER)
        {
         StmtDDLAlterUser *alterUserParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterUser();
          alterSeabaseUser(alterUserParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_REGISTER_COMPONENT)
        {
         StmtDDLRegisterComponent *registerComponentParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLRegisterComponent();
         registerSeabaseComponent(registerComponentParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_COMPONENT_PRIVILEGE)
        {
         StmtDDLCreateComponentPrivilege *createComponentOperationParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateComponentPrivilege();
         createSeabaseComponentOperation(getSystemCatalog(),
                                         createComponentOperationParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_COMPONENT_PRIVILEGE)
        {
         StmtDDLDropComponentPrivilege *dropComponentOperationParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropComponentPrivilege();
         dropSeabaseComponentOperation(getSystemCatalog(),
                                       dropComponentOperationParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_GRANT_COMPONENT_PRIVILEGE)
        {
         StmtDDLGrantComponentPrivilege *grantComponentPrivilegeParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLGrantComponentPrivilege();
         grantSeabaseComponentPrivilege(getSystemCatalog(),
                                        grantComponentPrivilegeParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_REVOKE_COMPONENT_PRIVILEGE)
        {
         StmtDDLRevokeComponentPrivilege *revokeComponentPrivilegeParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLRevokeComponentPrivilege();
         revokeSeabaseComponentPrivilege(getSystemCatalog(),
                                         revokeComponentPrivilegeParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_GRANT_ROLE)
        {
         StmtDDLRoleGrant *grantRoleParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLRoleGrant();   
         grantRevokeSeabaseRole(getSystemCatalog(),grantRoleParseNode);
        }
      else if ((ddlNode->getOperatorType() == DDL_GRANT) ||
               (ddlNode->getOperatorType() == DDL_REVOKE))
        {
          // grant/revoke seabase table
          StmtDDLNode * stmtDDLParseNode =
            ddlNode->castToStmtDDLNode();
          
          seabaseGrantRevoke(stmtDDLParseNode,
                             (ddlNode->getOperatorType() == DDL_GRANT 
                              ? TRUE : FALSE),
                             currCatName, currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_GIVE_ALL)
        {
         StmtDDLGiveAll *giveAllParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLGiveAll();   
         giveSeabaseAll(giveAllParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_GIVE_OBJECT)
        {
         StmtDDLGiveObject *giveObjectParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLGiveObject();   
         giveSeabaseObject(giveObjectParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_GIVE_SCHEMA)
        {
         StmtDDLGiveSchema *giveSchemaParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLGiveSchema();   
         giveSeabaseSchema(giveSchemaParseNode,currCatName);
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_SCHEMA)
        {
          StmtDDLCreateSchema * createSchemaParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateSchema();
            
          createSeabaseSchema(createSchemaParseNode,currCatName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_SCHEMA)
        {
          // drop all tables in schema
          StmtDDLDropSchema * dropSchemaParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropSchema();
          
          dropSeabaseSchema(dropSchemaParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_ALTER_SCHEMA)
        {
          StmtDDLAlterSchema * alterSchemaParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLAlterSchema();
          
          alterSeabaseSchema(alterSchemaParseNode);
        }
      else if (ddlNode->getOperatorType() == DDL_CREATE_LIBRARY)
        {
          // create seabase library
          StmtDDLCreateLibrary * createLibraryParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateLibrary();
          
          createSeabaseLibrary(createLibraryParseNode, currCatName, 
                               currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_LIBRARY)
        {
          // drop seabase library
          StmtDDLDropLibrary * dropLibraryParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropLibrary();
          
          dropSeabaseLibrary(dropLibraryParseNode, currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() == DDL_ALTER_LIBRARY)
         {
           // create seabase library
           StmtDDLAlterLibrary * alterLibraryParseNode =
             ddlNode->castToStmtDDLNode()->castToStmtDDLAlterLibrary();
           
           alterSeabaseLibrary(alterLibraryParseNode, currCatName, 
                               currSchName);
         }
      else if (ddlNode->getOperatorType() == DDL_CREATE_ROUTINE)
        {
          // create seabase routine
          StmtDDLCreateRoutine * createRoutineParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateRoutine();
          
          createSeabaseRoutine(createRoutineParseNode, currCatName, 
                               currSchName);
        }
      else if (ddlNode->getOperatorType() == DDL_DROP_ROUTINE)
        {
          // drop seabase routine
          StmtDDLDropRoutine * dropRoutineParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLDropRoutine();
          
          dropSeabaseRoutine(dropRoutineParseNode, currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() == DDL_CREATE_SEQUENCE)
        {
          // create seabase sequence
          StmtDDLCreateSequence * createSequenceParseNode =
            ddlNode->castToStmtDDLNode()->castToStmtDDLCreateSequence();
          
          if (createSequenceParseNode->isAlter())
            alterSeabaseSequence(createSequenceParseNode, currCatName, 
                                 currSchName);
          else
            createSeabaseSequence(createSequenceParseNode, currCatName, 
                                  currSchName);
        }
       else if (ddlNode->getOperatorType() == DDL_DROP_SEQUENCE)
         {
           // drop seabase sequence
           StmtDDLDropSequence * dropSequenceParseNode =
             ddlNode->castToStmtDDLNode()->castToStmtDDLDropSequence();
           
           dropSeabaseSequence(dropSequenceParseNode, currCatName, currSchName);
         }
       else if (ddlNode->getOperatorType() ==  DDL_ALTER_TABLE_ALTER_COLUMN_SET_SG_OPTION)
         {
           StmtDDLAlterTableAlterColumnSetSGOption * alterIdentityColNode =
             ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableAlterColumnSetSGOption();
           
           alterSeabaseTableAlterIdentityColumn(alterIdentityColNode, 
                                                currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() ==  DDL_ALTER_TABLE_ALTER_COLUMN_DATATYPE)
         {
           StmtDDLAlterTableAlterColumnDatatype * alterColNode =
             ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableAlterColumnDatatype();
           
           alterSeabaseTableAlterColumnDatatype(alterColNode, 
                                                currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() ==  DDL_ALTER_TABLE_ALTER_COLUMN_RENAME)
         {
           StmtDDLAlterTableAlterColumnRename * alterColNode =
             ddlNode->castToStmtDDLNode()->castToStmtDDLAlterTableAlterColumnRename();
           
           alterSeabaseTableAlterColumnRename(alterColNode, 
                                              currCatName, currSchName);
        }
       else if (ddlNode->getOperatorType() ==  DDL_CLEANUP_OBJECTS)
         {
           StmtDDLCleanupObjects * co = 
             ddlNode->castToStmtDDLNode()->castToStmtDDLCleanupObjects();

           CmpSeabaseMDcleanup cmpSBDC(STMTHEAP);

           cmpSBDC.cleanupObjects(co, currCatName, currSchName, dws);
        }
      else if (ddlNode->getOperatorType() ==  DDL_COMMENT_ON)
        {
           StmtDDLCommentOn * comment = 
             ddlNode->castToStmtDDLNode()->castToStmtDDLCommentOn();

           doSeabaseCommentOn(comment, currCatName, currSchName);
        }
      else
        {
           // some operator type that this routine doesn't support yet
           *CmpCommon::diags() << DgSqlCode(-CAT_UNSUPPORTED_COMMAND_ERROR);  
        }
       
    } // else
  
label_return:

  restoreAllControlsAndFlags();

  if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_))
    {
      cliRC = -1;

      // some ddl stmts are executed as multiple sub statements.
      // some of those sub stmts may abort the enclosing xn started here
      // in case of an error, and add an error condition that the xn
      // was aborted.
      // remove that error condition from the diags area. But dont do it
      // if it is the main error.
      //      if (xnWasStartedHere && 
      if (CmpCommon::diags()->mainSQLCODE() != -CLI_VALIDATE_TRANSACTION_ERROR)
        {
          CollIndex i = 
            CmpCommon::diags()->returnIndex(-CLI_VALIDATE_TRANSACTION_ERROR);
          if (i != NULL_COLL_INDEX)
            CmpCommon::diags()->deleteError(i);
        }
    }

  if (endXnIfStartedHere(&cliInterface, xnWasStartedHere, cliRC) < 0)
    return -1;
  
  return 0;
}

void CmpSeabaseDDL::registerSeabaseUser(StmtDDLRegisterUser * authParseNode)
{
  CmpSeabaseDDLuser user(getSystemCatalog(),getMDSchema());
  user.registerUser(authParseNode);
}

void CmpSeabaseDDL::alterSeabaseUser(StmtDDLAlterUser * authParseNode)
{
  CmpSeabaseDDLuser user(getSystemCatalog(),getMDSchema());
  user.alterUser(authParseNode);
}

void CmpSeabaseDDL::unregisterSeabaseUser(StmtDDLRegisterUser * authParseNode)
{
  CmpSeabaseDDLuser user(getSystemCatalog(),getMDSchema());
  user.unregisterUser(authParseNode);
}

// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::giveSeabaseAll                                   *
// *                                                                           *
// *   This function transfers ownership of all SQL objects owned by one       *
// * authID to another authID.                                                 *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <giveAllParseNode>           StmtDDLGiveAll *                   In       *
// *    is a pointer to parse node containing the data for the GIVE ALL command*
// *                                                                           *
// *****************************************************************************
void CmpSeabaseDDL::giveSeabaseAll(StmtDDLGiveAll * giveAllParseNode)

{

//
// A user cannot give away all of their own objects unless they have the 
// ALTER privilege.  
//

   if (!isDDLOperationAuthorized(SQLOperation::ALTER,NA_UserIdDefault,
                                 NA_UserIdDefault))
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
      return;
   }

int32_t fromOwnerID = -1;

   if (ComUser::getAuthIDFromAuthName(giveAllParseNode->getFromID().data(),
                                      fromOwnerID) != 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                          << DgString0(giveAllParseNode->getFromID().data());
      return;
   }

int32_t toOwnerID = -1;

   if (ComUser::getAuthIDFromAuthName(giveAllParseNode->getToID().data(),
                                      toOwnerID) != 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                          << DgString0(giveAllParseNode->getToID().data());
      return;
   }
   
// If the FROM and TO IDs are the same, just return.

   if (fromOwnerID == toOwnerID)
      return;
   
char buf[4000];
ExeCliInterface cliInterface(STMTHEAP, 0, NULL,
    CmpCommon::context()->sqlSession()->getParentQid());
Lng32 cliRC = 0;

   str_sprintf(buf,"UPDATE %s.\"%s\".%s "
                   "SET object_owner = %d "
                   "WHERE object_owner = %d",
               getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS,
               toOwnerID,fromOwnerID);
   cliRC = cliInterface.executeImmediate(buf);
   if (cliRC < 0)
   {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
   }  
              
// Verify all objects in the database have been given to the new owner.   
   str_sprintf(buf,"SELECT COUNT(*) "
                   "FROM %s.\"%s\".%s "
                   "WHERE object_owner = %d "
                   "FOR READ COMMITTED ACCESS",
               getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS,
               fromOwnerID);
               
int32_t length = 0;
Int64 rowCount = 0;

   cliRC = cliInterface.executeImmediate(buf,(char*)&rowCount,&length,FALSE);
  
   if (cliRC < 0)
   {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
   }
   
   if (rowCount > 0)
   {
      SEABASEDDL_INTERNAL_ERROR("Not all objects were given");
      return;
   }

}
//******************** End of CmpSeabaseDDL::giveSeabaseAll ********************


// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::giveSeabaseObject                                *
// *                                                                           *
// *   This function transfers ownership of a SQL object to another authID.    *
// * authID                                                                    *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <giveObjectParseNode>        StmtDDLGiveObject *                In       *
// *    is a pointer to parse node containing the data for the GIVE command.   *
// *                                                                           *
// *****************************************************************************
void CmpSeabaseDDL::giveSeabaseObject(StmtDDLGiveObject * giveObjectParseNode)
{

   *CmpCommon::diags() << DgSqlCode(-CAT_UNSUPPORTED_COMMAND_ERROR);

}
//****************** End of CmpSeabaseDDL::giveSeabaseObject *******************



// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::dropOneTableorView                               *
// *                                                                           *
// *    Drops a table or view and all its dependent objects.                   *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <cliInterface>                  ExeCliInterface &               In       *
// *    is a reference to an Executor CLI interface handle.                    *
// *                                                                           *
// *  <objectName>                    const char *                    In       *
// *    is the fully quailified name of the object to drop.                    *
// *                                                                           *
// *  <objectType>                    ComObjectType                   In       *
// *    is the type of object (Table or view) to drop.                         *
// *                                                                           *
// *  <isVolatile>                    bool                            In       *
// *    is true if the object is volatile or part of a volatile schema.        *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: bool                                                             *
// *                                                                           *
// * true: Could not drop table/view or one of its dependent objects.          *
// * false: Drop successful or could not set CQD for NATable cache reload.     *
// *                                                                           *
// *****************************************************************************
bool CmpSeabaseDDL::dropOneTableorView(
   ExeCliInterface & cliInterface,
   const char * objectName,
   ComObjectType objectType,
   bool isVolatile)
   
{

char buf [1000];

bool someObjectsCouldNotBeDropped = false;

char volatileString[20] = {0};
char objectTypeString[20] = {0};

   switch (objectType)
   {
      case COM_BASE_TABLE_OBJECT:
         strcpy(objectTypeString,"TABLE");
         break;
      case COM_VIEW_OBJECT:
         strcpy(objectTypeString,"VIEW");
         break;
      default:   
         SEABASEDDL_INTERNAL_ERROR("Unsupported object type in CmpSeabaseDDL::dropOneTableorView");
   }   

   if (isVolatile)
      strcpy(volatileString,"VOLATILE");

   str_sprintf(buf,"DROP %s %s %s CASCADE",
               volatileString,objectTypeString,objectName);
               
   // Turn on the internal query parser flag; note that when
   // this object is destroyed, the flags will be reset to
   // their original state
   PushAndSetSqlParserFlags savedParserFlags(INTERNAL_QUERY_FROM_EXEUTIL);
   Lng32 cliRC = 0;

   try
   {                      
      cliRC = cliInterface.executeImmediate(buf);
   }
   catch (...)
   {      
      throw;
   }
   
   if (cliRC < 0 && cliRC != -CAT_OBJECT_DOES_NOT_EXIST_IN_TRAFODION)
      someObjectsCouldNotBeDropped = true;

   return someObjectsCouldNotBeDropped;
   
}
//****************** End of CmpSeabaseDDL::dropOneTableorView ******************


// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::verifyDDLCreateOperationAuthorized               *
// *                                                                           *
// *   This member function determines if a user has the authority to perform  *
// * a specific DDL operation in a specified schema.                           *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <cliInterface>                ExeCliInterface &                 In       *
// *    is a pointer to an Executor CLI interface handle.                      *
// *                                                                           *
// *  <operation>                  SQLOperation                       In       *
// *    is operation the user wants to perform.                                *
// *                                                                           *
// *  <catalogName>                const NAString &                   In       *
// *    is the name of the catalog where the object is to be created.          *
// *                                                                           *
// *  <schemaName>                 const NAString &                   In       *
// *    is the name of the schema where the object is to be created.  If this  *
// *  is a CREATE SCHEMA request, this is the name of the schema to be created *
// *                                                                           *
// *  <schemaClass>                ComSchemaClass &                   Out      *
// *    passes back the class of the schema where the object to be created.    *
// *                                                                           *
// *  <objectOwner>                Int32 &                            Out      *
// *    passes back the user ID to use for object ownership.                   *
// *                                                                           *
// *  <schemaOwner>                Int32 &                            Out      *
// *    passes back the user ID to use for schema ownership.                   *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: int32_t/SQL error code                                           *
// *                                                                           *
// * 0: Create operation is authorized.                                        *
// * 1001: Internal error - not a create operation.                            *
// * 1003: Schema does not exist.                                              *
// * 1017: Create operation not authorized                                     *
// *                                                                           *
// *****************************************************************************
int32_t CmpSeabaseDDL::verifyDDLCreateOperationAuthorized(
   ExeCliInterface * cliInterface,
   SQLOperation operation,
   const NAString & catalogName,
   const NAString & schemaName,
   ComSchemaClass & schemaClass,
   Int32 & objectOwner,
   Int32 & schemaOwner)

{

   int32_t currentUser = ComUser::getCurrentUser(); 
   NAString privMgrMDLoc;

   CONCAT_CATSCH(privMgrMDLoc,getSystemCatalog(),SEABASE_PRIVMGR_SCHEMA);
   
   PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),
                                                  CmpCommon::diags());
                                               
   // CREATE SCHEMA is a special case.  There is no existing schema with an 
   // an owner or class.  A new schema may be created if the user is DB__ROOT,
   // authorization is not enabled, or the user has the CREATE_SCHEMA privilege. 

   if (operation == SQLOperation::CREATE_SCHEMA)
   {
      objectOwner = schemaOwner = currentUser;
      
      if (currentUser == ComUser::getRootUserID())
         return 0;
         
      if (!isAuthorizationEnabled())
         return 0;
         
      if (componentPrivileges.hasSQLPriv(currentUser,
                                         SQLOperation::CREATE_SCHEMA,
                                         true))
         return 0;
         
      objectOwner = schemaOwner = NA_UserIdDefault; 
      return CAT_NOT_AUTHORIZED;
   }

   // 
   // Not CREATE SCHEMA, but verify the operation is a create operation.
   //
   if (!PrivMgr::isSQLCreateOperation(operation))
   {
      SEABASEDDL_INTERNAL_ERROR("Unknown create operation");   
      objectOwner = schemaOwner = NA_UserIdDefault; 
      return CAT_INTERNAL_EXCEPTION_ERROR; 
   }
      
   // User is asking to create an object in an existing schema.  Determine if this
   // schema exists, and if it exists, the owner of the schema.  The schema class     
   // and owner will determine if this user can create an object in the schema and 
   // who will own the object.
       
   ComObjectType objectType;

   if (getObjectTypeandOwner(cliInterface,catalogName.data(),schemaName.data(),
                             SEABASE_SCHEMA_OBJECTNAME,objectType,schemaOwner) == -1)
   {
      objectOwner = schemaOwner = NA_UserIdDefault; 
      return CAT_SCHEMA_DOES_NOT_EXIST_ERROR;
   }
      
// All users are authorized to create objects in shared schemas.      
   if (objectType == COM_SHARED_SCHEMA_OBJECT)
   {
      schemaClass = COM_SCHEMA_CLASS_SHARED;
      objectOwner = currentUser;
      return 0;
   }
   
   if (objectType != COM_PRIVATE_SCHEMA_OBJECT)
   {
      SEABASEDDL_INTERNAL_ERROR("Unknown schema class");   
      objectOwner = schemaOwner = NA_UserIdDefault; 
      return CAT_INTERNAL_EXCEPTION_ERROR;
   }

   // For private schemas, the objects are always owned by the schema owner.
   schemaClass = COM_SCHEMA_CLASS_PRIVATE; 
   objectOwner = schemaOwner;


   // Root user is authorized for all create operations in private schemas.  For 
   // installations with no authentication, all users are mapped to root database  
   // user, so all users have full DDL create authority.

   if (currentUser == ComUser::getRootUserID())
      return 0;

   // If authorization is not enabled, then authentication should not be enabled
   // either, and the previous check should have already returned.  But just in 
   // case, verify authorization is enabled before proceeding.  Eventually this 
   // state should be recorded somewhere, e.g. CLI globals.

   if (!isAuthorizationEnabled())
      return 0;

   // If this is an internal operation, allow the operation.
  if (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))
      return 0;   

   // To create an object in a private schema, one of three conditions must be true:
   //
   // 1) The user is the owner of the schema.
   // 2) The schema is owned by a role, and the user has been granted the role.
   // 3) The user has been granted the requisite system-level SQL_OPERATIONS
   //    component create privilege.
   //
   // NOTE: In the future, schema-level create authority will be supported.
      
   if (currentUser == schemaOwner)
      return 0;
      
   if (CmpSeabaseDDLauth::isRoleID(schemaOwner))
   {
      PrivMgrRoles roles(std::string(getMDSchema()),
                         std::string(privMgrMDLoc.data()),
                         CmpCommon::diags());
                         
      if (roles.hasRole(currentUser,schemaOwner))
         return 0;              
   }
   
   // Current user is not the schema owner.  See if they have been granted the
   // requisite create privilege.
  
   if (componentPrivileges.hasSQLPriv(currentUser,operation,true))
      return 0;   
   
   // TODO: When schema-level privileges are implemented, see if user has the 
   // requisite create privilege for this specific schema.

   objectOwner = schemaOwner = NA_UserIdDefault; 
   return CAT_NOT_AUTHORIZED;

}
//********* End of CmpSeabaseDDL::verifyDDLCreateOperationAuthorized ***********





// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::isDDLOperationAuthorized                         *
// *                                                                           *
// *   This member function determines if a user has authority to perform a    *
// * specific DDL operation.                                                   *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <operation>                  SQLOperation                       In       *
// *    is operation the user wants to perform.                                *
// *                                                                           *
// *  <objOwner>                   const Int32                        In       *
// *    is the userID of the object owner.                                     *
// *                                                                           *
// *  <schemaOwner>                const Int32                        In       *
// *    is the userID of the schema owner.                                     *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: bool                                                             *
// *                                                                           *
// * true: DDL operation is authorized.                                        *
// * false: DDL operation is NOT authorized.                                   *
// *                                                                           *
// *****************************************************************************
bool CmpSeabaseDDL::isDDLOperationAuthorized(
   SQLOperation operation,
   const Int32 objOwner,
   const Int32 schemaOwner)

{

// Root user is authorized for all operations.  For installations with no
// security, all users are mapped to root database user, so all users have
// full DDL authority.

int32_t currentUser = ComUser::getCurrentUser(); 

   if (currentUser == ComUser::getRootUserID())
      return true;
      
// If this is an internal operation, allow the operation.
   if (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))
      return true;

// If authorization is not enabled, then authentication should not be enabled
// either, and the previous check should have already returned.  But just in 
// case, verify authorization is enabled before proceeding.  Eventually this 
// state should be recorded somewhere, e.g. CLI globals.

   if (!isAuthorizationEnabled())
      return true;
      
// For create operations there is no object owner; the object does not exist
// yet.  Function isDDLCreateOperationAuthorized() should be called instead.
// Reject any create callers.
   if (PrivMgr::isSQLCreateOperation(operation) && 
       operation != SQLOperation::CREATE_INDEX)
   {
      SEABASEDDL_INTERNAL_ERROR("isDDLOperationAuthorized called for a create operation");  
      return false;
   }
          
   if (currentUser == objOwner || currentUser == schemaOwner)
      return true;
      
NAString privMgrMDLoc;

   CONCAT_CATSCH(privMgrMDLoc,getSystemCatalog(),SEABASE_PRIVMGR_SCHEMA);

   if (CmpSeabaseDDLauth::isRoleID(schemaOwner))
   {
      PrivMgrRoles roles(std::string(getMDSchema()),
                         std::string(privMgrMDLoc.data()),
                         CmpCommon::diags());
                         
      if (roles.hasRole(currentUser,schemaOwner))
         return true;              
   }
   
PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),
                                               CmpCommon::diags());

   if (componentPrivileges.hasSQLPriv(currentUser,operation,true))
      return true;   
   
//TODO: check for schema-level DDL privileges.   
//TODO: check for object-level DDL privileges.
   return false;

}
//************** End of CmpSeabaseDDL::isDDLOperationAuthorized ****************


// *****************************************************************************
// *                                                                           *
// * Function: createSeabaseComponentOperation                                 *
// *                                                                           *
// *   This functions handles the CREATE COMPONENT PRIVILEGE command.          *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <systemCatalog>              const std::string &                In       *
// *    is catalog where system tables reside.                                 *
// *                                                                           *
// *  <pParseNode>                 StmtDDLCreateComponentPrivilege *  In       *
// *    is a pointer to parse node containing the data for the CREATE          *
// *  COMPONENT PRIVILEGE command.                                             *
// *                                                                           *
// *****************************************************************************
static void createSeabaseComponentOperation(
   const std::string & systemCatalog,
   StmtDDLCreateComponentPrivilege *pParseNode)
   
{

NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, systemCatalog.c_str(), SEABASE_PRIVMGR_SCHEMA);

PrivMgrCommands componentOperations(std::string(privMgrMDLoc.data()),CmpCommon::diags());

   if (!CmpCommon::context()->isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
  
const std::string componentName = pParseNode->getComponentName().data();
const std::string operationName = pParseNode->getComponentPrivilegeName().data();
const std::string operationCode = pParseNode->getComponentPrivilegeAbbreviation().data();
bool isSystem = pParseNode->isSystem();
const std::string operationDescription = pParseNode->getComponentPrivilegeDetailInformation().data();

PrivStatus retcode = STATUS_GOOD;

   retcode = componentOperations.createComponentOperation(componentName,
                                                          operationName,
                                                          operationCode,
                                                          isSystem,
                                                          operationDescription);
           
   if (retcode == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("CREATE COMPONENT PRIVILEGE command");
   
}
//****************** End of createSeabaseComponentOperation ********************

// *****************************************************************************
// *                                                                           *
// * Function: dropSeabaseComponentOperation                                   *
// *                                                                           *
// *   This functions handles the DROP COMPONENT PRIVILEGE command.            *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <systemCatalog>                 const std::string &             In       *
// *    is catalog where system tables reside.                                 *
// *                                                                           *
// *  <pParseNode>                    StmtDDLDropComponentPrivilege * In       *
// *    is a pointer to parse node containing the data for the DROP            *
// *  COMPONENT PRIVILEGE command.                                             *
// *                                                                           *
// *****************************************************************************
static void dropSeabaseComponentOperation(
   const std::string & systemCatalog,
   StmtDDLDropComponentPrivilege *pParseNode)
   
{

NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, systemCatalog.c_str(), SEABASE_PRIVMGR_SCHEMA);

PrivMgrCommands componentOperations(std::string(privMgrMDLoc.data()),CmpCommon::diags());
  
   if (!CmpCommon::context()->isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
  
const std::string componentName = pParseNode->getComponentName().data();
const std::string operationName = pParseNode->getComponentPrivilegeName().data();

// Convert from SQL enums to PrivMgr enums.
PrivDropBehavior privDropBehavior;

   if (pParseNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR)
      privDropBehavior = PrivDropBehavior::CASCADE;
   else
      privDropBehavior = PrivDropBehavior::RESTRICT;

PrivStatus retcode = STATUS_GOOD;

   retcode = componentOperations.dropComponentOperation(componentName,
                                                        operationName,
                                                        privDropBehavior);
           
   if (retcode == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("DROP COMPONENT PRIVILEGE command");
   
}
//******************* End of dropSeabaseComponentOperation *********************



// *****************************************************************************
// *                                                                           *
// * Function: grantRevokeSeabaseRole                                          *
// *                                                                           *
// *   This function handles the GRANT ROLE and REVOKE ROLE commands.          *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <systemCatalog>              const std::string &                In       *
// *    is catalog where system tables reside.                                 *
// *                                                                           *
// *  <pParseNode>                 StmtDDLGrantRole *                 In       *
// *    is a pointer to parse node containing the data for the GRANT           *
// *  ROLE or REVOKE ROLE command.                                             *
// *                                                                           *
// *****************************************************************************
static void grantRevokeSeabaseRole(
   const std::string & systemCatalog,
   StmtDDLRoleGrant *pParseNode)
   
{
   NAString trafMDLocation;
   CONCAT_CATSCH(trafMDLocation,systemCatalog.c_str(),SEABASE_MD_SCHEMA);
   NAString privMgrMDLoc;
   CONCAT_CATSCH(privMgrMDLoc,systemCatalog.c_str(),SEABASE_PRIVMGR_SCHEMA);
   
   PrivMgrCommands roleCommand(std::string(trafMDLocation.data()),
                               std::string(privMgrMDLoc.data()),
                               CmpCommon::diags());

   if (!CmpCommon::context()->isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
      
   //   The GRANT ROLE and REVOKE ROLE commands each take a list of roles       
   // and a list of grantees (authorization names to grant the role to).        
   // All items on both lists need to be verified for existence and no         
   // duplication.  The results are stored in two parallel name/ID vectors.     
   //                                                                           
   //   Currently roles may only be granted to users, and may not be granted    
   // to PUBLIC, so some code takes shortcuts and assumes users, while other    
   // code is prepared for eventually supporting all authorization types.       
     
   //  By default, the user issuing the GRANT or REVOKE ROLE command is         
   // the grantor.  However, if the GRANTED BY clause is specified,             
   // that authorization ID is the grantor.                                     
   //                                                                           
   //    If the GRANTED BY clause is NOT specified, and the user is             
   // DB__ROOT, then the GRANT/REVOKE is assumed to have been                   
   // issued by the owner/creator of the role.  So if no GRANTED BY             
   // clause and grantor is DB__ROOT, note it, so we can look for the           
   // role creator later.                                                       
   int32_t grantorID = ComUser::getCurrentUser();
   std::string grantorName;
   bool grantorIsRoot = false;

   ElemDDLGrantee *grantedBy = pParseNode->getGrantedBy();

   if (grantedBy != NULL)
   {
      // GRANTED BY clause reserved for DB__ROOT and users with the MANAGE_ROLES
      // component privilege.
      if (grantorID != ComUser::getRootUserID())
      {
         PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags());
         if (!componentPrivileges.hasSQLPriv(grantorID,
                                             SQLOperation::MANAGE_ROLES,
                                             true))
         {
            *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
            return;
         }
      }

      // BY clause specified.  Determine the grantor
      ComString grantedByName = grantedBy->getAuthorizationIdentifier();

      //TODO: will need to update this if grant role to role is supported,
      // i.e., the granted by could be a role. getUserIDFromUserName() only
      // supports users.       
      if (ComUser::getUserIDFromUserName(grantedByName.data(),grantorID) != 0)
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                             << DgString0(grantedByName.data());
         return;
      }
      grantorName = grantedByName.data();
   }  // grantedBy not null
   else
   {
      grantorName = ComUser::getCurrentUsername();
      if (grantorID == ComUser::getRootUserID())
         grantorIsRoot = true;
   }
      
   //   Next, walk through the list of roles being granted, making sure         
   // each one exists and none appear more than once.  For each role,           
   // if the grantor is DB__ROOT, determine the creator of the role and         
   // use that data for the entries in the grantor vectors.                     
   ElemDDLGranteeArray & roles = pParseNode->getRolesArray();

   std::vector<int32_t> grantorIDs;
   std::vector<std::string> grantorNames;
   std::vector<int32_t> roleIDs;
   std::vector<std::string> roleNames;

   for (size_t r = 0; r < roles.entries(); r++)
   {
      ComString roleName(roles[r]->getAuthorizationIdentifier());
      CmpSeabaseDDLrole roleInfo;
      int32_t roleID;
      
      // See if role exists
      if (!roleInfo.getRoleIDFromRoleName(roleName.data(),roleID))
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_ROLE_NOT_EXIST)
                             << DgString0(roleName.data());
         return;
      }
      
      // See if this role has already been specified.
      if (hasValue(roleIDs,roleID))
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_DUPLICATE_ROLES_IN_LIST)
                             << DgString0(roleName.data());
         return;
      }
      
      roleIDs.push_back(roleID);
      roleNames.push_back(roleName.data());
      
      // If grantor is DB__ROOT, substitute the role creator as the grantor.
      if (grantorIsRoot)
      {
         grantorIDs.push_back(roleInfo.getAuthCreator());
         
         char GrantorNameString[MAX_DBUSERNAME_LEN + 1];
         int32_t length;
         
         Int16 retCode = ComUser::getAuthNameFromAuthID(roleInfo.getAuthCreator(),
                                                        GrantorNameString,
                                                        sizeof(GrantorNameString),
                                                        length);
         
         if (retCode != 0)
            SEABASEDDL_INTERNAL_ERROR("Role administrator not registered");

         grantorNames.push_back(GrantorNameString);
      }
      else
      {
         grantorIDs.push_back(grantorID);     
         grantorNames.push_back(grantorName);
      }
   }
   
   //   Now, walk throught the list of grantees, making sure they all exist     
   //  and none appear more than once.                                         
   ElemDDLGranteeArray & grantees = pParseNode->getGranteeArray();
   std::vector<int32_t> granteeIDs;
   std::vector<std::string> granteeNames;
   std::vector<PrivAuthClass> granteeClasses;
   for (size_t g = 0; g < grantees.entries(); g++)
   {
      int32_t granteeID;
      ComString granteeName(grantees[g]->getAuthorizationIdentifier());
      
      //TODO: the parser goes through a lot of work to segregrate PUBLIC from
      // other grantees, requiring more work here.  Could be simplified.
      // Note, _SYSTEM is not separated, but is included with other
      // grantee names.  
      if (grantees[g]->isPublic())
      {
         granteeID = ComUser::getPublicUserID();
         granteeName = ComUser::getPublicUserName();
      }
      else
      {
         granteeName = grantees[g]->getAuthorizationIdentifier();
         
         Int16 retCode = ComUser::getUserIDFromUserName(granteeName.data(),granteeID);
         //TODO: API only supports up/down on "is a user."  Could be a role
         // or PUBLIC.  Instead of "name does not exist" we could say 
         // "name is not a user" or "Roles can only be granted to users, name is 
         // not a user".  If support is added for granting to roles, a new 
         // API is needed.
         if (retCode != 0)
         {
            *CmpCommon::diags() << DgSqlCode(-CAT_USER_NOT_EXIST)
                                << DgString0(granteeName.data());
            return;
         }
      }
      
      // See if the grantee has already been specified.
      if (hasValue(granteeIDs,granteeID))
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_DUPLICATE_USERS_IN_LIST)
                             << DgString0(granteeName.data());
         return;
      }
      granteeIDs.push_back(granteeID);
      granteeNames.push_back(granteeName.data());
      granteeClasses.push_back(PrivAuthClass::USER);
   }

   //   The WITH ADMIN option means the grantee can grant the role to another   
   // authorization ID.  In the case of REVOKE, this ability (but not the role  
   // itself) is being taken from the grantee.                                  
   int32_t grantDepth = 0;
   bool withAdminOptionSpecified = false;

   if (pParseNode->isWithAdminOptionSpecified())
   {
      if (pParseNode->isGrantRole())
         grantDepth = -1;
      withAdminOptionSpecified = true;
   }
   
   //   For REVOKE ROLE, the operation can either be RESTRICT, i.e. restrict    
   // the command if any dependencies exist or CASCADE, in which case any       
   // dependencies are silently removed.  Currently only RESTRICT is supported. 
   PrivDropBehavior privDropBehavior = PrivDropBehavior::RESTRICT;

   if (pParseNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR)
      privDropBehavior = PrivDropBehavior::CASCADE;
   else
      privDropBehavior = PrivDropBehavior::RESTRICT;
      
   PrivStatus privStatus = STATUS_GOOD;
   std::string commandString;

   if (pParseNode->isGrantRole())
   {
      commandString = "GRANT ROLE";
      privStatus = roleCommand.grantRole(roleIDs,
                                         roleNames,
                                         grantorIDs,
                                         grantorNames,
                                         PrivAuthClass::USER,
                                         granteeIDs,
                                         granteeNames,                                 
                                         granteeClasses,                               
                                         grantDepth);                                   
   }
   else
   {
      commandString = "REVOKE ROLE";
      privStatus = roleCommand.revokeRole(roleIDs,
                                          granteeIDs,
                                          granteeClasses,
                                          grantorIDs,
                                          withAdminOptionSpecified, 
                                          grantDepth,
                                          privDropBehavior);
   }
    
   if (privStatus == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
   {
      commandString += " command";
      SEABASEDDL_INTERNAL_ERROR(commandString.c_str());
   }
   
   // update the redef timestamp for the role in auths table
   char buf[(roleIDs.size()*12) + 500];
   Int64 redefTime = NA_JulianTimestamp();
   std::string roleList;
   for (size_t i = 0; i < roleIDs.size(); i++)
   {
     if (i > 0)
       roleList += ", ";
     roleList += to_string((long long int)roleIDs[i]);
   }

   str_sprintf(buf, "update %s.\"%s\".%s set auth_redef_time = %ld "
                    "where auth_id in (%s)",
              systemCatalog.c_str(), SEABASE_MD_SCHEMA, SEABASE_AUTHS,
              redefTime, roleList.c_str());
 
   ExeCliInterface cliInterface(STMTHEAP);
   Int32 cliRC = cliInterface.executeImmediate(buf);
   if (cliRC < 0)
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());

}
//********************** End of grantRevokeSeabaseRole *************************




// *****************************************************************************
// *                                                                           *
// * Function: grantSeabaseComponentPrivilege                                  *
// *                                                                           *
// *   This functions handles the GRANT COMPONENT PRIVILEGE command.           *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <systemCatalog>              const std::string &                In       *
// *    is catalog where system tables reside.                                 *
// *                                                                           *
// *  <pParseNode>                 StmtDDLGrantComponentPrivilege *   In       *
// *    is a pointer to parse node containing the data for the GRANT           *
// *  COMPONENT PRIVILEGE command.                                             *
// *                                                                           *
// *****************************************************************************
static void grantSeabaseComponentPrivilege(
   const std::string & systemCatalog,
   StmtDDLGrantComponentPrivilege *pParseNode)
   
{
  NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, systemCatalog.c_str(), SEABASE_PRIVMGR_SCHEMA);
   
  PrivMgrCommands componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags());
  
   if (!CmpCommon::context()->isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
  
  const std::string componentName = pParseNode->getComponentName().data();
  const ConstStringList & privList = pParseNode->getComponentPrivilegeNameList();

  const NAString & granteeName = pParseNode->getUserRoleName(); 
  int32_t granteeID;

   if (ComUser::getAuthIDFromAuthName(granteeName.data(),granteeID) != 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                          << DgString0(granteeName.data());
      return;
   }

  int32_t grantorID = ComUser::getCurrentUser();
  std::string grantorName;

  ElemDDLGrantee *grantedBy = pParseNode->getGrantedBy();

   if (grantedBy != NULL)
   {
      if (grantorID != ComUser::getRootUserID())
      {
         PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags());
         if (!componentPrivileges.hasSQLPriv(grantorID,
                                             SQLOperation::MANAGE_COMPONENTS,
                                             true))
         {
            *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
            return;
         }
      }
      
      // BY clause specified.  Determine the grantor
      ComString grantedByName = grantedBy->getAuthorizationIdentifier();

      if (ComUser::getAuthIDFromAuthName(grantedByName.data(),grantorID) != 0)
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                             << DgString0(grantedByName.data());
         return;
      }
      
      grantorName = grantedByName.data();
      
      //TODO: Cannot grant to _SYSTEM.  PUBLIC ok?
    
   }  
   else	// Grantor is the current user.
      grantorName = ComUser::getCurrentUsername();

  int32_t grantDepth = 0;

   if (pParseNode->isWithGrantOptionSpecified())
   {
      // Don't allow WGO for roles
      if (CmpSeabaseDDLauth::isRoleID(granteeID) &&
          (CmpCommon::getDefault(ALLOW_WGO_FOR_ROLES) == DF_OFF))
      {
        *CmpCommon::diags() << DgSqlCode(-CAT_WGO_NOT_ALLOWED);
        return;
      }
      grantDepth = -1;
   }

  vector<std::string> operationNamesList;

   for (size_t i = 0; i < privList.entries(); i++)
   {
      const ComString * operationName = privList[i];
      operationNamesList.push_back(operationName->data());
   }   

  PrivStatus retcode = STATUS_GOOD;

   retcode = componentPrivileges.grantComponentPrivilege(componentName,
                                                         operationNamesList,
                                                         grantorID,
                                                         grantorName,
                                                         granteeID,
                                                         granteeName.data(),
                                                         grantDepth);
           
   if (retcode == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("GRANT COMPONENT PRIVILEGE command");
   
}
//****************** End of grantSeabaseComponentPrivilege *********************


// *****************************************************************************
// *                                                                           *
// * Function: hasValue                                                        *
// *                                                                           *
// *   This function determines if a vector contains a value.                  *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <container>                  std::vector<int32_t>               In       *
// *    is the vector of 32-bit values.                                        *
// *                                                                           *
// *  <value>                      int32_t                            In       *
// *    is the value to be compared against existing values in the vector.     *
// *                                                                           *
// *****************************************************************************
static bool hasValue(
   std::vector<int32_t> container,
   int32_t value)
   
{

   for (size_t index = 0; index < container.size(); index++)
      if (container[index] == value)
         return true;
         
   return false;
   
}
//***************************** End of hasValue ********************************


// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::registerSeabaseComponent                         *
// *                                                                           *
// *    This function handles register (adding) and unregister (drop) of       *
// *  components known to the Privilege Manager.                               *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <pParseNode>                    StmtDDLRegisterComponent *      In       *
// *    is a pointer to parse node containing the data for the REGISTER or     *
// *  UNREGISTER COMPONENT command.                                            *
// *                                                                           *
// *****************************************************************************
void CmpSeabaseDDL::registerSeabaseComponent(StmtDDLRegisterComponent *pParseNode)
{

NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);

  PrivMgrCommands component(std::string(privMgrMDLoc.data()),CmpCommon::diags());
  
   if (!isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
  
const std::string componentName = pParseNode->getExternalComponentName().data();
  
PrivStatus retcode = STATUS_GOOD;

   switch (pParseNode->getRegisterComponentType())
   {
      case StmtDDLRegisterComponent::REGISTER_COMPONENT:
      {
         const NAString details = pParseNode->getRegisterComponentDetailInfo();
         bool isSystem = pParseNode->isSystem();
         const std::string componentDetails = details.data();
         retcode = component.registerComponent(componentName,isSystem,componentDetails);
         break;
      }
      case StmtDDLRegisterComponent::UNREGISTER_COMPONENT:
      {
         PrivDropBehavior privDropBehavior;

         if (pParseNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR)
            privDropBehavior = PrivDropBehavior::CASCADE;
         else
            privDropBehavior = PrivDropBehavior::RESTRICT;
         
         retcode = component.unregisterComponent(componentName,privDropBehavior);
      } 
         break;
      default:
         retcode = STATUS_ERROR; 
   }
  
   if (retcode == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("REGISTER/UNREGISTER COMPONENT command");

}

//************** End of CmpSeabaseDDL::registerSeabaseComponent ****************


// *****************************************************************************
// *                                                                           *
// * Function: revokeSeabaseComponentPrivilege                                 *
// *                                                                           *
// *   This functions handles the REVOKE COMPONENT PRIVILEGE command.          *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <systemCatalog>              const std::string &                In       *
// *    is catalog where system tables reside.                                 *
// *                                                                           *
// *  <pParseNode>                 StmtDDLRevokeComponentPrivilege *  In       *
// *    is a pointer to parse node containing the data for the REVOKE          *
// *  COMPONENT PRIVILEGE command.                                             *
// *                                                                           *
// *****************************************************************************
static void revokeSeabaseComponentPrivilege(
   const std::string & systemCatalog,
   StmtDDLRevokeComponentPrivilege *pParseNode)
   
{

NAString privMgrMDLoc;
  CONCAT_CATSCH(privMgrMDLoc, systemCatalog.c_str(), SEABASE_PRIVMGR_SCHEMA);

PrivMgrCommands componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags());
  
   if (!CmpCommon::context()->isAuthorizationEnabled())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHORIZATION_NOT_ENABLED);
      return;
   }
  
const std::string componentName = pParseNode->getComponentName().data();
const ConstStringList & privList = pParseNode->getComponentPrivilegeNameList();

const NAString & granteeName = pParseNode->getUserRoleName(); 
int32_t granteeID;

   if (ComUser::getAuthIDFromAuthName(granteeName.data(),granteeID) != 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                          << DgString0(granteeName.data());
      return;
   }

int32_t grantorID = ComUser::getCurrentUser();

ElemDDLGrantee *grantedBy = pParseNode->getGrantedBy();

   if (grantedBy != NULL)
   {
      if (grantorID != ComUser::getRootUserID())
      {
         PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags());
         if (!componentPrivileges.hasSQLPriv(grantorID,
                                             SQLOperation::MANAGE_COMPONENTS,
                                             true))
         {
            *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
            return;
         }
      }
      
      // BY clause specified.  Determine the grantor
      ComString grantedByName = grantedBy->getAuthorizationIdentifier();

      if (ComUser::getAuthIDFromAuthName(grantedByName.data(),grantorID) != 0)
      {
         *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                             << DgString0(grantedByName.data());
         return;
      }
    
 }  // grantedBy not null

bool isGOFSpecified = false;

   if (pParseNode->isGrantOptionForSpecified())
      isGOFSpecified = true;
      
vector<std::string> operationNamesList;

   for (size_t i = 0; i < privList.entries(); i++)
   {
      const ComString * operationName = privList[i];
      operationNamesList.push_back(operationName->data());
   }   

PrivStatus retcode = STATUS_GOOD;
PrivDropBehavior dropBehavior = PrivDropBehavior::RESTRICT; 

   retcode = componentPrivileges.revokeComponentPrivilege(componentName,
                                                          operationNamesList,
                                                          grantorID,
                                                          granteeID,
                                                          isGOFSpecified,
                                                          dropBehavior);
   if (retcode == STATUS_ERROR && 
       CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
      SEABASEDDL_INTERNAL_ERROR("REVOKE COMPONENT PRIVILEGE command");
   
}
//****************** End of revokeSeabaseComponentPrivilege ********************



short 
CmpSeabaseDDL::setupHbaseOptions(ElemDDLHbaseOptions * hbaseOptionsClause,
                                 Int32 numSplits, const NAString& objName,
                                 NAList<HbaseCreateOption*>& hbaseCreateOptions,
                                 NAString& hco)
{
  NAText hbaseOptionsStr;
  NABoolean maxFileSizeOptionSpecified = FALSE;
  NABoolean splitPolicyOptionSpecified = FALSE;
  const char *maxFileSizeOptionString = "MAX_FILESIZE";
  const char *splitPolicyOptionString = "SPLIT_POLICY";

  NABoolean dataBlockEncodingOptionSpecified = FALSE;
  NABoolean compressionOptionSpecified = FALSE;
  const char *dataBlockEncodingOptionString = "DATA_BLOCK_ENCODING";
  const char *compressionOptionString = "COMPRESSION";

  Lng32 numHbaseOptions = 0;
  if (hbaseOptionsClause)
  {
    for (CollIndex i = 0; i < hbaseOptionsClause->getHbaseOptions().entries(); 
         i++)
    {
      HbaseCreateOption * hbaseOption =
        hbaseOptionsClause->getHbaseOptions()[i];

      hbaseCreateOptions.insert(hbaseOption);

      if (hbaseOption->key() == maxFileSizeOptionString)
        maxFileSizeOptionSpecified = TRUE;
      else if (hbaseOption->key() == splitPolicyOptionString)
        splitPolicyOptionSpecified = TRUE;
      else if (hbaseOption->key() == dataBlockEncodingOptionString)
        dataBlockEncodingOptionSpecified = TRUE;
      else if (hbaseOption->key() == compressionOptionString)
        compressionOptionSpecified = TRUE;
      
      hbaseOptionsStr += hbaseOption->key();
      hbaseOptionsStr += "='";
      hbaseOptionsStr += hbaseOption->val();
      hbaseOptionsStr += "'";

      hbaseOptionsStr += "|";
    }

    numHbaseOptions += hbaseOptionsClause->getHbaseOptions().entries();
  }

  if (numSplits > 0 /* i.e. a salted table */)
  {
    // set table-specific region split policy and max file
    // size, controllable by CQDs, but only if they are not
    // already set explicitly in the DDL.
    // Save these options in metadata if they are specified by user through
    // explicit create option or through a cqd.
    double maxFileSize = 
      CmpCommon::getDefaultNumeric(HBASE_SALTED_TABLE_MAX_FILE_SIZE);
    NABoolean usePerTableSplitPolicy = 
      (CmpCommon::getDefault(HBASE_SALTED_TABLE_SET_SPLIT_POLICY) == DF_ON);
    HbaseCreateOption * hbaseOption = NULL;

    if (maxFileSize > 0 && !maxFileSizeOptionSpecified)
    {
      char fileSizeOption[100];
      Int64 maxFileSizeInt;

      if (maxFileSize < LLONG_MAX)
        maxFileSizeInt = maxFileSize;
      else
        maxFileSizeInt = LLONG_MAX;
          
      snprintf(fileSizeOption,100,"%ld", maxFileSizeInt);
      hbaseOption = new(STMTHEAP) 
        HbaseCreateOption("MAX_FILESIZE", fileSizeOption);
      hbaseCreateOptions.insert(hbaseOption);

      if (ActiveSchemaDB()->getDefaults().userDefault(
               HBASE_SALTED_TABLE_MAX_FILE_SIZE) == TRUE)
      {
        numHbaseOptions += 1;
        snprintf(fileSizeOption,100,"MAX_FILESIZE='%ld'|", maxFileSizeInt);
        hbaseOptionsStr += fileSizeOption;
      }
    }

    if (usePerTableSplitPolicy && !splitPolicyOptionSpecified)
    {
      const char *saltedTableSplitPolicy =
        "org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy";
      hbaseOption = new(STMTHEAP) HbaseCreateOption(
           "SPLIT_POLICY", saltedTableSplitPolicy);
      hbaseCreateOptions.insert(hbaseOption);

      if (ActiveSchemaDB()->getDefaults().userDefault(
               HBASE_SALTED_TABLE_SET_SPLIT_POLICY) == TRUE)
      {
        numHbaseOptions += 1;
        hbaseOptionsStr += "SPLIT_POLICY='";
        hbaseOptionsStr += saltedTableSplitPolicy;
        hbaseOptionsStr += "'|";
      }
    }  
  }
  
  NAString dataBlockEncoding =
    CmpCommon::getDefaultString(HBASE_DATA_BLOCK_ENCODING_OPTION);
  NAString compression = 
    CmpCommon::getDefaultString(HBASE_COMPRESSION_OPTION);
  HbaseCreateOption * hbaseOption = NULL;
  
  char optionStr[200];
  if (!dataBlockEncoding.isNull() && !dataBlockEncodingOptionSpecified)
    {
      hbaseOption = new(STMTHEAP) HbaseCreateOption("DATA_BLOCK_ENCODING", 
                                                    dataBlockEncoding.data());
      hbaseCreateOptions.insert(hbaseOption);

      if (ActiveSchemaDB()->getDefaults().userDefault
          (HBASE_DATA_BLOCK_ENCODING_OPTION) == TRUE)
        {
          numHbaseOptions += 1;
          sprintf(optionStr, "DATA_BLOCK_ENCODING='%s'|", dataBlockEncoding.data());
          hbaseOptionsStr += optionStr;
        }
    }

  if (!compression.isNull() && !compressionOptionSpecified)
    {
      hbaseOption = new(STMTHEAP) HbaseCreateOption("COMPRESSION", 
                                                    compression.data());
      hbaseCreateOptions.insert(hbaseOption);

      if (ActiveSchemaDB()->getDefaults().userDefault
          (HBASE_COMPRESSION_OPTION) == TRUE)
        {
          numHbaseOptions += 1;
          sprintf(optionStr, "COMPRESSION='%s'|", compression.data());
          hbaseOptionsStr += optionStr;
        }
    }

  /////////////////////////////////////////////////////////////////////
  // update HBASE_CREATE_OPTIONS field in metadata TABLES table.
  // Format of data stored in this field, if applicable.
  //    HBASE_OPTIONS=>numOptions(4bytes)option='val'| ...
  ///////////////////////////////////////////////////////////////////////
  if  (hbaseOptionsStr.size() > 0)
  {
    hco += "HBASE_OPTIONS=>";

    char hbaseOptionsNumCharStr[HBASE_OPTION_MAX_INTEGER_LENGTH];
    sprintf(hbaseOptionsNumCharStr, "%04d", numHbaseOptions);
    hco += hbaseOptionsNumCharStr;

    hco += hbaseOptionsStr.data();
      
    hco += " "; // separator
  }

  if (hco.length() > HBASE_OPTIONS_MAX_LENGTH)
  {
    *CmpCommon::diags() << DgSqlCode(-CAT_INVALID_HBASE_OPTIONS_CLAUSE)
                        << DgString0(objName);
    return -1 ;
  }
  return 0;
}
