/**********************************************************************
// @@@ 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:         QueryCacheSt.cpp
 * Description:
 *
 *
 * Created:      3/19/2002
 * Language:     C++
 *
 *****************************************************************************
 */

#include "QueryCacheSt.h"
#include "QCache.h"
#include "CmpMain.h"
#include "Globals.h"
#include "Context.h"

SP_STATUS QueryCacheStatStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "QueryCache");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
     //column as input parameter for ISP, specifiy query cache of metadata or user context
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance char(16)  not null");
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location char(16)  not null"); 
     return SP_SUCCESS;
}

SP_STATUS QueryCacheStatStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
							    SP_COMPILE_HANDLE spCompileObj,
							    SP_HANDLE spObj,
							    SP_ERROR_STRUCT *error)
{
  *numFields = 21;
  return SP_SUCCESS;
}


// Specifies the columns of the QueryCache table and their types
SP_STATUS QueryCacheStatStoredProcedure::sp_OutputFormat(SP_FIELDDESC_STRUCT *format,
							 SP_KEYDESC_STRUCT keyFields[],
							 Lng32 *numKeyFields,
							 SP_HANDLE spCompileObj,
							 SP_HANDLE spObj,
							 SP_ERROR_STRUCT *error)
{
  strcpy(&((format++)->COLUMN_DEF[0]), "Avg_template_size     	INT UNSIGNED"); //  0
  strcpy(&((format++)->COLUMN_DEF[0]), "Current_size       	INT UNSIGNED"); //  1
  strcpy(&((format++)->COLUMN_DEF[0]), "Max_cache_size        	INT UNSIGNED"); //  2
  strcpy(&((format++)->COLUMN_DEF[0]), "Max_num_victims       INT UNSIGNED"); //  3
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_entries    	    	INT UNSIGNED"); //  4
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_plans    	    	INT UNSIGNED"); //  5
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_compiles        	INT UNSIGNED"); //  6
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_recompiles        	INT UNSIGNED"); //  7
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_retries    	    	INT UNSIGNED"); //  8
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cacheable_parsing  	INT UNSIGNED"); //  9
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cacheable_binding  	INT UNSIGNED"); // 10
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cache_hits_parsing 	INT UNSIGNED"); // 11
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cache_hits_binding 	INT UNSIGNED"); // 12
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_cacheable_too_large	INT UNSIGNED"); // 13
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_displaced  		INT UNSIGNED"); // 14
  strcpy(&((format++)->COLUMN_DEF[0]), "Optimization_level    	CHAR(10 BYTES) character set utf8");	// 15
  strcpy(&((format++)->COLUMN_DEF[0]), "Text_cache_hits INT UNSIGNED"); // 16
  strcpy(&((format++)->COLUMN_DEF[0]), "Avg_text_size        	INT UNSIGNED"); //  17
  strcpy(&((format++)->COLUMN_DEF[0]), "Text_entries   	    	INT UNSIGNED"); //  18
  strcpy(&((format++)->COLUMN_DEF[0]), "Displaced_texts 		INT UNSIGNED"); //  19
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_lookups        	INT UNSIGNED"); //  20
  return SP_SUCCESS;
}

