CmpStatement::ReturnStatus
CmpStatement::process (const CmpMessageDDLNATableInvalidate& statement)
{
  CmpSeabaseDDL cmpSBD(heap_);
  if (cmpSBD.ddlInvalidateNATables())
    {
      return CmpStatement_ERROR;
    }

  return CmpStatement_SUCCESS;
}
float SchemaDB::getHbaseBlockCacheFrac()
{
  if (hbaseBlockCacheFrac_ < 0) // access JNI layer first time to set value
  {
    CmpSeabaseDDL cmpSBD(STMTHEAP);
    ExpHbaseInterface* ehi = cmpSBD.allocEHI();
    if (!ehi)
      hbaseBlockCacheFrac_ = 0.4 ; // hbase default default
    else {
    float frac;
    Lng32 retcode;
    retcode = ehi->getBlockCacheFraction(frac);
    if (retcode < 0)
      hbaseBlockCacheFrac_ = 0.4 ; // hbase default default
    else
      hbaseBlockCacheFrac_ = frac;
    cmpSBD.deallocEHI(ehi);
    }
  }
  return hbaseBlockCacheFrac_ ;
}
// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::describeSchema                                   *
// *                                                                           *
// *    Provides text for SHOWDDL SCHEMA comnmand.                             *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <catalogName>                   const NAString &                In       *
// *    is a reference to a catalog name.                                      *
// *                                                                           *
// *  <schemaName>                    const NAString &                In       *
// *    is a reference to a schema name.                                       *
// *                                                                           *
// *  <output>                        NAString &                      Out      *
// *    passes back text for the SHOWDDL SCHEMA command, specifically the      *
// *  command to create the specified schema.                                  *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: bool                                                             *
// *                                                                           *
// * true: Text returned for specified schema.                                 *
// * false: Could not retrieve information for specified schema.               *
// *                                                                           *
// *****************************************************************************
bool CmpSeabaseDDL::describeSchema(
   const NAString & catalogName,
   const NAString & schemaName,
   NAString & output)
   
{

ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, 
CmpCommon::context()->sqlSession()->getParentQid());
ComSchemaClass schemaClass;
Int32 objectOwner;
Int32 schemaOwner;
ComObjectType objectType;

   CmpSeabaseDDL cmpSBD(STMTHEAP);
   if (cmpSBD.switchCompiler())
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_RETRIEVE_PRIVS);
      return false;
   }

Int64 schemaUID = getObjectTypeandOwner(&cliInterface,
                                        catalogName.data(),
                                        schemaName.data(),
                                        SEABASE_SCHEMA_OBJECTNAME,
                                        objectType,
                                        objectOwner);
                                        
   if (schemaUID < 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR)
                          << DgSchemaName(catalogName + "." + schemaName);
      cmpSBD.switchBackCompiler();
      return false;
   }
      
char username[MAX_USERNAME_LEN+1];
Int32 lActualLen = 0;
Int16 status = ComUser::getAuthNameFromAuthID(objectOwner,username, 
                                              MAX_USERNAME_LEN,lActualLen);
   if (status != FEOK)
   {
      *CmpCommon::diags() << DgSqlCode(-20235) // Error converting user ID.
                          << DgInt0(status)
                          << DgInt1(objectOwner);
      cmpSBD.switchBackCompiler();
      return false;
   }
      
// Generate output text
   output = "CREATE ";
   switch (objectType)
   {
      case COM_PRIVATE_SCHEMA_OBJECT:
         output += "PRIVATE";
         break;
      case COM_SHARED_SCHEMA_OBJECT:
         output += "SHARED";
         break;
      default:
         return false;
   }
   output += " SCHEMA \"";
   output += catalogName.data();
   output += "\".\"";
   output += schemaName.data();
   
