blob: f87ff96d95c804181772f74cf3f4799eb53891a9 [file] [log] [blame]
/**********************************************************************
// @@@ 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: NATableSt.cpp
* Description:
*
* Created: 2/06/2012
* Language: C++
*
*****************************************************************************
*/
#include "NATable.h"
#include "NATableSt.h"
#include "SchemaDB.h"
#include "CmpErrors.h"
#include "CmpMain.h"
#include "Globals.h"
#include "Context.h"
//-----------------------------------------------------------------------
// NATableCacheStoredProcedure is a class that contains functions used by
// the NATableCache virtual table, whose purpose is to serve as an interface
// to the SQL/MX NATable cache statistics. This table is implemented as
// an internal stored procedure.
//-----------------------------------------------------------------------
SP_STATUS NATableCacheStatStoredProcedure::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], "NATableCache");
error->optionalInteger[0] = 2;
return SP_FAIL;
}
//column as input parameter for ISP, specifiy 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;
}
const Lng32 NUM_OF_OUTPUT = 7;
SP_STATUS NATableCacheStatStoredProcedure::sp_NumOutputFields(
Lng32 *numFields,
SP_COMPILE_HANDLE spCompileObj,
SP_HANDLE spObj,
SP_ERROR_STRUCT *error)
{
*numFields = NUM_OF_OUTPUT;
return SP_SUCCESS;
}
SP_STATUS NATableCacheStatStoredProcedure::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]), "Context CHAR(8) CHARACTER SET ISO88591");
strcpy(&((format++)->COLUMN_DEF[0]), "Num_lookups INT UNSIGNED");
strcpy(&((format++)->COLUMN_DEF[0]), "Num_cache_hits INT UNSIGNED");
strcpy(&((format++)->COLUMN_DEF[0]), "Num_entries INT UNSIGNED");
strcpy(&((format++)->COLUMN_DEF[0]), "Current_cache_size INT UNSIGNED");
strcpy(&((format++)->COLUMN_DEF[0]), "High_watermark INT UNSIGNED");
strcpy(&((format++)->COLUMN_DEF[0]), "Max_cache_size INT UNSIGNED");
return SP_SUCCESS;
}
SP_STATUS NATableCacheStatStoredProcedure::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) {
NATableCacheStatsISPIterator * it = new (GetCliGlobals()->exCollHeap())
NATableCacheStatsISPIterator(inputData, eFunc, error,
GetCliGlobals()->currContext()->getCmpContextInfo(),
GetCliGlobals()->exCollHeap());
*spProcHandle = it;
return SP_SUCCESS;
}
if (action == SP_PROC_FETCH) {
NATableCacheStatsISPIterator* it = (NATableCacheStatsISPIterator *)(*spProcHandle);
if (!it) {
return SP_FAIL;
}
NATableCacheStats stats;
if(!it->getNext(stats))
return SP_SUCCESS;
fFunc(0, outputData, sizeof(stats.contextType), &(stats.contextType), 0);
fFunc(1, outputData, sizeof(ULng32), &(stats.numLookups), 0);
fFunc(2, outputData, sizeof(ULng32), &(stats.numCacheHits), 0);
fFunc(3, outputData, sizeof(ULng32), &(stats.numEntries), 0);
fFunc(4, outputData, sizeof(ULng32), &(stats.currentCacheSize), 0);
fFunc(5, outputData, sizeof(ULng32), &(stats.highWaterMark), 0);
fFunc(6, outputData, sizeof(ULng32), &(stats.maxCacheSize), 0);
return SP_MOREDATA;
}
if (action == SP_PROC_CLOSE) {
if (*spProcHandle)
NADELETEBASIC((NATableCacheStatsISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
return SP_SUCCESS;
}
return SP_SUCCESS;
}
void NATableCacheStatStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
regFunc("NATABLECACHE",
sp_Compile,
sp_InputFormat,
0,
sp_NumOutputFields,
sp_OutputFormat,
sp_Process,
0,
CMPISPVERSION);
}
SP_STATUS NATableCacheEntriesStoredProcedure::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], "NATableCacheEntries");
error->optionalInteger[0] = 2;
return SP_FAIL;
}
//column as input parameter for ISP, specifiy 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
NATableCacheEntriesStoredProcedure::sp_NumOutputFields(Lng32 *numFields,
SP_COMPILE_HANDLE spCompileObj,
SP_HANDLE spObj,
SP_ERROR_STRUCT *error)
{
*numFields = 5;
return SP_SUCCESS;
}
// Specifies the columns of the NATableEntries table and their types
SP_STATUS NATableCacheEntriesStoredProcedure::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]), "Catalog_name VARCHAR(128) character set UTF8");
strcpy(&((format++)->COLUMN_DEF[0]), "Schema_name VARCHAR(128) character set UTF8");
strcpy(&((format++)->COLUMN_DEF[0]), "Object_name VARCHAR(128) character set UTF8");
strcpy(&((format++)->COLUMN_DEF[0]), "Entry_size INT");
return SP_SUCCESS;
}
// Copies information on the NATable cache by the interface provided in
// NATable.h and processes it
SP_STATUS NATableCacheEntriesStoredProcedure::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 )
{
if (action == SP_PROC_OPEN) {
NATableCacheEntriesISPIterator * it = new (GetCliGlobals()->exCollHeap())
NATableCacheEntriesISPIterator(inputData, eFunc, error,
GetCliGlobals()->currContext()->getCmpContextInfo(),
GetCliGlobals()->exCollHeap());
*spProcHandle = it;
return SP_SUCCESS;
}
if (action == SP_PROC_FETCH) {
NATableCacheEntriesISPIterator* it = (NATableCacheEntriesISPIterator *)(*spProcHandle);
if (!it) {
return SP_FAIL;
}
NATableEntryDetails details;
if(!it->getNext(details))
return SP_SUCCESS;
fFunc(0,outputData, sizeof(it->rowid()), &(it->rowid()), 0);
fFunc(1,outputData,(Lng32)strlen(details.catalog),(void*)(details.catalog),1);
fFunc(2,outputData,(Lng32)strlen(details.schema),(void*)(details.schema),1);
fFunc(3,outputData,(Lng32)strlen(details.object),(void*)(details.object),1);
fFunc(4,outputData,(Lng32)sizeof(details.size), (void*)(&details.size),0);
return SP_MOREDATA;
}
if (action == SP_PROC_CLOSE) {
if (*spProcHandle)
NADELETEBASIC((NATableCacheEntriesISPIterator *)(*spProcHandle), GetCliGlobals()->exCollHeap());
return SP_SUCCESS;
}
return SP_SUCCESS;
}
// Registers the NATableEntries function
void NATableCacheEntriesStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
regFunc("NATABLECACHEENTRIES",
sp_Compile,
sp_InputFormat,
0,
sp_NumOutputFields,
sp_OutputFormat,
sp_Process,
0,
CMPISPVERSION);
}
//-----------------------------------------------------------------------
// NATableCacheDeleteStoredProcedure is a class that contains functions used
// to delete the contents of the NATableCache virtual table. The delete
// function is implemented as an internal stored procedure.
//-----------------------------------------------------------------------
SP_STATUS NATableCacheDeleteStoredProcedure::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;
NATableDB * tableDB = NULL;
switch (action)
{
case SP_PROC_OPEN:
// No inputs to process
break;
case SP_PROC_FETCH:
tableDB = ActiveSchemaDB()->getNATableDB();
//clear out NATableCache
tableDB->setCachingOFF();
tableDB->setCachingON();
break;
case SP_PROC_CLOSE:
break;
}
return status;
}
void NATableCacheDeleteStoredProcedure::Initialize(SP_REGISTER_FUNCPTR regFunc)
{
regFunc("NATABLECACHEDELETE",
sp_Compile,
sp_InputFormat,
0,
sp_NumOutputFields,
sp_OutputFormat,
sp_Process,
0,
CMPISPVERSION);
}
NATableCacheStatsISPIterator::NATableCacheStatsISPIterator(
SP_ROW_DATA inputData, SP_EXTRACT_FUNCPTR eFunc,
SP_ERROR_STRUCT* error, const NAArray<CmpContextInfo*> & ctxs,
CollHeap * h)
: ISPIterator(ctxs, h)
{
initializeISPCaches(inputData, eFunc, error, ctxs,
contextName_, currCacheIndex_);
}
NABoolean NATableCacheStatsISPIterator::getNext(NATableCacheStats & stats)
{
//Only for remote tdm_arkcmp with 0 context
if(currCacheIndex_ == -1)
{
const char *cName = "ARKCMP";
ActiveSchemaDB()->getNATableDB()->getCacheStats(stats);
memset(stats.contextType, ' ', sizeof(stats.contextType));
memcpy(stats.contextType, cName, MINOF(sizeof(stats.contextType), strlen(cName)));
currCacheIndex_ = -2;
return TRUE;
}
//fetch QueryCaches of all CmpContexts with name equal to contextName_
if(currCacheIndex_ > -1 && currCacheIndex_ < ctxInfos_.entries())
{
if( !ctxInfos_[currCacheIndex_]->isSameClass(contextName_.data()) //current context name is not equal to contextName_
&& contextName_.compareTo("ALL", NAString::exact)!=0) //and contextName_ is not "ALL"
{// go to next context in ctxInfos_
currCacheIndex_++;
return getNext(stats);
}
ctxInfos_[currCacheIndex_]->getCmpContext()->getSchemaDB()->getNATableDB()->getCacheStats(stats);
const char *cName = ctxInfos_[currCacheIndex_++]->getName();
memset(stats.contextType, ' ', sizeof(stats.contextType));
memcpy(stats.contextType, cName, MINOF(sizeof(stats.contextType), strlen(cName)));
return TRUE;
}
//all entries of all caches are fetched, we are done!
return FALSE;
}
NATableCacheEntriesISPIterator::NATableCacheEntriesISPIterator(
SP_ROW_DATA inputData, SP_EXTRACT_FUNCPTR eFunc,
SP_ERROR_STRUCT* error, const NAArray<CmpContextInfo*> & ctxs,
CollHeap * h)
: ISPIterator(ctxs, h)
{
initializeISPCaches(inputData, eFunc, error, ctxs,
contextName_, currCacheIndex_);
counter_ = 0;
rowid_ = 0;
}
NABoolean NATableCacheEntriesISPIterator::getNext(NATableEntryDetails & details)
{
NATableDB* currNATableDB ;
//Only for remote tdm_arkcmp with 0 context
if(currCacheIndex_ == -1)
{
currNATableDB = ActiveSchemaDB()->getNATableDB();
if (currNATableDB->empty() || currNATableDB->end() == counter_)
return FALSE;
currNATableDB->getEntryDetails(counter_, details);
counter_++;
rowid_++;
return TRUE;
}
//fetch QueryCaches of all CmpContexts with name equal to contextName_
while(currCacheIndex_ > -1 && currCacheIndex_ < ctxInfos_.entries())
{
if( !ctxInfos_[currCacheIndex_]->isSameClass(contextName_.data()) //current context name is not equal to contextName_
&& contextName_.compareTo("ALL", NAString::exact)!=0) //and contextName_ is not "ALL"
{// go to next context in ctxInfos_
currCacheIndex_++;
return getNext(details);
}
currNATableDB = ctxInfos_[currCacheIndex_]->getCmpContext()->getSchemaDB()->getNATableDB();
if (currNATableDB->empty() || currNATableDB->end() == counter_)
{
currCacheIndex_++;
counter_ = 0;
continue;
}
currNATableDB->getEntryDetails(counter_, details);
counter_++;
rowid_++;
return TRUE;
}
//all entries of all caches are fetched, we are done!
return FALSE;
}