// Copies information on the query cache by the interface provided in
// QueryCache.h and processes it
SP_STATUS
  QueryCacheStatStoredProcedure::sp_Process(SP_PROCESS_ACTION action,
					    SP_ROW_DATA inputData,
					    SP_EXTRACT_FUNCPTR eFunc,
					    SP_ROW_DATA outputData,
					    SP_FORMAT_FUNCPTR fFunc,
					    SP_KEY_VALUE keys,
					    SP_KEYVALUE_FUNCPTR kFunc,
					    SP_PROCESS_HANDLE *spProcHandle,
					    SP_HANDLE spObj,
					    SP_ERROR_STRUCT *error)
{  
  if (action == SP_PROC_OPEN) {
  
    QueryCacheStatsISPIterator * it = new (GetCliGlobals()->exCollHeap()) QueryCacheStatsISPIterator(inputData, eFunc, error,
                                                                              GetCliGlobals()->currContext()->getCmpContextInfo(), GetCliGlobals()->exCollHeap());
    *spProcHandle = it;
    
    return SP_SUCCESS;
  }

  if (action == SP_PROC_FETCH) {
    QueryCacheStatsISPIterator* it = (QueryCacheStatsISPIterator *)(*spProcHandle);

    if (!it) {
      return SP_FAIL;
    }

    QueryCacheStats stats;
    if(!it->getNext(stats))
       return SP_SUCCESS;

    ULong kBytes;

    kBytes = stats.avgPlanSize;
    fFunc(0,  outputData, sizeof(kBytes), &(kBytes), 0);
    kBytes = stats.s.currentSize / 1024;
    fFunc(1,  outputData, sizeof(kBytes), &(kBytes), 0);
    kBytes = stats.maxSize / 1024;
    fFunc(2,  outputData, sizeof(kBytes), &(kBytes), 0);
    fFunc(3,  outputData, sizeof(stats.maxVictims),	&(stats.maxVictims),  0);
    fFunc(4,  outputData, sizeof(stats.nEntries),	&(stats.nEntries),    0);
    fFunc(5,  outputData, sizeof(stats.nPlans),		&(stats.nPlans),    0);
    fFunc(6,  outputData, sizeof(stats.nCompiles),	&(stats.nCompiles),   0);
    fFunc(7,  outputData, sizeof(stats.s.nRecompiles),	&(stats.s.nRecompiles), 0);
    fFunc(8,  outputData, sizeof(stats.nRetries),	&(stats.nRetries),    0);
    fFunc(9,  outputData, sizeof(stats.s.nCacheableP),	&(stats.s.nCacheableP), 0);
    fFunc(10, outputData, sizeof(stats.s.nCacheableB),	&(stats.s.nCacheableB), 0);
    fFunc(11, outputData, sizeof(stats.s.nCacheHitsP),	&(stats.s.nCacheHitsP), 0);
    fFunc(12, outputData, sizeof(stats.s.nCacheHitsB),	&(stats.s.nCacheHitsB), 0);
    fFunc(13, outputData, sizeof(stats.nTooLarge),	&(stats.nTooLarge),   0);
    fFunc(14, outputData, sizeof(stats.nDisplaced),	&(stats.nDisplaced),  0);
    char optimizationLevel[8];
    switch (stats.optimLvl) {
      case CompilerEnv::OPT_MINIMUM:
	strcpy(optimizationLevel, "0      ");	  break;
      case CompilerEnv::OPT_MEDIUM_LOW:
	strcpy(optimizationLevel, "2      ");	  break;
      case CompilerEnv::OPT_MEDIUM:
	strcpy(optimizationLevel, "3      ");	  break;
      case CompilerEnv::OPT_MAXIMUM:
	strcpy(optimizationLevel, "5      ");	  break;
	default: strcpy(optimizationLevel, "UNKNOWN"); break;
    }

    fFunc(15,outputData,(Lng32)strlen(optimizationLevel),optimizationLevel,1);
    fFunc(16,outputData,sizeof(stats.s.nCacheHitsPP),&(stats.s.nCacheHitsPP),0);
    fFunc(17,outputData,sizeof(stats.avgTEntSize),&(stats.avgTEntSize),0);
    fFunc(18,outputData,sizeof(stats.nTextEntries),&(stats.nTextEntries),0);
    fFunc(19,outputData,sizeof(stats.nDispTEnts),&(stats.nDispTEnts),0);
    fFunc(20,outputData,sizeof(stats.s.nLookups),&(stats.s.nLookups),0);

    return SP_MOREDATA;
  } // if (action == SP_PROC_FETCH)

  if (action == SP_PROC_CLOSE) {
    NADELETEBASIC((QueryCacheStatsISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
    return SP_SUCCESS;
  }

  return SP_SUCCESS;
}

// Registers the QueryCache function
void QueryCacheStatStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("QUERYCACHE",
           sp_Compile,
           sp_InputFormat,
	   0,
           sp_NumOutputFields,
           sp_OutputFormat,
	   sp_Process,
	   0,
	   CMPISPVERSION);
}

SP_STATUS QueryCacheEntriesStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "QueryCacheEntries");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
     //column as input parameter for ISP, specifiy query cache of metadata or user context
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance    char(16) not null");
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location    char(16) not null"); 
     return SP_SUCCESS;
}