// AUTHORIZATION clause is rarely used, but include it for replay.
   output += "\" AUTHORIZATION \"";
   output += username;
   output += "\";";

   cmpSBD.switchBackCompiler();
   return true;
   
}
CmpStatement::ReturnStatus
CmpStatement::process (const CmpMessageDDL& statement)
{
  CmpMain cmpmain;

  CMPASSERT(statement.getCmpCompileInfo());
  
  char * sqlStr = NULL;
  Int32 sqlStrLen = 0;
  Lng32 inputCS = 0;
  NAString currCatName;
  NAString currSchName;
  char * recompControlInfo = NULL;
  NABoolean isSchNameRecvd;
  NABoolean nametypeNsk;
  NABoolean odbcProcess;
  NABoolean noTextCache;
  NABoolean aqrPrepare;
  NABoolean standaloneQuery;
  isDDL_ = TRUE;

  if (processRecvdCmpCompileInfo(this,
				 statement,
  				 statement.getCmpCompileInfo(),
				 context_,
				 sqlStr, 
				 sqlStrLen, // out - long &
				 inputCS,
				 isSchNameRecvd, 
				 currCatName, currSchName, 
				 recompControlInfo,
				 nametypeNsk,
				 odbcProcess,
				 noTextCache,
				 aqrPrepare,
				 standaloneQuery))
    return CmpStatement_ERROR;

  CmpCommon::context()->sqlSession()->setParentQid(
    statement.getParentQid());
  // process recompControlInfo, if received
  if (recompControlInfo)
    setupRecompControlInfo(recompControlInfo, &cmpmain);

  cmpmain.setSqlParserFlags(statement.getFlags());

  // set the current catalog and schema names.
  InitSchemaDB();

  // C control character embedded in sqlStr is not handled.  Now replace 
  // control characters tabs, line feeds, spaces with spaces. (no longer 
  // substitute for \n so we can recognized embedded comments)
  for (Int32 i = 0; sqlStr[i]; i++)
   if (sqlStr[i] != '\n' && isSpace8859_1((unsigned char)sqlStr[i])) sqlStr[i] = ' ';

  // skip leading blanks
  NAString ns(sqlStr);
  ns = ns.strip(NAString::leading, ' ');

  // if this is an "update statistics..." request,
  // then do not send it catalog manager.
  Int32 foundUpdStat = 0;

  // check if the first token is UPDATE
  size_t position = ns.index("UPDATE", 0, NAString::ignoreCase);
  if (position == 0)
    {
      // found UPDATE. See if the next token is STATISTICS.
      ns = ns(6, ns.length()-6); // skip over UPDATE
      ns = ns.strip(NAString::leading, ' ');

      position = ns.index("STATISTICS", 0, NAString::ignoreCase);
      if (position == 0)
	foundUpdStat = -1;
    }

  if (foundUpdStat)
    {
      // TODO, should be removed later
      
      // A pointer to user SQL query is stored in CmpStatement; if an exception
      // is thrown the user query is copied from here. It is reset upon return
      // from the UpdateStats() method.
      
      char *userStr= new (heap()) char[2000];
#pragma nowarn(1506)   // warning elimination 
      Int32 len=strlen(sqlStr);
#pragma warn(1506)  // warning elimination 
      
      if (len > 1999)
        len=1999;
      
      strncpy(userStr, sqlStr, len);
      userStr[len]='\0';
      
      sqlTextStr_ = userStr;
      sqlTextLen_ = len;
      
      if (UpdateStats(sqlStr))
        {
	  sqlTextStr_ = NULL;
	  sqlTextLen_ = 0;
	  if (recompControlInfo)
	    restoreRecompControlInfo(recompControlInfo);
	  return CmpStatement_ERROR;
        }
      
      sqlTextStr_ = NULL;
      sqlTextLen_ = 0;
      
      if (recompControlInfo)
	restoreRecompControlInfo(recompControlInfo);
      return CmpStatement_SUCCESS;
    }

  ReturnStatus status = CmpStatement_SUCCESS;
  if (statement.getCmpCompileInfo()->isHbaseDDL())
    {
      CmpMain::ReturnStatus rs = CmpMain::SUCCESS;
      
      QueryText qText(sqlStr, inputCS);

      CmpMessageReplyCode
	*bound = new(outHeap_) CmpMessageReplyCode(outHeap_, statement.id(), 0, 0, outHeap_);

      //      CmpMain cmpmain;
      Set_SqlParser_Flags(DELAYED_RESET);	// sqlcompCleanup resets for us
      Parser parser(CmpCommon::context());
      BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), TRUE);

      // save parser flags
      Int32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
      ExprNode * exprNode = NULL;
      if (parser.parseDML(qText, &exprNode, NULL))
	{
	  error(arkcmpErrorNoDiags, statement.data());
	  sqlTextStr_=NULL;
	  return CmpStatement_ERROR;
	}

      RelExpr * rRoot = NULL;
      if (exprNode->getOperatorType() EQU STM_QUERY)
	{
	  rRoot = (RelRoot*)exprNode->getChild(0);
	}
      else if (exprNode->getOperatorType() EQU REL_ROOT)
	{
	  rRoot = (RelRoot*)exprNode;
	}
      
      CMPASSERT(rRoot);

      ExprNode *boundDDL = rRoot->bindNode(&bindWA);
      CMPASSERT(boundDDL);

      if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_))
	{
	  return CmpStatement_ERROR;
	}
      
      ExprNode * ddlNode = NULL;
      DDLExpr * ddlExpr = NULL;

      ddlExpr = (DDLExpr*)rRoot->getChild(0);
      ddlNode = ddlExpr->getDDLNode();

      if (ddlNode)
	{
	  boundDDL = ddlNode->castToStmtDDLNode()->bindNode(&bindWA);
	  CMPASSERT(boundDDL);

	  if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_))
	    {
	      return CmpStatement_ERROR;
	    }
 	  
	  ddlNode = boundDDL;
	}

      // reset saved flags
      Set_SqlParser_Flags (savedParserFlags);
      CmpSeabaseDDL cmpSBD(heap_);
      if (cmpSBD.executeSeabaseDDL(ddlExpr, ddlNode,
				   currCatName, currSchName))
      {
        Set_SqlParser_Flags(0);
	return CmpStatement_ERROR;
      }
      Set_SqlParser_Flags (0);

      // TEMPTEMP.
      // Until support for metadata invalidation is in, clear up query cache for
      // this process. That way statements issued later from this session will
      // not see stale definitions.
      // This also helps in running tests where tables are modified and accessed from
      // the same session.
      // This does not solve the issue of stale definition seen by other processes,
      // that will be fixed once we have metadata invalidation.
      CURRENTQCACHE->makeEmpty();

      return CmpStatement_SUCCESS;
    } // hbaseDDL

  // This is a normal DDL request, call Catalog manager
  *diags() << DgSqlCode(-4222)
           << DgString0("SQL Compiler DDL");
  return CmpStatement_ERROR;
}
CmpStatement::ReturnStatus
CmpStatement::process(const CmpMessageDDLwithStatus &statement)
{
  CmpMain cmpmain;

  CMPASSERT(statement.getCmpCompileInfo());
  
  char * sqlStr = NULL;
  Int32 sqlStrLen = 0;
  Lng32 inputCS = 0;
  NAString currCatName;
  NAString currSchName;
  char * recompControlInfo = NULL;
  NABoolean isSchNameRecvd;
  NABoolean nametypeNsk;
  NABoolean odbcProcess;
  NABoolean noTextCache;
  NABoolean aqrPrepare;
  NABoolean standaloneQuery;
  isDDL_ = TRUE;

  if (processRecvdCmpCompileInfo(NULL,
				 statement,
  				 statement.getCmpCompileInfo(),
				 context_,
				 sqlStr, 
				 sqlStrLen, // out - long &
				 inputCS,
				 isSchNameRecvd, 
				 currCatName, currSchName, 
				 recompControlInfo,
				 nametypeNsk,
				 odbcProcess,
				 noTextCache,
				 aqrPrepare,
				 standaloneQuery))
    return CmpStatement_ERROR;
  CmpCommon::context()->sqlSession()->setParentQid(statement.getParentQid());

  // process recompControlInfo, if received
  if (recompControlInfo)
    setupRecompControlInfo(recompControlInfo, &cmpmain);

  cmpmain.setSqlParserFlags(statement.getFlags());

  // set the current catalog and schema names.
  InitSchemaDB();

  DDLExpr *ddlExpr = NULL;
  ExprNode *ddlNode = NULL;
  if (sqlStr)
    {
      if (getDDLExprAndNode(sqlStr, inputCS, ddlExpr, ddlNode))
        {
          return CmpStatement_ERROR;
        }
    }

  CmpDDLwithStatusInfo *dws = statement.getCmpDDLwithStatusInfo();
  if ((dws->getMDupgrade()) || (dws->getMDVersion()) || (dws->getSWVersion()))
    {
      CmpSeabaseMDupgrade cmpMDU(heap_);
      
      NABoolean ddlXns = (CmpCommon::getDefault(DDL_TRANSACTIONS) == DF_ON);
      if (cmpMDU.executeSeabaseMDupgrade(dws, ddlXns,
                                         currCatName, currSchName))
        return CmpStatement_ERROR;
    }
  else if (dws->getMDcleanup())
    {
      CmpSeabaseDDL cmpSBD(heap_);
      if (cmpSBD.executeSeabaseDDL(ddlExpr, ddlNode,
                                   currCatName, currSchName,
                                   dws))
        {
          Set_SqlParser_Flags(0);
          return CmpStatement_ERROR;
        }
      Set_SqlParser_Flags (0);
    }
  else
    {
      return CmpStatement_ERROR;
    }

  /*
  CmpDDLwithStatusInfo * replyDWS = NULL;
  replyDWS = new(outHeap_) CmpDDLwithStatusInfo(); 
  replyDWS->copyStatusInfo(dws);
  */

  dws->init();

  Lng32 replyDataLen = dws->getLength();
  char * replyData = new(outHeap_) char[replyDataLen];
  dws->pack(replyData);

  CmpDDLwithStatusInfo * replyDWS = (CmpDDLwithStatusInfo*)replyData;
  
  reply_ =
    new(outHeap_) CmpMessageReplyCode( outHeap_, statement.id(), 0, 0, outHeap_);
  reply_->data() = replyData;
  reply_->size() = replyDataLen;

  return CmpStatement_SUCCESS;
}
// ----------------------------------------------------------------------------
// method: getPrivileges
//
// If authorization is enabled, set privs based on the passed in priv_desc
// and set up query invalidation (security) keys for the routine.
// ----------------------------------------------------------------------------
void NARoutine::getPrivileges(TrafDesc *priv_desc)
{
  if ( !CmpCommon::context()->isAuthorizationEnabled() || ComUser::isRootUserID())
  {
    privInfo_ = new(heap_) PrivMgrUserPrivs;
    privInfo_->setOwnerDefaultPrivs();
    return;
  }

  NAString privMDLoc = CmpSeabaseDDL::getSystemCatalogStatic();
  privMDLoc += ".\"";
  privMDLoc += SEABASE_PRIVMGR_SCHEMA;
  privMDLoc += "\"";
  PrivMgrCommands privInterface(privMDLoc.data(), CmpCommon::diags(),PrivMgr::PRIV_INITIALIZED);

  if (priv_desc == NULL)
  {
    privInfo_ = new(heap_) PrivMgrUserPrivs;

    CmpSeabaseDDL cmpSBD(STMTHEAP);
    if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
    {
      if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
        *CmpCommon::diags() << DgSqlCode( -4400 );

      return;
    }

    ComObjectType objectType = (UDRType_ == COM_PROCEDURE_TYPE ?
                                COM_STORED_PROCEDURE_OBJECT :
                                COM_USER_DEFINED_ROUTINE_OBJECT);

    std::vector <ComSecurityKey *>* secKeyVec = new(heap_) std::vector<ComSecurityKey *>;
    if (privInterface.getPrivileges(objectUID_, objectType,
                                    ComUser::getCurrentUser(), 
                                   *privInfo_, secKeyVec) != STATUS_GOOD)
    {
      NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
      privInfo_ = NULL;
    }

    cmpSBD.switchBackCompiler();

    if (privInfo_)
    {
      for (std::vector<ComSecurityKey*>::iterator iter = secKeyVec->begin();
           iter != secKeyVec->end();
           iter++)
      {
        // Insertion of the dereferenced pointer results in NASet making
        // a copy of the object, and then we delete the original.
        routineSecKeySet_.insert(**iter);
          delete *iter;
      }
    }
  }
  else
  {
    // get roles granted to current user 
    // SQL_EXEC_GetRoleList returns the list of roles from the CliContext
    std::vector<int32_t> myRoles;
    Int32 numRoles = 0;
    Int32 *roleIDs = NULL;
    if (SQL_EXEC_GetRoleList(numRoles, roleIDs) < 0)
    {
      *CmpCommon::diags() << DgSqlCode(-1034);
      return;
    }

    // At this time we should have at least one entry in roleIDs (PUBLIC_USER)
    CMPASSERT (roleIDs && numRoles > 0);

    for (Int32 i = 0; i < numRoles; i++)
      myRoles.push_back(roleIDs[i]);

    privInfo_ = new (heap_) PrivMgrUserPrivs;
    privInfo_->initUserPrivs(myRoles, priv_desc, ComUser::getCurrentUser(),objectUID_, routineSecKeySet_);
  }
}