SP_STATUS
  QueryCacheEntriesStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
						       SP_COMPILE_HANDLE spCompileObj,
						       SP_HANDLE spObj,
						       SP_ERROR_STRUCT *error)
{
  *numFields = 20;
  return SP_SUCCESS;
}

// Specifies the columns of the QueryCacheEntries table and their types
SP_STATUS QueryCacheEntriesStoredProcedure::sp_OutputFormat(
						SP_FIELDDESC_STRUCT* format,
						SP_KEYDESC_STRUCT*  /*keyFields */,
						Lng32*  /*numKeyFields */,
						SP_COMPILE_HANDLE cmpHandle,
						SP_HANDLE /* spHandle */,
						SP_ERROR_STRUCT* /* error */  )
{
  strcpy(&((format++)->COLUMN_DEF[0]), "Row_id        		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Plan_id     		LARGEINT");
  strcpy(&((format++)->COLUMN_DEF[0]), "Text  			VARCHAR(4096 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Entry_size  		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Plan_length  		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_hits        	INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Phase        		CHAR(10 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Optimization_level	CHAR(10 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Catalog_name 		CHAR(40 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Schema_name 		CHAR(40 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Num_params   		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Param_types   		VARCHAR(1024 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Compilation_time	INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Average_hit_time	INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "Shape    		VARCHAR(1024 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Isolation_level    	CHAR(20 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Isolation_level_For_Updates   	CHAR(20 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Access_mode     	CHAR(20 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Auto_commit     	CHAR(15 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "Rollback_mode     	CHAR(15 BYTES) character set utf8");
  return SP_SUCCESS;
}

void
setIsolationLevelAsString(TransMode::IsolationLevel il,
                          char* buffer, Int32 bufLen)
{
   memset(buffer, ' ', bufLen);
   strcpy(buffer, getStrOfIsolationLevel(il, FALSE));
}

// Copies information on the query cache by the interface provided in
// QueryCache.h and processes it
SP_STATUS QueryCacheEntriesStoredProcedure::sp_Process(SP_PROCESS_ACTION action,
						       SP_ROW_DATA  inputData ,
						       SP_EXTRACT_FUNCPTR  eFunc ,
						       SP_ROW_DATA outputData ,
						       SP_FORMAT_FUNCPTR fFunc,
						       SP_KEY_VALUE,
						       SP_KEYVALUE_FUNCPTR,
						       SP_PROCESS_HANDLE* spProcHandle,
						       SP_HANDLE /* spHandle */,
						       SP_ERROR_STRUCT*  error )
{
  switch (action) {
  case SP_PROC_OPEN:
    {
      QueryCacheEntriesISPIterator * it = new (GetCliGlobals()->exCollHeap()) QueryCacheEntriesISPIterator(inputData, eFunc, error, 
                                                                                   GetCliGlobals()->currContext()->getCmpContextInfo(), GetCliGlobals()->exCollHeap());
      
      *spProcHandle = it;

      return SP_SUCCESS;
    }
    break;

  case SP_PROC_FETCH:
    {
      QueryCacheEntriesISPIterator * it = (QueryCacheEntriesISPIterator *)(*spProcHandle);
      if (!it) {
        return SP_FAIL;
      }

      QueryCacheDetails details;
      if(!it->getNext(details))
         return SP_SUCCESS;

      fFunc(0,  outputData, sizeof(Int32),	&(it->counter()), 0);
      fFunc(1,  outputData, sizeof(details.planId),	&(details.planId), 0);
      fFunc(2,outputData,(Lng32)strlen(details.qryTxt),(void*)(details.qryTxt),1);
      fFunc(3,  outputData, sizeof(details.entrySize),	&(details.entrySize), 0);
      fFunc(4,  outputData, sizeof(details.planLength), &(details.planLength), 0);
      fFunc(5,  outputData, sizeof(details.nOfHits),	&(details.nOfHits), 0);

      char phase[11];

      switch (details.phase) {
      case CmpMain::PREPARSE:  strcpy(phase, "PREPARSING"); break;
      case CmpMain::PARSE:  strcpy(phase, "PARSING   "); break;
      case CmpMain::BIND:  strcpy(phase, "BINDING   "); break;
      default: strcpy(phase, "UNKNOWN   "); break;
      }
      fFunc(6,outputData,(Lng32)strlen(phase),phase,1);

      char optimizationLevel[8];

      switch (details.optLvl) {
      case CompilerEnv::OPT_MINIMUM:    strcpy(optimizationLevel, "0      ");	break;
      case CompilerEnv::OPT_MEDIUM_LOW: strcpy(optimizationLevel, "2      ");	break;
      case CompilerEnv::OPT_MEDIUM:     strcpy(optimizationLevel, "3      ");	break;
      case CompilerEnv::OPT_MAXIMUM:    strcpy(optimizationLevel, "5      ");	break;
      default: strcpy(optimizationLevel,"UNKNOWN");				break;
	  }
      fFunc(7,outputData,(Lng32)strlen(optimizationLevel),optimizationLevel,1);
      fFunc(8,outputData,(Lng32)strlen(details.catalog),(void*)(details.catalog),1);
      fFunc(9,outputData,(Lng32)strlen(details.schema),(void*)(details.schema),1);
      fFunc(10, outputData, sizeof(details.nParams), &(details.nParams), 0);
      fFunc(11,outputData,(Lng32)strlen(details.paramTypes),(void*)(details.paramTypes),1);

      ULong time = details.compTime / 1000;
      fFunc(12, outputData, sizeof(time), &(time), 0);
      time = details.avgHitTime / 1000;
      fFunc(13, outputData, sizeof(time), &(time), 0);
      fFunc(14,outputData,(Lng32)strlen(details.reqdShape),(void*)(details.reqdShape),1);

      char isolationLevel[18];

      setIsolationLevelAsString(details.isoLvl, isolationLevel, 18);
      fFunc(15,outputData,(Lng32)strlen(isolationLevel),isolationLevel,1);

      setIsolationLevelAsString(details.isoLvlForUpdates, isolationLevel, 18);
      fFunc(16,outputData,(Lng32)strlen(isolationLevel),isolationLevel,1);

      char accessMode[14];
      switch(details.accMode) {
      case TransMode::READ_ONLY_:
      case TransMode::READ_ONLY_SPECIFIED_BY_USER_:
        strcpy(accessMode, "READ ONLY    ");	break;
      case TransMode::READ_WRITE_:
        strcpy(accessMode, "READ/WRITE   ");	break;
      default:
        strcpy(accessMode, "NOT SPECIFIED");	break;
      }
      fFunc(17,outputData,(Lng32)strlen(accessMode),accessMode,1);

      char autoCommit[14];
      switch(details.autoCmt) {
      case TransMode::ON_:
        strcpy(autoCommit, "ON           ");	break;
      case TransMode::OFF_:
        strcpy(autoCommit, "OFF          ");	break;
      default:
        strcpy(autoCommit, "NOT SPECIFIED");	break;
      }
      fFunc(18,outputData,(Lng32)strlen(autoCommit),autoCommit,1);

      char rollBackMode[14];
      switch(details.rbackMode) {
      case TransMode::ROLLBACK_MODE_WAITED_:
        strcpy(rollBackMode, "WAITED       ");	break;
      case TransMode::ROLLBACK_MODE_NOWAITED_:
        strcpy(rollBackMode, "NO WAITED    ");	break;
      default:
        strcpy(rollBackMode, "NOT SPECIFIED");	break;
	  }
      fFunc(19,outputData,(Lng32)strlen(rollBackMode),rollBackMode,1);

      it->counter()++;

      return SP_MOREDATA;
    }
    break;

  case SP_PROC_CLOSE: {
    NADELETEBASIC((QueryCacheEntriesISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
    return SP_SUCCESS;
  }

  default: break;
  } // switch
  return SP_SUCCESS;
}

// Registers the QueryCache function
void QueryCacheEntriesStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("QUERYCACHEENTRIES",
           sp_Compile,
           sp_InputFormat,
	   0,
           sp_NumOutputFields,
           sp_OutputFormat,
	   sp_Process,
	   0,
	   CMPISPVERSION);
}


//-----------------------------------------------------------------------
// QueryCacheDeleteStoredProcedure is a class that contains functions used
// to delete the contents of the  QueryCache virtual table. The delete 
// function is implemented as an internal stored procedure.
//-----------------------------------------------------------------------


SP_STATUS QueryCacheDeleteStoredProcedure::sp_Process(
  SP_PROCESS_ACTION action,
  SP_ROW_DATA inputData,
  SP_EXTRACT_FUNCPTR eFunc,
  SP_ROW_DATA outputData,
  SP_FORMAT_FUNCPTR fFunc,
  SP_KEY_VALUE keys,
  SP_KEYVALUE_FUNCPTR kFunc,
  SP_PROCESS_HANDLE *spProcHandle,
  SP_HANDLE spObj,
  SP_ERROR_STRUCT *error)
{
  SP_STATUS status = SP_SUCCESS;
  switch (action)
  {
  case SP_PROC_OPEN:
    {
      QueryCacheDeleter* deleter = new (GetCliGlobals()->exCollHeap()) QueryCacheDeleter(inputData, eFunc, error, 
                                   GetCliGlobals()->currContext()->getCmpContextInfo(), GetCliGlobals()->exCollHeap());
      *spProcHandle = deleter;
    }
    break;
  case SP_PROC_FETCH:
    {
      QueryCacheDeleter* deleter = (QueryCacheDeleter*)(*spProcHandle);
      if (deleter == NULL )
      {
        status = SP_FAIL;
        break;
      }
      //clear all specified QueryCache
      deleter->doDelete();
    }
    break;
  case SP_PROC_CLOSE:
    NADELETEBASIC((QueryCacheDeleter *)(*spProcHandle), GetCliGlobals()->exCollHeap());
    break;
  }
  return status;
}

void QueryCacheDeleteStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("QUERYCACHEDELETE",
          sp_Compile,
          sp_InputFormat,
          0,
          sp_NumOutputFields,
          sp_OutputFormat,
          sp_Process,
          0,
	  CMPISPVERSION);
}

SP_STATUS QueryCacheDeleteStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
                                  Lng32 numFields,
                                  SP_COMPILE_HANDLE spCompileObj,
                                  SP_HANDLE spObj,
                                  SP_ERROR_STRUCT *error)
{
    if ( numFields != 2 )
    {
      //accepts 2 input columns
      error->error = arkcmpErrorISPWrongInputNum;
      strcpy(error->optionalString[0], "QueryCacheDelete");
      error->optionalInteger[0] = 2;
      return SP_FAIL;
    }

   //column as input parameter for ISP, specifiy query cache of metadata or user context
   strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance    char(16) not null");
   strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location    char(16) not null"); 
   return SP_SUCCESS;
}

//------------------------Hybrid Query Cache Stat--------------------------//
void HybridQueryCacheStatStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("HYBRIDQUERYCACHE",
          sp_Compile,
          sp_InputFormat,
          0,
          sp_NumOutputFields,
          sp_OutputFormat,
          sp_Process,
          0,
	  CMPISPVERSION);
}

SP_STATUS HybridQueryCacheStatStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "HybridQueryCache");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
     //column as input parameter for ISP, specifiy query cache of metadata or user context
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance char(16) not null");  
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location char(16)  not null");  
     return SP_SUCCESS;
}

SP_STATUS
  HybridQueryCacheStatStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
						       SP_COMPILE_HANDLE spCompileObj,
						       SP_HANDLE spObj,
						       SP_ERROR_STRUCT *error)
{
  *numFields = 4;
  return SP_SUCCESS;
}

SP_STATUS HybridQueryCacheStatStoredProcedure::sp_OutputFormat(
						SP_FIELDDESC_STRUCT* format,
						SP_KEYDESC_STRUCT*  /*keyFields */,
						Lng32*  /*numKeyFields */,
						SP_COMPILE_HANDLE cmpHandle,
						SP_HANDLE /* spHandle */,
						SP_ERROR_STRUCT* /* error */  )
{
  strcpy(&((format++)->COLUMN_DEF[0]), "num_hkeys                                    INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_skeys                                     INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_max_values_per_key            INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_hash_table_buckets              INT UNSIGNED");
  return SP_SUCCESS;
}

SP_STATUS HybridQueryCacheStatStoredProcedure::sp_Process(SP_PROCESS_ACTION action,
						       SP_ROW_DATA  inputData ,
						       SP_EXTRACT_FUNCPTR  eFunc ,
						       SP_ROW_DATA outputData ,
						       SP_FORMAT_FUNCPTR fFunc,
						       SP_KEY_VALUE keys,
						       SP_KEYVALUE_FUNCPTR kFunc,
						       SP_PROCESS_HANDLE* spProcHandle,
						       SP_HANDLE spObj/* spHandle */,
						       SP_ERROR_STRUCT*  error )		       
{
  switch (action) {
    case SP_PROC_OPEN:
    {
        HybridQueryCacheStatsISPIterator * it = new (GetCliGlobals()->exCollHeap()) HybridQueryCacheStatsISPIterator(inputData, eFunc, error, 
                                                                                                 GetCliGlobals()->currContext()->getCmpContextInfo(), GetCliGlobals()->exCollHeap());
        *spProcHandle = it;
        
        return SP_SUCCESS;
    }
    break;

    case SP_PROC_FETCH:
    {
      HybridQueryCacheStatsISPIterator* it = (HybridQueryCacheStatsISPIterator *)(*spProcHandle);
      if (!it) {
        return SP_FAIL;
      }

      HybridQueryCacheStats stats;
      if(!it->getNext(stats))
         return SP_SUCCESS;
         
      fFunc(0,  outputData, sizeof(stats.nHKeys),	&(stats.nHKeys), 0);
      fFunc(1,  outputData, sizeof(stats.nSKeys),	&(stats.nSKeys), 0);
      fFunc(2,  outputData, sizeof(stats.nMaxValuesPerKey),	&(stats.nMaxValuesPerKey), 0);
      fFunc(3,  outputData, sizeof(stats.nHashTableBuckets),	&(stats.nHashTableBuckets), 0);
      
      return SP_MOREDATA;
    }
    break;

    case SP_PROC_CLOSE: {
       NADELETEBASIC((HybridQueryCacheStatsISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
       return SP_SUCCESS;
    }
    break;
     
    default: break;
  } // switch
  return SP_SUCCESS;
}

//------------------------Hybrid Query Cache Entries--------------------------//
void HybridQueryCacheEntriesStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
  regFunc("HYBRIDQUERYCACHEENTRIES",
          sp_Compile,
          sp_InputFormat,
          0,
          sp_NumOutputFields,
          sp_OutputFormat,
          sp_Process,
          0,
	  CMPISPVERSION);
}

SP_STATUS HybridQueryCacheEntriesStoredProcedure::sp_InputFormat(SP_FIELDDESC_STRUCT *inputFieldFormat,
				  Lng32 numFields,
				  SP_COMPILE_HANDLE spCompileObj,
				  SP_HANDLE spObj,
	    			  SP_ERROR_STRUCT *error)
{
      if ( numFields != 2 )
      {
        //accepts 2 input columns
        error->error = arkcmpErrorISPWrongInputNum;
        strcpy(error->optionalString[0], "HybridQueryCacheEntries");
        error->optionalInteger[0] = 2;
        return SP_FAIL;
      }
  
      // Describe input columns
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "instance char(16)  not null");
     strcpy(&((inputFieldFormat++)->COLUMN_DEF[0]), "location char(16)   not null"); 
     return SP_SUCCESS;
}

SP_STATUS
  HybridQueryCacheEntriesStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
						       SP_COMPILE_HANDLE spCompileObj,
						       SP_HANDLE spObj,
						       SP_ERROR_STRUCT *error)
{
  *numFields = 8;
  return SP_SUCCESS;
}

SP_STATUS HybridQueryCacheEntriesStoredProcedure::sp_OutputFormat(
						SP_FIELDDESC_STRUCT* format,
						SP_KEYDESC_STRUCT*  /*keyFields */,
						Lng32*  /*numKeyFields */,
						SP_COMPILE_HANDLE cmpHandle,
						SP_HANDLE /* spHandle */,
						SP_ERROR_STRUCT* /* error */  )
{
  strcpy(&((format++)->COLUMN_DEF[0]), "plan_id     		LARGEINT");
  strcpy(&((format++)->COLUMN_DEF[0]), "hkey  			VARCHAR(4096 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "skey        		VARCHAR(4096 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_hits  		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_PLiterals  		INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "PLiterals	VARCHAR(4096 BYTES) character set utf8");
  strcpy(&((format++)->COLUMN_DEF[0]), "num_NPLiterals        	INT UNSIGNED");
  strcpy(&((format++)->COLUMN_DEF[0]), "NPLiterals   VARCHAR(4096 BYTES) character set utf8");
  return SP_SUCCESS;
}


SP_STATUS HybridQueryCacheEntriesStoredProcedure::sp_Process(SP_PROCESS_ACTION action,
						       SP_ROW_DATA  inputData ,
						       SP_EXTRACT_FUNCPTR  eFunc ,
						       SP_ROW_DATA outputData ,
						       SP_FORMAT_FUNCPTR fFunc,
						       SP_KEY_VALUE keys,
						       SP_KEYVALUE_FUNCPTR kFunc,
						       SP_PROCESS_HANDLE* spProcHandle,
						       SP_HANDLE spObj/* spHandle */,
						       SP_ERROR_STRUCT*  error )		       
{
  switch (action) {
    case SP_PROC_OPEN:
    {
        HybridQueryCacheEntriesISPIterator * it = new (GetCliGlobals()->exCollHeap()) HybridQueryCacheEntriesISPIterator(inputData, eFunc, error, 
                                                                                                    GetCliGlobals()->currContext()->getCmpContextInfo(), GetCliGlobals()->exCollHeap());

        *spProcHandle = it;
        
        return SP_SUCCESS;
    }
    break;

    case SP_PROC_FETCH:
    {
       HybridQueryCacheEntriesISPIterator* it = (HybridQueryCacheEntriesISPIterator *)(*spProcHandle);
       if (!it) 
          return SP_FAIL;
      
      //fill data field
      HybridQueryCacheDetails details;
      
      if(!it->getNext(details))
           return SP_SUCCESS;

      fFunc(0, outputData, sizeof(details.planId), &(details.planId), 0);
      
      Lng32 len = (Lng32)details.hkeyTxt.length() < 2048 ? (Lng32)details.hkeyTxt.length() : 2048;
      fFunc(1, outputData, len, (void*)(details.hkeyTxt.data()),1);

      len = (Lng32)details.skeyTxt.length() < 2048 ? (Lng32)details.skeyTxt.length() : 2048;
      fFunc(2, outputData,(Lng32)details.skeyTxt.length(), (void*)(details.skeyTxt.data()),1);

      fFunc(3, outputData, sizeof(details.nHits), &(details.nHits), 0);
      
      fFunc(4, outputData, sizeof(details.nOfPConst),	&(details.nOfPConst), 0);

      len = (Lng32)details.PConst.length() < 1024 ? (Lng32)details.PConst.length() : 1024;
      fFunc(5, outputData,(Lng32)details.PConst.length(), (void*)(details.PConst.data()),1);
      
      fFunc(6, outputData, sizeof(details.nOfNPConst),	&(details.nOfNPConst), 0);

      len = (Lng32)details.NPConst.length() < 1024 ? (Lng32)details.NPConst.length() : 1024;
      fFunc(7, outputData,(Lng32)details.NPConst.length(), (void*)(details.NPConst.data()),1);
      
      return SP_MOREDATA;
    }
    break;

    case SP_PROC_CLOSE: {
       NADELETEBASIC((HybridQueryCacheEntriesISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
       return SP_SUCCESS;
    }
    break;
     
    default: break;
  } // switch
    return SP_SUCCESS;
}


NABoolean ISPIterator::initializeISPCaches(SP_ROW_DATA  inputData, SP_EXTRACT_FUNCPTR  eFunc, SP_ERROR_STRUCT* error, 
                                  const NAArray<CmpContextInfo*> & ctxs, //input 
                                  NAString & contextName, 
                                  Int32 & index           //output, set initial index in arrary of CmpContextInfos
                                  ) 
{
//extract ISP input, find QueryCache belonging to specified context
//and use it for fetch later
  Lng32 maxSize = 16;
  char receivingField[maxSize+1];
  if (eFunc (0, inputData, (Lng32)maxSize, receivingField, FALSE) == SP_ERROR_EXTRACT_DATA)
  {
      error->error = arkcmpErrorISPFieldDef;
      return FALSE;
  }
   //choose context
   // 1. Search ctxInfos_ for all context with specified name('USER', 'META', 'USTATS'),
   //    'ALL' option will fetch all context in ctxInfos_, index is set to 0, qcache is always NULL, 
   // 2. For remote arkcmp, which has 0 context in ctxInfos_, index is always -1, 

  NAString qCntxt = receivingField;
  qCntxt.toLower();
  //the receivingField is of pattern xxx$trafodion.yyy, 
  //where xxx is the desired input string.
  Int32 dollarIdx = qCntxt.index("$");
  CMPASSERT(dollarIdx > 0);
  //find the specified context
  if(ctxs.entries() == 0){
    //for remote compiler
    if( (dollarIdx==3 && strncmp(qCntxt.data(), "all", dollarIdx)==0) 
     ||(dollarIdx==4 && strncmp(qCntxt.data(), "user", dollarIdx)==0) )
      index = -1;
  }
  else
  {
    if(dollarIdx==3 && strncmp(qCntxt.data(), "all", dollarIdx)==0)
    {
       contextName = "ALL";
       index = 0;
    }
    else if(dollarIdx==4 && strncmp(qCntxt.data(), "user", dollarIdx)==0)
    {
       contextName = "NONE";
       index = 0;
    }
    else if(dollarIdx==4 && strncmp(qCntxt.data(), "meta", dollarIdx)==0)
    {
       contextName = "META";
       index = 0;
    }
    else if(dollarIdx==6 && strncmp(qCntxt.data(), "ustats", dollarIdx)==0)
    {
       contextName = "USTATS";
       index = 0;
    }
  }           
  return TRUE;
}

