blob: 1484edbabd5320259366187a40ff5461f1034f7c [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 @@@
**************************************************************************/
//
// MODULE: sqlInterface.cpp
//
// PURPOSE: Implements the Srvr interface to SQL
//
/*Change Log
* Methods Changed: ClearDiags
*/
/*Change Log
* Methods Changed: Removed setOfCQD
*/
#include <platform_ndcs.h>
#include <sql.h>
#include <sqlext.h>
#include "SrvrCommon.h"
#include "SrvrKds.h"
#include "SqlInterface.h"
#include "CommonDiags.h"
#include "Debug.h"
#include "GlobalInformation.h"
#include <map> //MFC
#include <sys/stat.h> // MFC
#include <fcntl.h>
//Added for CQDs filter
#if defined(TAG64)
std::map<long,SRVR_STMT_HDL*> tempStmtIdMap;
#endif
#ifndef TODO // Linux port ToDo
extern long SQLMXStatement_int_FAILED(void);
extern long SQLMXStatement_SUCCESS_NO_INFO(void);
#endif
extern int SPJRS;
#define HANDLE_ERROR(error_code, warning_flag) \
{\
if (error_code != 0) \
{\
if (error_code < 0) \
CLI_DEBUG_RETURN_SQL(SQL_ERROR); \
warning_flag = TRUE; \
}\
}
#define THREAD_RETURN(pSrvrStmt, return_code) \
{ \
if (NULL != pSrvrStmt) \
pSrvrStmt->threadReturnCode = return_code; \
if (NULL != pSrvrStmt && pSrvrStmt->threadReturnCode!=SQL_SUCCESS) \
pSrvrStmt->processThreadReturnCode(); \
CLI_DEBUG_RETURN_SQL(return_code); \
}
#define HANDLE_THREAD_ERROR(error_code, warning_flag, pSrvrStmt) \
{\
if (error_code != 0) \
{\
if (error_code < 0) \
THREAD_RETURN(pSrvrStmt,SQL_ERROR); \
warning_flag = TRUE; \
}\
}
long AdjustCharLength(SRVR_STMT_HDL::DESC_TYPE descType, long SQLCharset, long Length)
{
FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE,"AdjustCharLength",("descType=%s, SQLCharset=%s, Length=%ld",
CliDebugDescTypeStr(descType),
getCharsetEncoding(SQLCharset),
Length));
long ret_length = Length;
switch (SQLCharset)
{
// SBB: The doubling for Kanji and KSC5601 needs to be removed
// upon incorporation of MXCMP Case 10-040224-9870 into next sut (UCS2 also ?)
case SQLCHARSETCODE_KANJI:
case SQLCHARSETCODE_KSC5601:
case SQLCHARSETCODE_UCS2:
ret_length *= 2;
break;
}
FUNCTION_RETURN_NUMERIC(ret_length,(NULL));
}
long MapSQLCharsetToJDBC(long SQLCharset)
{
FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_DATA|DEBUG_LEVEL_UNICODE, "MapSQLCharsetToODBC",("SQLCharset=%s",
getCharsetEncoding(SQLCharset)));
long rc = SQLCHARSETCODE_ISO88591;
//if locale is Japanses switch to SJIS (MBCS)
if (PRIMARYLANGID(LANGIDFROMLCID(srvrGlobal->clientLCID)) == LANG_JAPANESE)
rc = SQLCHARSETCODE_SJIS;
// Unicode support
switch (SQLCharset)
{
case SQLCHARSETCODE_ISO88591:
rc = SQLCHARSETCODE_ISO88591;
break;
case SQLCHARSETCODE_KANJI:
rc = SQLCHARSETCODE_KANJI;
break;
case SQLCHARSETCODE_KSC5601:
rc = SQLCHARSETCODE_KSC5601;
break;
case SQLCHARSETCODE_SJIS:
rc = SQLCHARSETCODE_SJIS;
break;
case SQLCHARSETCODE_UCS2:
rc = SQLCHARSETCODE_UCS2;
break;
}
FUNCTION_RETURN_NUMERIC(rc,("%s",getCharsetEncoding(rc)));
}
// * ***********************************************************************************
// *
// * This routine is only called by BuildSQLDesc, which is in this same file
// *
// * ***********************************************************************************
SQLRETURN GetJDBCValues( SQLItemDesc_def *SQLItemDesc,
long &totalMemLen,
char *ColHeading)
{
FUNCTION_ENTRY("GetJDBCValues",
("DataType=%s, DateTimeCode=%ld, Length=%ld, Precision=%ld, ODBCDataType=%ld, ODBCPrecision=%ld, SignType=%ld, Nullable=%ld, totalMemLen=%ld, SQLCharset=%ld, ODBCCharset=%ld, IntLeadPrec=%ld",
CliDebugSqlTypeCode(SQLItemDesc->dataType),
SQLItemDesc->datetimeCode,
SQLItemDesc->maxLen,
SQLItemDesc->precision,
SQLItemDesc->ODBCDataType,
SQLItemDesc->ODBCPrecision,
SQLItemDesc->signType,
SQLItemDesc->nullInfo,
totalMemLen,
SQLItemDesc->SQLCharset,
SQLItemDesc->ODBCCharset,
SQLItemDesc->intLeadPrec));
SQLItemDesc->ODBCCharset = SQLCHARSETCODE_ISO88591;
long memAlignOffset;
//long allocSize; 64 bit change
int allocSize;
getMemoryAllocInfo( SQLItemDesc->dataType,
SQLItemDesc->SQLCharset,
SQLItemDesc->maxLen,
SQLItemDesc->vc_ind_length,
totalMemLen,
&memAlignOffset,
&allocSize,
NULL);
switch (SQLItemDesc->dataType)
{
case SQLTYPECODE_CHAR:
SQLItemDesc->ODBCPrecision = SQLItemDesc->maxLen;
SQLItemDesc->ODBCDataType = SQL_CHAR;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCCharset = MapSQLCharsetToJDBC(SQLItemDesc->SQLCharset);
break;
case SQLTYPECODE_VARCHAR:
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
SQLItemDesc->ODBCPrecision = SQLItemDesc->maxLen;
SQLItemDesc->ODBCDataType = SQL_VARCHAR;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCCharset = MapSQLCharsetToJDBC(SQLItemDesc->SQLCharset);
break;
case SQLTYPECODE_VARCHAR_LONG:
SQLItemDesc->ODBCPrecision = SQLItemDesc->maxLen;
SQLItemDesc->ODBCDataType = SQL_LONGVARCHAR;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCCharset = MapSQLCharsetToJDBC(SQLItemDesc->SQLCharset);
break;
case SQLTYPECODE_SMALLINT:
SQLItemDesc->ODBCPrecision = 5;
SQLItemDesc->ODBCDataType = SQL_SMALLINT;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_SMALLINT_UNSIGNED:
SQLItemDesc->ODBCPrecision = 5;
SQLItemDesc->ODBCDataType = SQL_SMALLINT;
SQLItemDesc->signType = FALSE;
break;
case SQLTYPECODE_INTEGER:
SQLItemDesc->ODBCPrecision = 10;
SQLItemDesc->ODBCDataType = SQL_INTEGER;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_INTEGER_UNSIGNED:
SQLItemDesc->ODBCPrecision = 10;
SQLItemDesc->ODBCDataType = SQL_INTEGER;
SQLItemDesc->signType = FALSE;
break;
case SQLTYPECODE_LARGEINT:
SQLItemDesc->ODBCDataType = SQL_BIGINT; // The LARGEINT is mapped to Types.BIGINT unless CLOB or BLOB
SQLItemDesc->ODBCPrecision = 19; // Make sure that the precision is set correctly
if (ColHeading[0] != '\0')
{
if (strstr(ColHeading, CLOB_HEADING) != NULL)
SQLItemDesc->ODBCDataType = TYPE_CLOB;
else if (strstr(ColHeading, BLOB_HEADING) != NULL)
SQLItemDesc->ODBCDataType = TYPE_BLOB;
}
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_IEEE_REAL:
case SQLTYPECODE_TDM_REAL:
SQLItemDesc->ODBCDataType = SQL_REAL;
SQLItemDesc->ODBCPrecision = 7;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_IEEE_DOUBLE:
case SQLTYPECODE_TDM_DOUBLE:
SQLItemDesc->ODBCDataType = SQL_DOUBLE;
SQLItemDesc->ODBCPrecision = 15;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_DATETIME:
switch (SQLItemDesc->datetimeCode)
{
case SQLDTCODE_DATE:
SQLItemDesc->ODBCDataType = SQL_TYPE_DATE;
break;
case SQLDTCODE_TIME:
SQLItemDesc->ODBCDataType = SQL_TYPE_TIME;
break;
case SQLDTCODE_TIMESTAMP:
SQLItemDesc->ODBCDataType = SQL_TYPE_TIMESTAMP;
break;
default:
SQLItemDesc->ODBCDataType = SQL_TYPE_TIMESTAMP;
break;
}
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCPrecision = SQLItemDesc->precision;
getMemoryAllocInfo( SQLItemDesc->dataType,
SQLItemDesc->SQLCharset,
SQLItemDesc->maxLen,
SQLItemDesc->vc_ind_length,
totalMemLen,
&memAlignOffset,
&allocSize,
NULL);
break;
case SQLTYPECODE_NUMERIC:
SQLItemDesc->ODBCDataType = SQL_NUMERIC;
SQLItemDesc->ODBCPrecision = SQLItemDesc->precision;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_NUMERIC_UNSIGNED:
SQLItemDesc->ODBCDataType = SQL_NUMERIC;
SQLItemDesc->ODBCPrecision = SQLItemDesc->precision;
SQLItemDesc->signType = FALSE;
break;
case SQLTYPECODE_DECIMAL_UNSIGNED:
SQLItemDesc->ODBCPrecision = SQLItemDesc->maxLen;
SQLItemDesc->ODBCDataType = SQL_DECIMAL;
SQLItemDesc->signType = FALSE;
break;
case SQLTYPECODE_DECIMAL:
SQLItemDesc->ODBCPrecision = SQLItemDesc->maxLen;
SQLItemDesc->ODBCDataType = SQL_DECIMAL;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: // Tandem extension
SQLItemDesc->ODBCDataType = SQL_DOUBLE; // Since there is no corresponding ODBC DataType, Map it as a double
SQLItemDesc->ODBCPrecision = 15;
SQLItemDesc->signType = FALSE;
break;
case SQLTYPECODE_DECIMAL_LARGE: // Tandem extension
SQLItemDesc->ODBCDataType = SQL_DOUBLE; // Since there is no corresponding ODBC DataType, Map it as a double
SQLItemDesc->ODBCPrecision = 15;
SQLItemDesc->signType = TRUE;
break;
case SQLTYPECODE_INTERVAL: // Interval will be sent in ANSIVARCHAR format
SQLItemDesc->ODBCDataType = SQL_INTERVAL;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCPrecision = SQLItemDesc->precision;
// Calculate the length based on Precision and IntLeadPrec
// The max. length is for Day to Fraction(6)
// Day = IntLeadPrec + 1 ( 1 for Blank space)
// Hour = 3 ( 2+1)
// Minute = 3 (2+1)
// Seconds = 3 (2+1)
// Fraction = Precision
/*SQLItemDesc->maxLen = SQLItemDesc->intLeadPrec + 1 + 3 + 3 + 3 + SQLItemDesc->precision; //Anitha -- 10-060510-6400 */
/* Soln No: 10-060510-6400
* Desc:String overflow no longer occurs during evaluation
*/
SQLItemDesc->maxLen = SQLItemDesc->intLeadPrec + 1 + 1 + 3 + 3 + 3 + SQLItemDesc->precision;
getMemoryAllocInfo( SQLItemDesc->dataType,
SQLItemDesc->SQLCharset,
SQLItemDesc->maxLen,
SQLItemDesc->vc_ind_length,
totalMemLen,
&memAlignOffset,
&allocSize,
NULL);
break;
case SQLTYPECODE_CLOB:
SQLItemDesc->ODBCDataType = TYPE_CLOB;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCPrecision = 0;
break;
case SQLTYPECODE_BLOB:
SQLItemDesc->ODBCDataType = TYPE_BLOB;
SQLItemDesc->signType = FALSE;
SQLItemDesc->ODBCPrecision = 0;
break;
case SQLTYPECODE_BIT:
case SQLTYPECODE_BITVAR:
case SQLTYPECODE_IEEE_FLOAT:
case SQLTYPECODE_FLOAT:
// SQLTYPECODE_FLOAT is also considered an error, Since Trafodion will never
// return SQLTYPECODE_FLOAT. It returns either SQLTYPECODE_IEEE_REAL or SQLTYPECODE_IEEE_DOUBLE
// depending upon the precision for FLOAT fields
case SQLTYPECODE_BPINT_UNSIGNED:
default:
SQLItemDesc->ODBCDataType = SQL_TYPE_NULL;
SQLItemDesc->ODBCPrecision = 0;
SQLItemDesc->signType = FALSE;
break;
}
totalMemLen += memAlignOffset + allocSize;
if (SQLItemDesc->nullInfo)
{
// 2-byte boundary
totalMemLen = ((totalMemLen + 2 - 1) >> 1) << 1;
totalMemLen += sizeof(short) ;
}
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("Result - ODBCPrecision=%ld ODBCDataType=%ld SignType=%ld Length=%ld totalMemLen=%ld ODBCCharset=%ld",
SQLItemDesc->ODBCPrecision,
SQLItemDesc->ODBCDataType,
SQLItemDesc->signType,
SQLItemDesc->maxLen,
totalMemLen,
SQLItemDesc->ODBCCharset));
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN SET_DATA_PTR(SRVR_STMT_HDL *pSrvrStmt, SRVR_STMT_HDL::DESC_TYPE descType)
{
FUNCTION_ENTRY("SET_DATA_PTR", ("pSrvrStmt=0x%08x, descType=%s",
pSrvrStmt,
CliDebugDescTypeStr(descType)));
SQLDESC_ID *pDesc = pSrvrStmt->getDesc(descType);
SQLItemDescList_def *SQLDesc = pSrvrStmt->getDescList(descType);
long *totalMemLen = pSrvrStmt->getDescBufferLenPtr(descType);
BYTE **varBuffer = pSrvrStmt->getDescVarBufferPtr(descType);
int numEntries = pSrvrStmt->getDescEntryCount(descType);
int rowsetSize = pSrvrStmt->getRowsetSize(descType);
struct SQLCLI_QUAD_FIELDS *quadField = pSrvrStmt->getQuadField(descType); // Linux port - ToDo SQLCLI_QUAD_FIELDS struct is different on SQ
SRVR_DESC_HDL *implDesc = pSrvrStmt->getImplDesc(descType);
SQLItemDesc_def *SQLItemDesc;
long memOffset = 0, memAlignOffset, varLayout;
int allocSize; //64 change
BYTE *VarPtr;
BYTE *IndPtr;
BYTE *memPtr;
unsigned long i;
int retcode;
BOOL sqlWarning = FALSE;
long buffer_multiplier;
long quadOffset = pSrvrStmt->getQuadEntryCount(descType) - numEntries;
// Adjust totalMemLen to word boundary
*totalMemLen = ((*totalMemLen + 8 - 1) >> 3) << 3;
if (rowsetSize) buffer_multiplier = rowsetSize;
else buffer_multiplier = 1;
MEMORY_DELETE_ARRAY(*varBuffer);
DEBUG_ASSERT(*totalMemLen!=0,("totalMemLen==0"));
MEMORY_ALLOC_ARRAY(*varBuffer,BYTE,(*totalMemLen) * buffer_multiplier);
#ifdef _DEBUG
memset(*varBuffer,0,(*totalMemLen) * buffer_multiplier);
#endif
memPtr = *varBuffer ;
memOffset = 0;
for (i = 0 ; i < SQLDesc->_length ; i++)
{
SQLItemDesc = (SQLItemDesc_def *) SQLDesc->_buffer + i;
getMemoryAllocInfo(SQLItemDesc->dataType, SQLItemDesc->SQLCharset, SQLItemDesc->maxLen, SQLItemDesc->vc_ind_length, memOffset,
&memAlignOffset, &allocSize, &varLayout);
if ((SQLItemDesc->dataType==SQLTYPECODE_INTERVAL) ||
(SQLItemDesc->dataType==SQLTYPECODE_DATETIME))
{
retcode = CLI_SetDescItem(pDesc,
i+1,
SQLDESC_TYPE,
(long)SQLTYPECODE_VARCHAR_WITH_LENGTH,
NULL);
HANDLE_ERROR(retcode, sqlWarning);
retcode = CLI_SetDescItem(pDesc,
i+1,
SQLDESC_LENGTH,
SQLItemDesc->maxLen,
NULL);
HANDLE_ERROR(retcode, sqlWarning);
retcode = CLI_SetDescItem(pDesc,
i+1,
SQLDESC_VC_IND_LENGTH,
(long)sizeof(short),
NULL);
HANDLE_ERROR(retcode, sqlWarning);
}
VarPtr = memPtr + memOffset + memAlignOffset;
DEBUG_OUT(DEBUG_LEVEL_DATA,("Desc %d dataType=%s, VarPtr=0x%08x, memAlignOffset=%ld",
i,
CliDebugSqlTypeCode(SQLItemDesc->dataType),
VarPtr,
memAlignOffset));
memOffset += memAlignOffset + allocSize * buffer_multiplier;
if (SQLItemDesc->nullInfo)
{
memAlignOffset = (((memOffset + 2 - 1) >> 1) << 1) - memOffset;
IndPtr = memPtr + memOffset + memAlignOffset;
DEBUG_OUT(DEBUG_LEVEL_DATA,("IndPtr=0x%08x, memAlignOffset=%ld",
IndPtr,
memAlignOffset));
memOffset += memAlignOffset + sizeof(short) * buffer_multiplier;
} else IndPtr = NULL;
if (rowsetSize==0)
{
retcode = CLI_SetDescItem(pDesc,
i+1,
SQLDESC_VAR_PTR,
(long)VarPtr,
NULL);
HANDLE_ERROR(retcode, sqlWarning);
retcode = CLI_SetDescItem(pDesc,
i+1,
SQLDESC_IND_PTR,
(long)IndPtr,
NULL);
HANDLE_ERROR(retcode, sqlWarning);
} else {
quadField[i+quadOffset].var_layout = varLayout;
quadField[i+quadOffset].var_ptr = (BYTE *) VarPtr;
quadField[i+quadOffset].ind_ptr = (BYTE *) IndPtr;
if (IndPtr) quadField[i+quadOffset].ind_layout = sizeof(short);
else quadField[i+quadOffset].ind_layout = 0;
}
implDesc[i].varPtr = VarPtr;
implDesc[i].indPtr = IndPtr;
if (memOffset > (*totalMemLen * buffer_multiplier))
{
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("memOffset (%ld) > totalMemLen (%ld) * buffer_multiplier(%ld)",
memOffset,
*totalMemLen,
buffer_multiplier));
CLI_DEBUG_RETURN_SQL(PROGRAM_ERROR);
}
}
if (rowsetSize)
{
// Must set rowset entry var_layout to zero for set
if (descType==SRVR_STMT_HDL::Input) quadField[0].var_layout = 0;
// Setup descriptors for rowset processing
int rowset_status;
retcode = CLI_SETROWSETDESCPOINTERS(
pDesc,
rowsetSize,
&rowset_status,
1L,
numEntries,
quadField);
HANDLE_ERROR(retcode, sqlWarning);
}
if (sqlWarning) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN AllocAssignValueBuffer(SQLItemDescList_def *SQLDesc, SQLValueList_def *SQLValueList,
long totalMemLen, long maxRowCount, BYTE *&VarBuffer)
{
FUNCTION_ENTRY("AllocAssignValueBuffer",
("SQLDesc=0x%08x, SQLValueList=0x%08x, totalMemLen=%ld, maxRowCount=%ld, VarBuffer=0x%08x",
SQLDesc,
SQLValueList,
totalMemLen,
maxRowCount,
VarBuffer));
SQLItemDesc_def *SQLItemDesc;
SQLValue_def *SQLValue;
long memOffset = 0;
BYTE *VarPtr;
BYTE *IndPtr;
BYTE *memPtr;
unsigned long curValueCount, curDescCount;
long curRowCount;
long numValues;
//long AllocLength; 64 change
int AllocLength;
long totalRowMemLen;
// Allocate SQLValue Array
MEMORY_DELETE_ARRAY(SQLValueList->_buffer);
MEMORY_DELETE_ARRAY(VarBuffer);
numValues = SQLDesc->_length * maxRowCount;
if (numValues == 0)
{
SQLValueList->_buffer = NULL;
SQLValueList->_length = 0;
VarBuffer = NULL;
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
else
{
MEMORY_ALLOC_ARRAY(SQLValueList->_buffer, SQLValue_def, numValues);
SQLValueList->_length = 0;
}
// Allocate the Value Buffer
totalRowMemLen = totalMemLen * maxRowCount;
MEMORY_ALLOC_ARRAY(VarBuffer, BYTE, totalRowMemLen);
memPtr = VarBuffer ;
memOffset = 0;
for (curRowCount = 0, curValueCount = 0 ; curRowCount < maxRowCount ; curRowCount++)
{
for (curDescCount = 0 ; curDescCount < SQLDesc->_length ; curDescCount++, curValueCount++)
{
long memAlignOffset;
SQLItemDesc = (SQLItemDesc_def *)SQLDesc->_buffer + curDescCount;
SQLValue = (SQLValue_def *)SQLValueList->_buffer + curValueCount;
getMemoryAllocInfo(SQLItemDesc->dataType, SQLItemDesc->SQLCharset, SQLItemDesc->maxLen, SQLItemDesc->vc_ind_length, memOffset,
&memAlignOffset, &AllocLength, NULL);
VarPtr = memPtr + memOffset + memAlignOffset;
memOffset += memAlignOffset + AllocLength;
if (SQLItemDesc->nullInfo)
{
memOffset = ((memOffset + 2 - 1) >> 1) << 1;
IndPtr = memPtr + memOffset;
memOffset += sizeof(short) ;
}
else
IndPtr = NULL;
SQLValue->dataValue._buffer = (unsigned char *) VarPtr;
// Ignore the indPtr, since it is declared as short already in SQLValue_def
SQLValue->dataType = SQLItemDesc->dataType;
SQLValue->dataValue._length = AllocLength;
SQLValue->dataCharset = SQLItemDesc->ODBCCharset;
DEBUG_OUT(DEBUG_LEVEL_DATA,("SQLValue: dataValue._buffer=0x%08x, dataType=%s, dataValue._length=%ld, dataCharset=%s",
SQLValue->dataValue._buffer,
CliDebugSqlTypeCode(SQLValue->dataType),
SQLValue->dataValue._length,
getCharsetEncoding(SQLValue->dataCharset)));
if (memOffset > totalRowMemLen)
{
//TFDS
/* if (srvrEventLogger != NULL)
{
srvrEventLogger->SendEventMsg(MSG_PROGRAMMING_ERROR, EVENTLOG_ERROR_TYPE,
srvrGlobal->nskProcessInfo.processId, ODBCMX_SERVER, srvrGlobal->srvrObjRef,
1, "memOffset > totalMemLen in AllocAssignValueBuffer");
}
*/
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("memOffset > totalRowMemLen"));
CLI_DEBUG_RETURN_SQL(PROGRAM_ERROR);
}
}
// Align it to next word boundary for the next row
memOffset = ((memOffset + 8 - 1) >> 3) << 3;
}
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN CopyValueList(SQLValueList_def *outValueList, const SQLValueList_def *inValueList)
{
FUNCTION_ENTRY("CopyValueList",
("outValueList=0x%08x, inValueList=0x%08x",
outValueList,
inValueList));
SQLValue_def *inValue;
SQLValue_def *outValue;
unsigned long i;
for (i = 0; i < inValueList->_length ; i++)
{
inValue = (SQLValue_def *)inValueList->_buffer + i;
outValue = (SQLValue_def *)outValueList->_buffer + i;
if (inValue->dataType != outValue->dataType)
{
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("inValue->dataType != outValue->dataType"));
CLI_DEBUG_RETURN_SQL(PROGRAM_ERROR);
}
outValue->dataInd = inValue->dataInd;
if (inValue->dataInd == 0)
{
if (inValue->dataValue._length != outValue->dataValue._length)
{
// TFDS
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("inValue->dataValue._length != outValue->dataValue._length"));
CLI_DEBUG_RETURN_SQL(PROGRAM_ERROR);
}
memcpy(outValue->dataValue._buffer, inValue->dataValue._buffer, outValue->dataValue._length);
}
else
{
outValue->dataValue._length = 0;
}
}
outValueList->_length = inValueList->_length;
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN BuildSQLDesc(SRVR_STMT_HDL*pSrvrStmt, SRVR_STMT_HDL::DESC_TYPE descType)
{
FUNCTION_ENTRY("BuildSQLDesc", ("pSrvrStmt=0x%08x, pSrvrStmt->stmtName = %s, SQL Statement = %s, descType=%s",
pSrvrStmt,
pSrvrStmt->stmtName,
pSrvrStmt->sqlString.dataValue._buffer,
CliDebugDescTypeStr(descType)));
long retcode = SQL_SUCCESS;
short i;
short j;
short k;
BOOL sqlWarning = FALSE;
long *totalMemLen = pSrvrStmt->getDescBufferLenPtr(descType);
long numEntries = pSrvrStmt->getDescEntryCount(descType);
SQLDESC_ID *pDesc = pSrvrStmt->getDesc(descType);
SQLItemDescList_def *SQLDesc = pSrvrStmt->getDescList(descType);
SQLItemDesc_def *SQLItemDesc = (SQLItemDesc_def *)SQLDesc->_buffer + SQLDesc->_length;
SRVR_DESC_HDL *implDesc = pSrvrStmt->allocImplDesc(descType);
// The following routine is hard coded for at least 15 items, so make sure it does not change
DEBUG_ASSERT(NO_OF_DESC_ITEMS>=15,("NO_OF_DESC_ITEMS(%d) is less than 15",NO_OF_DESC_ITEMS));
*totalMemLen = 0;
for (i = 0; i < numEntries; i++) {
SQLItemDesc = (SQLItemDesc_def *)SQLDesc->_buffer + SQLDesc->_length;
// Initialize the desc entry in SQLDESC_ITEM struct
for (j = 0; j < NO_OF_DESC_ITEMS ; j++) {
gDescItems[j].entry = i+1;
}
gDescItems[10].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[11].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[12].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[13].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[14].num_val_or_len = MAX_ANSI_NAME_LEN+1;
retcode = CLI_GetDescItems2(pDesc,
NO_OF_DESC_ITEMS,
(SQLDESC_ITEM *)&gDescItems);
HANDLE_ERROR(retcode, sqlWarning);
SQLItemDesc->dataType = gDescItems[0].num_val_or_len;
SQLItemDesc->maxLen = gDescItems[1].num_val_or_len;
SQLItemDesc->precision = (short)gDescItems[2].num_val_or_len;
SQLItemDesc->scale = (short)gDescItems[3].num_val_or_len;
SQLItemDesc->nullInfo = (BOOL)gDescItems[4].num_val_or_len;
SQLItemDesc->paramMode = gDescItems[5].num_val_or_len;
SQLItemDesc->intLeadPrec = gDescItems[6].num_val_or_len;
SQLItemDesc->datetimeCode = gDescItems[7].num_val_or_len;
SQLItemDesc->SQLCharset = gDescItems[8].num_val_or_len;
SQLItemDesc->fsDataType = gDescItems[9].num_val_or_len;
for (k = 10; k < 15; k++) {
gDescItems[k].string_val[gDescItems[k].num_val_or_len] = '\0';
}
SQLItemDesc->vc_ind_length = gDescItems[15].num_val_or_len;
SQLItemDesc->maxLen = AdjustCharLength(descType, SQLItemDesc->SQLCharset, SQLItemDesc->maxLen);
GetJDBCValues( SQLItemDesc, // Input
*totalMemLen,
gDescItems[14].string_val);
implDesc[i].charSet = SQLItemDesc->SQLCharset;
implDesc[i].dataType = SQLItemDesc->dataType;
implDesc[i].length = SQLItemDesc->maxLen;
implDesc[i].precision = SQLItemDesc->ODBCPrecision;
implDesc[i].scale = SQLItemDesc->scale;
implDesc[i].sqlDatetimeCode = SQLItemDesc->datetimeCode;
implDesc[i].FSDataType = SQLItemDesc->fsDataType;
implDesc[i].paramMode = SQLItemDesc->paramMode;
implDesc[i].vc_ind_length = SQLItemDesc->vc_ind_length;
SQLItemDesc->version = 0;
strcpy(SQLItemDesc->catalogNm, gDescItems[10].string_val);
strcpy(SQLItemDesc->schemaNm, gDescItems[11].string_val);
strcpy(SQLItemDesc->tableNm, gDescItems[12].string_val);
strcpy(SQLItemDesc->colNm, gDescItems[13].string_val);
strcpy(SQLItemDesc->colLabel, gDescItems[14].string_val);
SQLDesc->_length++;
}
retcode = SET_DATA_PTR(pSrvrStmt, descType);
HANDLE_ERROR(retcode, sqlWarning);
if (sqlWarning) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
/* ***********************************************************************************************
* FUNCTION: RSgetRSmax
*
* DESCRIPTION:
* This routine will call SQL_EXEC_GetStmtAttr() to get the maximum number
* of RS's the stmt can rtn. {Note: This value corrsponds to the value of
* "DYNAMIC RESULT SETS" specified during the CREATE PROCEDURE registration.
*
* ARGUMENTS:
* INPUT/OUTPUT:
* pSrvrStmt - A C++ object that contains information about the
* statement being used.
* OUTPUT:
* pSrvrStmt->RSMax - Max number of SPJRS allowed for this stmt.
* Returns:
* SQL_SUCCESS or
* SQL failures (see CLI_GetStmtAttr() retcode failures).
*********************************************************************************************** */
SQLRETURN RSgetRSmax(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("RSgetRSmax",
("pSrvrStmt=0x%08x",pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
BOOL sqlWarning = FALSE;
SQLSTMT_ID *pStmt = &pSrvrStmt->stmt;
int retcode = SQL_SUCCESS;
int max_num_rs = 0;
pSrvrStmt->RSMax = 0;
// Get RSMax (max SPJ Result Sets that can be returned for this stmt)
retcode = CLI_GetStmtAttr((SQLSTMT_ID *)pStmt, // (IN) SQL statement ID
SQL_ATTR_MAX_RESULT_SETS, // (IN) Request query statement attribute (max RS per stmt)
&max_num_rs, // (OUT) Place to store Max resultsets
NULL, // (OUT) Optional string
0, // (IN) Max size of optional string buffer
NULL ); // (IN) Length of item
// Handle CLI errors
if (retcode != SQL_SUCCESS)
{
// CLI_ClearDiagnostics(NULL);
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,
("CLI_GetStmtAttr(SQL_ATTR_MAX_RESULT_SETS) FAILED : retcode=%s",
CliDebugSqlError(retcode)));
CLI_DEBUG_RETURN_SQL(retcode);
}
pSrvrStmt->RSMax = max_num_rs;
DEBUG_ASSERT((pSrvrStmt->RSMax>0)&&(pSrvrStmt->RSMax<256),
("Max ResultSets(%ld) is out of range", max_num_rs));
// Point to first RS if greater than 0
if(pSrvrStmt->RSMax > 0)
pSrvrStmt->RSIndex = 1;
// Also should fail if value is less than one or greater than 255
DEBUG_OUT(DEBUG_LEVEL_STMT,("RSMax: %d RSIndex: %d isSPJRS: %d",
pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS));
CLI_DEBUG_RETURN_SQL(retcode);
}
/* ***********************************************************************************************
* FUNCTION: ReadRow
*
* DESCRIPTION: Called during int or a fetch.
* This routine will retrieve information from a descriptor entry.
* Length of retrieved items is returned in totalRows.
* Copy items to the SQL output value list
* via the kdsCopyToSQLValueSeq() routine.
*
* ARGUMENTS:
* INPUT/OUTPUT:
* pSrvrStmt - A C++ object that contains information about the statement being
* used.
* OUTPUT:
* totalRows - running total of rows read.
* rowsRead - rows read by last fetch
* Returns:
* SQL_SUCCESS or
* SQL failures (see CLI_GetDescItem() for retcode failures).
*********************************************************************************************** */
static SQLRETURN ReadRow(SRVR_STMT_HDL *pSrvrStmt,
int *totalRows, long *rowsRead)
{
FUNCTION_ENTRY("ReadRow",
("pSrvrStmt=0x%08x, totalRows=%ld, rowsRead=0x%08x",
pSrvrStmt,
*totalRows,
rowsRead));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode = SQL_SUCCESS; // assume success
//long allocLength; // allocation length 64 change
int allocLength; // allocation length
long charSet;
long columnCount = 0; // total number of columns
long curColumnNo = 0; // current column number
long dataLength;
long dataType;
short *indPtr; // Linux port - ToDo: this is declared as Int64 in SQ ???
short indValue;
BYTE *pBytes;
SQLDESC_ID *pOutputDesc;
SQLValueList_def *pOutputValueList;
BOOL sqlWarning = FALSE;
SRVR_DESC_HDL *IRD;
pOutputValueList = &pSrvrStmt->outputValueList;
pOutputDesc = &pSrvrStmt->outputDesc;
columnCount = pSrvrStmt->columnCount;
IRD = pSrvrStmt->IRD;
DEBUG_OUT(DEBUG_LEVEL_DATA,("pOutputValueList=0x%08x",
pOutputValueList));
// Assert that outputValueList buffer is not null, if null assert
DEBUG_ASSERT(pOutputValueList->_buffer!=NULL,("pOutputValueList->_buffer==NULL"));
// This check may be needed; otherwise, a SIG11 occurs from calling kdsCopyToSqlValueSeq()
// if the buffer is null. This has been found to occur when JVM memory is exhausted.
// if (pOutputValueList->_buffer == NULL) CLI_DEBUG_RETURN_SQL(SQL_NULL_DATA);
if (pSrvrStmt->fetchRowsetSize > 0)
{
// This is a Rowset fetch
int item_count = 0;
long row;
retcode = CLI_GetDescItem(pOutputDesc,
1L,
SQLDESC_ROWSET_NUM_PROCESSED,
&item_count,
NULL,0,NULL,0);
if (retcode != SQL_SUCCESS) CLI_DEBUG_RETURN_SQL(retcode);
// Assert that colCnt equals fetch QuadEntries, if not equal assert
DEBUG_ASSERT(columnCount==pSrvrStmt->fetchQuadEntries,
("columnCount(%ld)!=pSrvrStmt->fetchQuadEntries(%ld)",
columnCount,
pSrvrStmt->fetchQuadEntries));
DEBUG_OUT(DEBUG_LEVEL_DATA,("Rowset rowsRead=%ld",item_count));
if (rowsRead) *rowsRead = item_count;
if (item_count==0) CLI_DEBUG_RETURN_SQL(retcode);
for (row=0; row<item_count; row++)
{
for (curColumnNo = 0; curColumnNo < columnCount; curColumnNo++)
{
dataType = IRD[curColumnNo].dataType;
indPtr = (short *) pSrvrStmt->fetchQuadField[curColumnNo].ind_ptr;
if ((indPtr == NULL) || (indPtr[row] != -1)) indValue = 0;
else indValue = -1;
charSet = IRD[curColumnNo].charSet;
dataLength = IRD[curColumnNo].length;
getMemoryAllocInfo(dataType,
charSet,
dataLength,
IRD[curColumnNo].vc_ind_length,
0,
NULL,
&allocLength,
NULL);
pBytes = (BYTE *)(pSrvrStmt->fetchQuadField[curColumnNo].var_ptr);
if (charSet != SQLCHARSETCODE_ISO88591 && dataType == SQLTYPECODE_VARCHAR_WITH_LENGTH)
pBytes += row * (allocLength - 1);
else
pBytes += row * allocLength;
DEBUG_OUT(DEBUG_LEVEL_DATA,("RowSet Row %ld Column %ld pBytes=0x%08x item_count=%ld",
row,
curColumnNo,
pBytes,
item_count));
MEMORY_DUMP(DEBUG_LEVEL_DATA,pBytes,allocLength);
kdsCopyToSQLValueSeq(pOutputValueList,
dataType,
indValue,
pBytes,
allocLength,
charSet);
}
}
*totalRows += item_count;
}
else
{
// This is not a Rowset fetch
*totalRows += 1;
if (rowsRead) *rowsRead = 1;
for (curColumnNo = 0; curColumnNo < columnCount; curColumnNo++)
{
dataType = IRD[curColumnNo].dataType;
indPtr = (short *) IRD[curColumnNo].indPtr;
if ((indPtr == NULL) || (indPtr[0] != -1)) indValue = 0;
else indValue = -1;
charSet = IRD[curColumnNo].charSet;
pBytes = (BYTE *)(IRD[curColumnNo].varPtr);
dataLength = IRD[curColumnNo].length;
// Compute memory allocation requirements for descriptor
getMemoryAllocInfo(dataType,
charSet,
dataLength,
IRD[curColumnNo].vc_ind_length,
0,
NULL,
&allocLength,
NULL);
DEBUG_OUT(DEBUG_LEVEL_DATA,("totalRows %ld curColumnNo %ld",*totalRows,curColumnNo));
MEMORY_DUMP(DEBUG_LEVEL_DATA,pBytes,allocLength);
kdsCopyToSQLValueSeq(pOutputValueList, dataType, indValue, pBytes, allocLength, charSet);
}
}
DEBUG_OUT(DEBUG_LEVEL_DATA,("totalRows=%ld curColumnNo=%ld pOutputValueList=0x%08x",
*totalRows, curColumnNo, pOutputValueList));
CLI_DEBUG_RETURN_SQL((SQLRETURN)retcode);
}
/* ***********************************************************************************************
* FUNCTION: EXECUTE
*
* DESCRIPTION: Evaluate input parameters and execute an SQL statement, make diagnostic
* information available and, if results are present, position the implicit cursor
* before the first row of the result set.
*
* For V2.1+ SQL their are four classes of Trafodion query stmt types:
* 1) Unique_selects (1 row) call ClearExecFetchClose() SQL/CLI (w/ a valid outputDesc).
* 2) Non_unique selects (multiple rows) statement types call Trafodion CLI Exec (not chg'd from V2.0 SQL).
* 3) UID (unique and non_unique) stmt types call SQL/CLI ClearExecFetchClose() (w/ a NULL outputDesc).
* 4) All other statements (SQL_CONTROL, SQL_SET_TRANSACTION, SQL_SET_CATALOG, SQL_SET_SCHEMA)
* call SQL/CLI ClearExecFetchClose() (w/ a NULL outputDesc).
*
*
* ARGUMENTS:
* INPUT: pSrvrStmt->inputRowCnt - When rowsets is used, this is the maximum number of rows to be fetched
* when using the ExecFetch CLI call.
* pSrvrStmt->sqlStmtType - Used with V2.0 SQL to indicate a select and non-select statement type.
*
* OUTPUT: pSrvrStmt->rowCount - The number of rows affected by the Exec or ClearExec/Fetch/Close.
*
*********************************************************************************************** */
SQLRETURN EXECUTE(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("EXECUTE",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
SRVR_CONNECT_HDL *pConnect = NULL;
if(pSrvrStmt->dialogueId == 0) CLI_DEBUG_RETURN_SQL(SQL_ERROR);
pConnect = (SRVR_CONNECT_HDL*)pSrvrStmt->dialogueId;
BOOL isSPJRS = false;
long retcode = SQL_SUCCESS;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
SQLSTMT_ID *pStmt;
SQLSTMT_ID cursorId;
long paramCount;
char *cursorName;
long len;
long curParamNo;
long curLength;
BYTE *varPtr;
BYTE *indPtr;
void *pBytes;
SQLValue_def *SQLValue;
BOOL sqlWarning = FALSE;
int rtn = 0;
pSrvrStmt->isSPJRS = FALSE;
pStmt = &pSrvrStmt->stmt;
pSrvrStmt->endOfData = FALSE; // true=return code 100 from CLI call (no data found)
if ((pSrvrStmt->stmtType == EXTERNAL_STMT) &&
(pSrvrStmt->moduleId.module_name == NULL))
{
// Conditions to check cursor
// SQL 2.0 Chk cursor if version==SQL 2.0 AND SQL Stmt Type==TYPE_SELECT.
// SQL 2.1+ Chk cursor if SQL Stmt query type is a non_unique select.
if ((pSrvrStmt->getSqlQueryStatementType() == SQL_SELECT_NON_UNIQUE) ||
((GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2) && (pSrvrStmt->sqlStmtType & TYPE_SELECT)))
{
cursorName = pSrvrStmt->cursorName;
// If cursor name is not specified, use the stmt name as cursor name
// due to bug in Trafodion, though it should default automatically
if (*cursorName == '\0')
cursorName = pSrvrStmt->stmtName;
DEBUG_OUT(DEBUG_LEVEL_CLI,("cursorName='%s', previousCursorName='%s'",
cursorName,
pSrvrStmt->previousCursorName));
// If cursorName has chg'd from last EXEC or EXECDIRECT cmd
// or has not yet been set for the first time call SetCursorName
if ((strcmp(pSrvrStmt->previousCursorName, cursorName) != 0) &&
(*cursorName != '\0'))
{
cursorId.version = SQLCLI_ODBC_VERSION;
cursorId.module = pStmt->module;
cursorId.handle = 0;
cursorId.charset = SQLCHARSETSTRING_ISO88591;
cursorId.name_mode = cursor_name;
cursorId.identifier_len = strlen(cursorName);
cursorId.identifier = cursorName;
strcpy(pSrvrStmt->previousCursorName, cursorName); // keep track of last cursorName
DEBUG_OUT(DEBUG_LEVEL_CLI,("EXECUTE cursorName %s previousCursorName %s",
cursorName,
pSrvrStmt->previousCursorName));
retcode = CLI_SetCursorName(pStmt, &cursorId);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
}
}
pInputDesc = &pSrvrStmt->inputDesc; // Input descriptor pointer
pOutputDesc = &pSrvrStmt->outputDesc; // Output descriptor pointer. Used in ClearExecFetchClose()
paramCount = pSrvrStmt->paramCount;
if(GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2)
{
pSrvrStmt->isClosed = FALSE; // Assume we are open after EXEC_Exec
if (pSrvrStmt->sqlStmtType & TYPE_SELECT) retcode = CLI_Exec(pStmt, pInputDesc, 0);
else retcode = CLI_ExecFetch(pStmt, pInputDesc, 0);
}
else // VER 2.1
{
// Should be Closed. If Opened assert
DEBUG_ASSERT(pSrvrStmt->isClosed, ("Server Statement is Open before execute."));
pSrvrStmt->isClosed = FALSE; // Assume we are open after EXEC_Exec
switch (pSrvrStmt->getSqlQueryStatementType())
{
case SQL_SELECT_UNIQUE:
DEBUG_OUT(DEBUG_LEVEL_CLI,("Unique SELECT statement type."));
if(pConnect->isSPJRS)
isSPJRS = true;
if(!isSPJRS) {
// ClearExecFetchClose performs exec, fetch, and close
retcode = CLI_ClearExecFetchClose(pStmt, pInputDesc, pOutputDesc, 0, 0, 0);
// ClearExecFetchClose() does an implicit close
pSrvrStmt->isClosed = TRUE;
}
else {
//For SPJRS SELECT UNIQUE
//Using Exec,fetch separately for SPJRS Configuration to avoid statement that is in the closed state.
retcode = CLI_Exec(pStmt, pInputDesc, 0);
if (retcode != 0) CLI_ClearDiagnostics(pStmt);
else {
retcode = CLI_Fetch(pStmt, pOutputDesc, 0);
if (retcode != 0) {
CLI_ClearDiagnostics(pStmt);
pSrvrStmt->endOfData = TRUE; //SPJRS
}
}
}
break;
case SQL_SELECT_NON_UNIQUE:
DEBUG_OUT(DEBUG_LEVEL_CLI,("Non-Unique SELECT statement type."));
retcode = CLI_Exec(pStmt, pInputDesc, 0);
break;
// IUD (Insert, Update, Delete) unique and non-unique Statement Types
case SQL_CONTROL:
case SQL_SET_TRANSACTION:
case SQL_SET_CATALOG:
case SQL_SET_SCHEMA:
DEBUG_OUT(DEBUG_LEVEL_CLI,("Control or Set Connection Attribute statement type."));
case SQL_INSERT_UNIQUE:
case SQL_UPDATE_UNIQUE:
case SQL_DELETE_UNIQUE:
// SQL_OTHER (DDLs - create/alter/drop/etc) should behave like IUD non-unique Statement Types
case SQL_OTHER:
case SQL_INSERT_NON_UNIQUE:
case SQL_UPDATE_NON_UNIQUE:
case SQL_DELETE_NON_UNIQUE:
default:
DEBUG_OUT(DEBUG_LEVEL_CLI,("IUD (Non-Unique and Unique) and control statement types."));
// ClearExecFetchClose performs exec, fetch, and close (implicit close)
// Output Desc = NULL
retcode = CLI_ClearExecFetchClose(pStmt, pInputDesc, NULL, 0, 0, 0);
// ClearExecFetchClose() does an implicit close
pSrvrStmt->isClosed = TRUE;
break;
} // End of stmt type switch
} // End of VER20 check
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING)
{
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("WaitForCompletion() returned %d",rtn));
if (rtn == 0)
{
SQLRETURN rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() returned %ld", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0: // Wait Success
// If not closed, try closing and clear out diag's
if(!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
pSrvrStmt->isClosed = TRUE;
if (retcode != 0) CLI_ClearDiagnostics(pStmt);
}
retcode = 0;
break;
case 9999: // Wait error
pSrvrStmt->isClosed = TRUE;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default: // All other errors
pSrvrStmt->isClosed = TRUE;
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
// If waitForCompletion() was not successful (rtn != 0)
pSrvrStmt->isClosed = TRUE;
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
else
#endif
{
if (retcode!=SQL_SUCCESS) pSrvrStmt->isClosed = TRUE;
}
if (srvrGlobal->moduleCaching)
{
if ( (retcode == 8579) || (retcode == 8578) || (retcode == -1004) || (retcode == -4082) )
{
//If a module file exists and there is a DDL modification in the
//table, we handle it here and return the error to client.
std::string strModuleName = pSrvrStmt->moduleName;
if(strModuleName.find("T2MFC") != -1)
{
pConnect->removeFromLoadedModuleSet(strModuleName);
remove(strModuleName.c_str()); // removing the Module file
}
}
}
// Process the SQL CLI return code
if (retcode != 0){ // SQL success
if (retcode == 100) { // No Data Found
CLI_ClearDiagnostics(pStmt);
retcode = 0;
pSrvrStmt->endOfData = TRUE; // indicates no data found using ClearExecFetchClose()
} else if (retcode < 0) { // SQL Error
THREAD_RETURN(pSrvrStmt,SQL_ERROR);
} else { // > 0, SQL Warning.
sqlWarning = TRUE;
}
}
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
if(GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2)
{
// Not a SELECT stmt type
if ((pSrvrStmt->sqlStmtType & TYPE_SELECT) == 0)
{
Int64 tmpRowCount;
// Get row count
retcode = CLI_GetDiagnosticsStmtInfo2 (pStmt, SQLDIAG_ROW_COUNT,
&tmpRowCount,
NULL, 0, NULL);
if (retcode == SQL_SUCCESS)
pSrvrStmt->rowCount._buffer[0] = (int)tmpRowCount;
else
pSrvrStmt->rowCount._buffer[0] = 0;
pSrvrStmt->totalRowCount += pSrvrStmt->rowCount._buffer[0];
// Batch Binding Size
if (pSrvrStmt->batchRowsetSize)
{
// Currently we only get one value back from SQL for rowsets.
// We will fill in all values with SUCCESS_NO_INFO and ignore the
// one value until SQL updates to return the actual number.
long row_idx;
#ifndef TODO // Linux port Todo - Currently hardcoding actual value
long info_value = SQLMXStatement_SUCCESS_NO_INFO();
#else
long info_value = -2L;
#endif
for (row_idx=0; row_idx<pSrvrStmt->inputRowCnt; row_idx++)
{
pSrvrStmt->rowCount._buffer[pSrvrStmt->rowCount._length+row_idx] = info_value;
}
}
if (retcode < 0) sqlWarning = TRUE;
else pSrvrStmt->rowCount._length += pSrvrStmt->inputRowCnt;
}
}
else { // VER 2.1 or later
// Linux port- moving variable declarations here from case blocks because of compile errors
long rows_read = 0;
long row_idx;
long info_value;
switch (pSrvrStmt->getSqlQueryStatementType())
{
// CLI will not return unique stmt types for rowsets
// Rowset processing will not be a unique command
case SQL_UPDATE_UNIQUE:
case SQL_INSERT_UNIQUE:
case SQL_DELETE_UNIQUE:
if(pSrvrStmt->endOfData) { // UID unique cmds chk for end of data
pSrvrStmt->rowCount._buffer[0] = 0; // If NO DATA FOUND (100) set to 0 row count
}
else {
pSrvrStmt->rowCount._buffer[0] = 1; // If DATA FOUND set row count to 1
}
pSrvrStmt->rowCount._length = 1;
pSrvrStmt->totalRowCount += pSrvrStmt->rowCount._buffer[0];
break;
case SQL_SELECT_UNIQUE:
// Read row count and load outputValueList for unique select
pSrvrStmt->rowsAffected = 0;
rows_read = 0;
if(!pSrvrStmt->endOfData)
{
retcode = ReadRow(pSrvrStmt, &pSrvrStmt->rowsAffected, &rows_read);
if (retcode < 0) THREAD_RETURN(pSrvrStmt,retcode);
if (retcode > 0) sqlWarning = TRUE;
pSrvrStmt->totalRowCount += rows_read;
}
DEBUG_OUT(DEBUG_LEVEL_DATA,("pSrvrStmt->rowsAffected=%ld ; rows_read=%ld", pSrvrStmt->rowsAffected, rows_read));
break;
case SQL_CONTROL:
case SQL_SET_TRANSACTION:
case SQL_SET_CATALOG:
case SQL_SET_SCHEMA:
DEBUG_OUT(DEBUG_LEVEL_CLI,("Control --- Set Connection Attribute statement type."));
case SQL_SELECT_NON_UNIQUE: // Row count to be filled in on subsequent fetch operations
break;
// SQL_OTHER (DDLs - create/alter/drop/etc) should behave like IUD non-unique Statement Types
case SQL_OTHER:
case SQL_INSERT_NON_UNIQUE:
case SQL_UPDATE_NON_UNIQUE:
case SQL_DELETE_NON_UNIQUE:
default:
Int64 tmpRowCount;
// For all other NON-UNIQUE statements get the row count from GetDiag2
retcode = CLI_GetDiagnosticsStmtInfo2( pStmt,
SQLDIAG_ROW_COUNT,
&tmpRowCount,
NULL,
0,
NULL);
if (retcode == 0)
pSrvrStmt->rowCount._buffer[0] = (int)tmpRowCount;
else
pSrvrStmt->rowCount._buffer[0] = 0;
pSrvrStmt->totalRowCount += pSrvrStmt->rowCount._buffer[0];
if (pSrvrStmt->batchRowsetSize > 0){
// Currently we only get one value back from SQL for rowsets.
// We will fill in all values with SUCCESS_NO_INFO and ignore the
// one value until SQL updates to return the actual number.
#ifndef TODO // Linux port Todo - Currently hardcoding actual value
info_value = SQLMXStatement_SUCCESS_NO_INFO();
#else
info_value = -2L;
#endif
for (row_idx=0; row_idx<pSrvrStmt->inputRowCnt; row_idx++) {
pSrvrStmt->rowCount._buffer[pSrvrStmt->rowCount._length+row_idx] = info_value;
}
}
if (retcode < 0) sqlWarning = TRUE;
else {
pSrvrStmt->rowCount._length += pSrvrStmt->inputRowCnt;
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->rowCount._length=%ld", pSrvrStmt->rowCount._length));
}
break;
} // end of default type
} // End of Version 2.0 Check
DEBUG_OUT(DEBUG_LEVEL_ENTRY,( "pSrvrStmt->endOfData=%ld, pSrvrStmt->outputValueList._buffer=0x%08x, pSrvrStmt->outputValueList._length=0x%08x, pSrvrStmt->totalRowCount=%ld",
pSrvrStmt->endOfData, pSrvrStmt->outputValueList._buffer, pSrvrStmt->outputValueList._length,pSrvrStmt->totalRowCount));
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN FREESTATEMENT(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("FREESTATEMENT",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode;
BOOL sqlWarning = FALSE;
SQLSTMT_ID *pStmt;
SQLDESC_ID *pDesc;
if (pSrvrStmt == NULL)
{
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("Server statement not allocated"));
THREAD_RETURN(pSrvrStmt,SQL_INVALID_HANDLE);
}
pStmt = &pSrvrStmt->stmt;
pSrvrStmt->rowsAffected = -1;
switch(pSrvrStmt->freeResourceOpt)
{
case SQL_DROP: // Logical Close
pDesc = &pSrvrStmt->inputDesc;
pSrvrStmt->freeBuffers(SQLWHAT_INPUT_DESC);
// Don't dealloc input descriptor if SPJRS (since it has not been allocated)
if ((pSrvrStmt->inputDescName[0] == '\0') && (!pSrvrStmt->isSPJRS))
{
retcode = CLI_DeallocDesc(pDesc);
if( trace_SQL ) LogDelete("SQL_EXEC_DeallocDesc(pDesc);",(void**)&pDesc,pDesc);
}
pDesc = &pSrvrStmt->outputDesc;
pSrvrStmt->freeBuffers(SQLWHAT_OUTPUT_DESC);
if (pSrvrStmt->outputDescName[0] == '\0')
{
retcode = CLI_DeallocDesc(pDesc);
if( trace_SQL ) LogDelete("SQL_EXEC_DeallocDesc(pDesc);",(void**)&pDesc,pDesc);
}
if (!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
pSrvrStmt->isClosed = TRUE;
}
retcode = CLI_ClearDiagnostics(pStmt);
if (pSrvrStmt->moduleName[0] == '\0')
{
retcode = CLI_DeallocStmt(pStmt);
if( trace_SQL ) LogDelete("SQL_EXEC_DeallocStmt(pStmt);",(void**)&pStmt,pStmt);
}
else
{
if (srvrGlobal->moduleCaching)
{
// Drop only the MFC Module.
SRVR_CONNECT_HDL *pConnect = (SRVR_CONNECT_HDL*)pSrvrStmt->dialogueId;
if(pSrvrStmt->moduleId.module_name != NULL)
{
if(pConnect->isModuleLoaded((const char *) pSrvrStmt->moduleId.module_name))
{
pConnect->removeFromLoadedModuleSet((const char *) pSrvrStmt->moduleId.module_name);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
}
}
}
// For drop, always return success, even if there was a warning.
// This was migrated logic during IDL removal.
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
case SQL_CLOSE: // Physical or hard close
if (! pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
pSrvrStmt->isClosed = TRUE;
if ((pSrvrStmt->stmtType == INTERNAL_STMT) && (retcode!=0)) CLI_ClearDiagnostics(pStmt);
else HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
break;
default:
break;
}
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN PREPARE(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("PREPARE",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode;
SQLRETURN rc;
SQLSTMT_ID *pStmt;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
long numEntries;
char *pStmtName;
BOOL sqlWarning = FALSE;
BOOL rgWarning = FALSE;
int SqlQueryStatementType;
pStmt = &pSrvrStmt->stmt;
pOutputDesc = &pSrvrStmt->outputDesc;
pInputDesc = &pSrvrStmt->inputDesc;
if (!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
if (retcode!=0) retcode = CLI_ClearDiagnostics(pStmt);
pSrvrStmt->isClosed = TRUE;
}
if (pSrvrStmt->holdability == HOLD_CURSORS_OVER_COMMIT){
retcode = CLI_SetStmtAttr(pStmt, SQL_ATTR_CURSOR_HOLDABLE, SQL_HOLDABLE, NULL);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
SQLDESC_ID sqlString_desc;
sqlString_desc.version = SQLCLI_ODBC_VERSION;
sqlString_desc.module = &pSrvrStmt->moduleId;
sqlString_desc.name_mode = string_data;
sqlString_desc.identifier = (const char *)pSrvrStmt->sqlString.dataValue._buffer;
sqlString_desc.handle = 0;
sqlString_desc.identifier_len = pSrvrStmt->sqlString.dataValue._length;
sqlString_desc.charset = SQLCHARSETSTRING_ISO88591;
retcode = CLI_Prepare(pStmt, &sqlString_desc);
int rtn;
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING){
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("WaitForCompletion() returned %d",rtn));
if (rtn == 0){
rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() returned %ld", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0:
retcode = 0;
break;
case 9999:
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
#endif
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->estimatedCost = -1;
retcode = CLI_DescribeStmt(pStmt, pInputDesc, pOutputDesc);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pInputDesc, (int *)&pSrvrStmt->paramCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pOutputDesc, (int *)&pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->prepareSetup();
if (pSrvrStmt->paramCount > 0){
kdsCreateSQLDescSeq(&pSrvrStmt->inputDescList, pSrvrStmt->paramCount+pSrvrStmt->inputDescParamOffset);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Input);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
} else {
kdsCreateEmptySQLDescSeq(&pSrvrStmt->inputDescList);
}
if (pSrvrStmt->columnCount > 0){
kdsCreateSQLDescSeq(&pSrvrStmt->outputDescList, pSrvrStmt->columnCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Output);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
} else {
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
/* *****************************************************************************
* The call to CLI_GetStmtAttr to query the statement type was added as a
* performance enhancement. Previous versions of the Trafodion database will not return
* a statement type, but will return a 0 which is SQL_OTHER. In the case were
* SQL_OTHER is returned and JDBC/MX knows what the statement type is, then the
* JDBC/MX statement type will be used. This will allow the JDBC/MX driver to
* run with an older version of the Trafodion.
* ***************************************************************************** */
DEBUG_OUT(DEBUG_LEVEL_CLI,( "getSQLMX_Version: returned %i", GlobalInformation::getSQLMX_Version()));
if (GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2 ) { //If this version of Trafodion is version R2
if (pSrvrStmt->sqlStmtType != TYPE_UNKNOWN) //If this is a SELECT, INVOKE, or SHOWSHAPE
SqlQueryStatementType = SQL_SELECT_NON_UNIQUE; //then force an execute with no fetch
else SqlQueryStatementType = SQL_OTHER; //else allow an executeFetch
}
else
{
retcode = CLI_GetStmtAttr( &pSrvrStmt->stmt, // (IN) SQL statement ID
SQL_ATTR_QUERY_TYPE, // (IN) Request query statement attribute
(int*)&SqlQueryStatementType, // (OUT) Place to store query statement type
NULL, // (OUT) Optional string
0, // (IN) Max size of optional string buffer
NULL ); // (IN) Length of item
//If there is an error this statement will return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("SQL Query Statement Type=%s",
CliDebugSqlQueryStatementType(SqlQueryStatementType)));
if (SqlQueryStatementType == SQL_EXE_UTIL &&
pSrvrStmt->columnCount > 0)
SqlQueryStatementType = SQL_SELECT_NON_UNIQUE;
pSrvrStmt->setSqlQueryStatementType(SqlQueryStatementType);
switch (pSrvrStmt->getSqlQueryStatementType())
{
case SQL_CALL_NO_RESULT_SETS:
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("Prepare SQL_CALL_NO_RESULT_SETS query type"));
pSrvrStmt->isSPJRS = false; // Indicate this is an RS.
pSrvrStmt->RSIndex = 0; // Index into RS array
pSrvrStmt->RSMax = 0; // No Result Sets to return
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("RSMax: %d RSIndex: %d isSPJRS: %d ", pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS));
break;
case SQL_CALL_WITH_RESULT_SETS:
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("Prepare SQL_CALL_WITH_RESULT_SETS query type"));
pSrvrStmt->isSPJRS = true;
retcode = RSgetRSmax(pSrvrStmt);
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("RSMax: %d RSIndex: %d isSPJRS: %d ", pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS));
//If there is an error this statement will return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
break;
}
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
static SQLRETURN NoDataFound(SRVR_STMT_HDL *pSrvrStmt, long curRowNo, int curRowCount, int *rowsAffected)
{
FUNCTION_ENTRY("NoDataFound",("pSrvrStmt=0x%08x, curRowNo=%ld, curRowCount=%ld, rowsAffected=0x%08x",
pSrvrStmt,
curRowNo,
curRowCount,
rowsAffected));
if (curRowNo == 1)
{
CLI_ClearDiagnostics(&pSrvrStmt->stmt);
CLI_DEBUG_RETURN_SQL(SQL_NO_DATA_FOUND);
}
*rowsAffected = curRowCount;
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("rowsAffected=%ld",*rowsAffected));
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
}
SQLRETURN FETCH(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("FETCH",
("pSrvrStmt=0x%08x",
pSrvrStmt));
long retcode=SQL_SUCCESS;
int curRowCount = 0;
long curRowNo;
long curColumnNo;
BYTE *varPtr;
short *indPtr;
BYTE *pBytes;
long dataType;
long dataLength;
long allocLength;
short indValue;
long columnCount;
long charSet;
long fetchSize;
SQLDESC_ID *pDesc;
BOOL sqlWarning = FALSE;
pDesc = &pSrvrStmt->outputDesc;
columnCount = pSrvrStmt->columnCount;
if (pSrvrStmt->fetchRowsetSize == 0) {
fetchSize = 1;
}
else {
fetchSize = pSrvrStmt->fetchRowsetSize;
}
curRowNo = 1;
while (curRowNo <= pSrvrStmt->maxRowCnt)
{
DEBUG_OUT(DEBUG_LEVEL_STMT,("***Anitha ---- >pSrvrStmt->isClosed=%ld", pSrvrStmt->isClosed));
/// For Modius
CLI_ClearDiagnostics(&pSrvrStmt->stmt);
retcode = CLI_Fetch(&pSrvrStmt->stmt, pDesc, 0);
int rtn;
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING){
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("WaitForCompletion() returned %d",rtn));
if (rtn == 0){
SQLRETURN rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() returned %ld", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0: // nowaitRetcode is successful
retcode = 0;
break;
case 9999:
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
/* Soln No: 10-070223-2784
Desc: JDBC/MX should call stmtinfo2 instead of Diagoninfo2 CLI call for rowsets
*/
/* long row = 0;
retcode = CLI_GetDiagnosticsStmtInfo2(&pSrvrStmt->stmt,SQLDIAG_ROW_COUNT,&row,NULL,0,NULL);
if(row == 0)
retcode = GETSQLCODE(pSrvrStmt);
*/
// Refixed 10-070223-2784 for sol.10-090613-2299
retcode = GETSQLCODE(pSrvrStmt);
long rows_read_fin = 0;
long retcodenew = 0;
if (pSrvrStmt->fetchRowsetSize > 0)
{
retcodenew = ReadRow(pSrvrStmt, &curRowCount, &rows_read_fin);
if (retcodenew < 0) THREAD_RETURN(pSrvrStmt,retcodenew);
if (retcodenew > 0) sqlWarning = TRUE;
curRowNo += rows_read_fin;
}
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else {
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
#endif
if (retcode != 0)
{ //Check for a bad return code
if (retcode == 100)
{
THREAD_RETURN(pSrvrStmt,NoDataFound(pSrvrStmt,curRowNo,curRowCount,&pSrvrStmt->rowsAffected));
}
else if (retcode < 0)
{
THREAD_RETURN(pSrvrStmt,SQL_ERROR);
}
else
{
sqlWarning = TRUE;
}
}
// Read row count and load the output value list
long rows_read = 0;
retcode = ReadRow(pSrvrStmt, &curRowCount, &rows_read);
if (retcode < 0) THREAD_RETURN(pSrvrStmt,retcode);
if (retcode > 0) sqlWarning = TRUE;
curRowNo += rows_read;
}
pSrvrStmt->rowsAffected = curRowCount > pSrvrStmt->maxRowCnt ? pSrvrStmt->maxRowCnt : curRowCount;
DEBUG_OUT(DEBUG_LEVEL_ENTRY,("pSrvrStmt->rowsAffected=%ld curRowCount=%ld pSrvrStmt->maxRowCnt=%ld",
pSrvrStmt->rowsAffected, curRowCount, pSrvrStmt->maxRowCnt));
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN GETSQLERROR(SRVR_STMT_HDL *pSrvrStmt,
odbc_SQLSvc_SQLError *SQLError)
{
FUNCTION_ENTRY("GETSQLERROR",
("pSrvrStmt=0x%08x, SQLError=0x%08x",
pSrvrStmt,
SQLError));
long retcode;
int total_conds = 0;
int buf_len;
int sqlcode = 0;
char sqlState[6];
int curr_cond = 1;
retcode = CLI_GetDiagnosticsStmtInfo2(NULL,
SQLDIAG_NUMBER,
&total_conds, NULL, 0, NULL);
if (total_conds == 0)
{
kdsCreateSQLErrorException(SQLError, 1);
kdsCopySQLErrorException(SQLError, "No error message in Trafodion diagnostics area, but sqlcode is non-zero", retcode, "");
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
kdsCreateSQLErrorException(SQLError, total_conds);
while (curr_cond <= total_conds)
{
char *msg_buf=NULL;
int msg_buf_len;
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_SQLCODE, curr_cond,
&sqlcode, NULL, 0, NULL);
if (retcode >= SQL_SUCCESS)
{
if (sqlcode == 100)
{
// We are not copying the Warning message if the error code is 100
// It is ok, though we have allocated more SQLError, but length is incremented
// only when SQLError is copied
curr_cond++;
continue;
}
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_MSG_LEN, curr_cond,
&msg_buf_len, NULL, 0, NULL);
}
if (retcode >= SQL_SUCCESS)
{
MEMORY_ALLOC_ARRAY(msg_buf, char, msg_buf_len+1);
msg_buf[msg_buf_len] = 0;
buf_len = 0;
// By passing the msg_buf_len to the following SQL call,
// the returned buf_len will be equal to msg_buf_len w/o a
// null terminator. If a value greater than msg_buf_len is passed,
// msg_buf will be null terminated by SQL.
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_MSG_TEXT, curr_cond,
NULL, msg_buf, msg_buf_len, &buf_len);
DEBUG_ASSERT(msg_buf[msg_buf_len]==0,("Memory corruption detected during error message handling"));
}
if (retcode >= SQL_SUCCESS)
{
// Found that the returned CLI message length can be incorrect. If the
// size returned is too small, we will retry once with a bigger buffer and hope
// it works.
if (buf_len>msg_buf_len)
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("CLI Message length changed. Retrying."));
MEMORY_DELETE_ARRAY(msg_buf);
msg_buf_len = buf_len;
MEMORY_ALLOC_ARRAY(msg_buf, char, msg_buf_len+1);
msg_buf[msg_buf_len] = 0;
buf_len = 0;
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_MSG_TEXT, curr_cond,
NULL, msg_buf, msg_buf_len, &buf_len);
DEBUG_ASSERT(msg_buf[msg_buf_len]==0,("Memory corruption detected during error message retry handling"));
// Happened again. Just use the short buffer.
if (buf_len>msg_buf_len) buf_len = msg_buf_len;
}
// Null terminate msg_buf since it is not yet null terminated.
msg_buf[buf_len] = '\0';
DEBUG_OUT(DEBUG_LEVEL_CLI,("msg_buf='%s'",msg_buf));
buf_len = 0;
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_RET_SQLSTATE, curr_cond,
NULL, sqlState, sizeof(sqlState), &buf_len);
}
if (retcode < SQL_SUCCESS)
{
kdsCopySQLErrorException(SQLError, "Internal Error : From CLI_GetDiagnosticsCondInfo2",
retcode, "");
MEMORY_DELETE_ARRAY(msg_buf);
break;
}
sqlState[5] = '\0';
kdsCopySQLErrorException(SQLError, msg_buf, sqlcode, sqlState);
MEMORY_DELETE_ARRAY(msg_buf);
curr_cond++;
}
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN EXECDIRECT(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("EXECDIRECT",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode = SQL_SUCCESS;
SQLSTMT_ID *pStmt;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
SQLSTMT_ID cursorId;
long numEntries;
char *pStmtName;
char *cursorName;
size_t len;
BOOL sqlWarning = FALSE;
pStmt = &pSrvrStmt->stmt;
pInputDesc = &pSrvrStmt->inputDesc;
pOutputDesc = &pSrvrStmt->outputDesc;
SQLDESC_ID sqlString_desc;
sqlString_desc.version = SQLCLI_ODBC_VERSION;
sqlString_desc.module = &pSrvrStmt->moduleId;
sqlString_desc.name_mode = string_data;
sqlString_desc.identifier = (const char *) pSrvrStmt->sqlString.dataValue._buffer;
sqlString_desc.handle = 0;
sqlString_desc.identifier_len = pSrvrStmt->sqlString.dataValue._length;
sqlString_desc.charset = SQLCHARSETSTRING_ISO88591;
DEBUG_ASSERT(pSrvrStmt->isClosed, ("Server Statement is Open before execute."));
pSrvrStmt->isClosed = TRUE;
if (pSrvrStmt->sqlStmtType & TYPE_SELECT)
{
retcode = CLI_Prepare(pStmt, &sqlString_desc);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->estimatedCost = -1;
}
else
{
retcode = CLI_ExecDirect(pStmt, &sqlString_desc, 0, 0);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->isClosed = FALSE;
pSrvrStmt->estimatedCost = -1;
}
if (pSrvrStmt->sqlStmtType & TYPE_SELECT)
{
// Retrieving/loading OutputDesc values
retcode = CLI_DescribeStmt(pStmt, (SQLDESC_ID *)NULL, pOutputDesc);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pOutputDesc, (int*)&pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
if (pSrvrStmt->columnCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->outputDescList, pSrvrStmt->columnCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Output);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
}
else
{
pSrvrStmt->columnCount = 0;
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
if (pSrvrStmt->stmtType == EXTERNAL_STMT)
{
if (pSrvrStmt->sqlStmtType & TYPE_SELECT)
{
cursorName = pSrvrStmt->cursorName;
// If cursor name is not specified, use the stmt name as cursor name
if (*cursorName == '\0') {
cursorName = pSrvrStmt->stmtName;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("cursorName %s previousCursorName %s",
cursorName,
pSrvrStmt->previousCursorName));
// If cursorName has chg'd from last EXEC or EXECDIRECT cmd
// or has not yet been set for the first time call SetCursorName
if ((strcmp(pSrvrStmt->previousCursorName, cursorName) != 0) && *cursorName != '\0')
{
cursorId.version = SQLCLI_ODBC_VERSION;
cursorId.module = pStmt->module;
cursorId.handle = 0;
cursorId.charset = SQLCHARSETSTRING_ISO88591;
cursorId.name_mode = cursor_name;
cursorId.identifier_len = strlen(cursorName);
cursorId.identifier = cursorName;
strcpy(pSrvrStmt->previousCursorName, cursorName); // keep track of last cursor name used
DEBUG_OUT(DEBUG_LEVEL_CLI,("cursorName %s previousCursorName %s",
cursorName,
pSrvrStmt->previousCursorName));
retcode = CLI_SetCursorName(pStmt, &cursorId);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
retcode = CLI_Exec(pStmt, NULL, 0);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->isClosed = FALSE;
}
}
if (retcode >= SQL_SUCCESS)
{
// If NOT a select type
if ((pSrvrStmt->sqlStmtType & TYPE_SELECT)==0)
{
Int64 tmpRowCount;
retcode = CLI_GetDiagnosticsStmtInfo2(pStmt, SQLDIAG_ROW_COUNT, &tmpRowCount,
NULL, 0, NULL);
if (retcode < 0)
{
sqlWarning = TRUE;
pSrvrStmt->rowsAffected = -1;
}
else
pSrvrStmt->rowsAffected = (int)tmpRowCount;
}
else
pSrvrStmt->rowsAffected = -1;
}
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN EXECUTESPJRS(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("EXECUTESPJRS",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode = SQL_SUCCESS;
SQLDESC_ID *pOutputDesc;
SQLSTMT_ID *pStmt;
SQLSTMT_ID cursorId;
long numEntries;
char *pStmtName;
char *cursorName;
size_t len;
BOOL sqlWarning = FALSE;
int rtn = 0;
SQLRETURN rc;
// For debug purposes only
//long int SqlQueryStatementType;
pStmt = &pSrvrStmt->stmt;
pOutputDesc = &pSrvrStmt->outputDesc;
DEBUG_OUT(DEBUG_LEVEL_STMT,("pStmt=0x%08x, pOutputDesc=0x%08x, RSIndex=%ld, isClosed=0x%08x",
pStmt,
pOutputDesc,
pSrvrStmt->RSIndex,
pSrvrStmt->isClosed));
// Retrieving/loading OutputDesc values
retcode = CLI_DescribeStmt(pStmt, (SQLDESC_ID *)NULL, pOutputDesc);
DEBUG_OUT(DEBUG_LEVEL_CLI, ("EXECUTESPJRS : retcode = %s",
CliDebugSqlError(retcode)));
// Trying to open a non-existent SPJRS
if(retcode == RS_DOES_NOT_EXIST)
{
pSrvrStmt->isClosed = TRUE;
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
THREAD_RETURN(pSrvrStmt,SQL_RS_DOES_NOT_EXIST);
}
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pOutputDesc,(int*) &pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
if (pSrvrStmt->columnCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->outputDescList, pSrvrStmt->columnCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Output);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
cursorName = pSrvrStmt->cursorName;
// If cursor name is not specified, use the stmt name as cursor name
if (*cursorName == '\0') {
cursorName = pSrvrStmt->stmtName;
}
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("cursorName %s : previousCursorName %s",
cursorName, pSrvrStmt->previousCursorName));
// If cursorName has chg'd from last EXEC or EXECDIRECT cmd
// or has not yet been set for the first time call SetCursorName
if ((strcmp(pSrvrStmt->previousCursorName, cursorName) != 0) && *cursorName != '\0')
{
cursorId.version = SQLCLI_ODBC_VERSION;
cursorId.module = pStmt->module;
cursorId.handle = 0;
cursorId.charset = SQLCHARSETSTRING_ISO88591;
cursorId.name_mode = cursor_name;
cursorId.identifier_len = strlen(cursorName);
cursorId.identifier = cursorName;
strcpy(pSrvrStmt->previousCursorName, cursorName);
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,
("Calling CLI_SetCursorName - cursorName %s : previousCursorName %s",
cursorName,
pSrvrStmt->previousCursorName));
retcode = CLI_SetCursorName(pStmt, &cursorId);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
DEBUG_ASSERT(pSrvrStmt->isClosed, ("Server RS Statement is Open before execute."));
retcode = CLI_Exec(pStmt, NULL, 0);
DEBUG_OUT(DEBUG_LEVEL_STMT,("EXECUTESPJRS CLI_EXEC retcode: %ld.", retcode));
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->isClosed = FALSE;
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING){
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("EXECUTESPJRS : WaitForCompletion() returned %d",rtn));
if (rtn == 0)
{
rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("EXECUTESPJRS pSrvrStmt->switchContext() return with: %ld.", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0:
retcode = 0;
break;
case 9999:
pSrvrStmt->isClosed = TRUE;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
pSrvrStmt->isClosed = TRUE;
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,
("EXECUTESPJRS : pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
pSrvrStmt->isClosed = TRUE;
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
#endif
// Note this could do a return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN GETSQLWARNING(SRVR_STMT_HDL *pSrvrStmt,
ERROR_DESC_LIST_def *sqlWarning)
{
// This function is needed since SQLError uses odbc_SQLSvc_SQLError * instead of ERROR_DESC_LIST_def *
// Hence this function wraps around GETSQLERROR
FUNCTION_ENTRY("GETSQLWARNING",
("pSrvrStmt=0x%08x, sqlWarning=0x%08x",
pSrvrStmt,
sqlWarning));
odbc_SQLSvc_SQLError SQLError;
CLEAR_ERROR(SQLError);
long retcode = GETSQLERROR(pSrvrStmt, &SQLError);
sqlWarning->_length = SQLError.errorList._length;
sqlWarning->_buffer = SQLError.errorList._buffer;
CLI_DEBUG_RETURN_SQL((SQLRETURN)retcode);
}
SQLRETURN CANCEL(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("CANCEL",
("pSrvrStmt=0x%08x",
pSrvrStmt));
THREAD_RETURN(pSrvrStmt,CLI_Cancel(&pSrvrStmt->stmt));
}
SQLRETURN CLEARDIAGNOSTICS(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("CLEARDIAGNOSTICS",
("pSrvrStmt=0x%08x",
pSrvrStmt));
long retcode = CLI_ClearDiagnostics(&pSrvrStmt->stmt);
CLI_DEBUG_RETURN_SQL((SQLRETURN)retcode);
}
SQLRETURN PREPARE_FROM_MODULE(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("PREPARE_FROM_MODULE",
("pSrvrStmt=0x%08x",
pSrvrStmt));
long retcode = SQL_SUCCESS;
SQLSTMT_ID *pStmt;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
int SqlQueryStatementType;
long numEntries;
char *pStmtName;
BOOL sqlWarning = FALSE;
pStmt = &pSrvrStmt->stmt;
pInputDesc = &pSrvrStmt->inputDesc;
pOutputDesc = &pSrvrStmt->outputDesc;
if (!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
if (retcode!=0)
{
retcode = CLI_ClearDiagnostics(pStmt);
}
pSrvrStmt->isClosed = TRUE;
}
if (pSrvrStmt->holdability == HOLD_CURSORS_OVER_COMMIT)
{
retcode = CLI_SetStmtAttr(&pSrvrStmt->stmt, SQL_ATTR_CURSOR_HOLDABLE, SQL_HOLDABLE, NULL);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
// MFC if mfc is on allocate descriptors even if descriptor name is NULL
if ((pSrvrStmt->useDefaultDesc) && (!srvrGlobal->moduleCaching))
{
if (pSrvrStmt->inputDescName[0] != '\0')
{
retcode = CLI_GetDescEntryCount(pInputDesc, (int *)&pSrvrStmt->paramCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
pSrvrStmt->paramCount = 0;
}
if (pSrvrStmt->outputDescName[0] != '\0')
{
retcode = CLI_GetDescEntryCount(pOutputDesc, (int *)&pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
pSrvrStmt->columnCount = 0;
}
else
{
retcode = CLI_DescribeStmt(pStmt, pInputDesc, pOutputDesc);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pInputDesc, (int *)&pSrvrStmt->paramCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pOutputDesc, (int *)&pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
if (pSrvrStmt->paramCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->inputDescList, pSrvrStmt->paramCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Input);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
kdsCreateEmptySQLDescSeq(&pSrvrStmt->inputDescList);
}
if (pSrvrStmt->columnCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->outputDescList, pSrvrStmt->columnCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Output);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
/* *****************************************************************************
* The call to SQL_EXEC_GetStmtAttr to query the statement type was added as a
* performance enhancement. Previous version of the Trafodion database will not return
* a statement type, but will return a 0 which is SQL_OTHER. In the case were
* SQL_OTHER is returned and JDBC/MX knows what the statement type is, then the
* JDBC/MX statement type will be used. This will allow the JDBC/MX driver to
* run with an older version of the Trafodion.
* ***************************************************************************** */
DEBUG_OUT(DEBUG_LEVEL_CLI,( "getSQLMX_Version: returned %i", GlobalInformation::getSQLMX_Version()));
if (GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2 ) { //If this version of Trafodion is version R2
if (pSrvrStmt->sqlStmtType != TYPE_UNKNOWN) //If this is a SELECT, INVOKE, or SHOWSHAPE
SqlQueryStatementType = SQL_SELECT_NON_UNIQUE; //then force an execute with no fetch
else SqlQueryStatementType = SQL_OTHER; //else allow an executeFetch
}
else
{
retcode = CLI_GetStmtAttr( &pSrvrStmt->stmt, // (IN) SQL statement ID
SQL_ATTR_QUERY_TYPE, // (IN) Request query statement attribute
&SqlQueryStatementType, // (OUT) Place to store query statement type
NULL, // (OUT) Optional string
0, // (IN) Max size of optional string buffer
NULL ); // (IN) Length of item
//If there is an error this statement will return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("SQL Query Statement Type=%s",
CliDebugSqlQueryStatementType(SqlQueryStatementType)));
pSrvrStmt->setSqlQueryStatementType(SqlQueryStatementType);
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN ALLOCSQLMXHDLS(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("ALLOCSQLMXHDLS", ("pSrvrStmt=0x%08x",
pSrvrStmt));
#if defined(TAG64)
int _ptr32* tempStmtId;
#endif
long retcode = SQL_SUCCESS;
SQLSTMT_ID *pStmt = &pSrvrStmt->stmt;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
SQLMODULE_ID *pModule = &pSrvrStmt->moduleId;
BOOL sqlWarning;
pStmt->version = SQLCLI_ODBC_VERSION;
pStmt->module = pModule;
pStmt->handle = 0;
pStmt->charset = SQLCHARSETSTRING_ISO88591;
if (pSrvrStmt->stmtName[0] != '\0')
{
pStmt->name_mode = stmt_name;
pStmt->identifier_len = strlen(pSrvrStmt->stmtName);
pStmt->identifier = pSrvrStmt->stmtName;
}
else
{
pStmt->name_mode = stmt_handle;
pStmt->identifier_len = 0;
pStmt->identifier = NULL;
}
if (srvrGlobal->nowaitOn)
{
#if defined(TAG64)
tempStmtId=(int _ptr32*)malloc32(sizeof(int));
pStmt->tag=(int)tempStmtId;
tempStmtIdMap[(long)tempStmtId]=pSrvrStmt;
#else
pStmt->tag = (long)pSrvrStmt;
#endif
}
else
{
pStmt->tag = 0;
}
if (pModule->module_name == NULL)
{
retcode = CLI_AllocStmt(pStmt,(SQLSTMT_ID *)NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
// MFC if mfc is on allocate descriptors
if ( ((srvrGlobal->moduleCaching) /*&& (srvrGlobal->moduleExists)*/)
|| (!pSrvrStmt->useDefaultDesc))
{
pInputDesc = &pSrvrStmt->inputDesc;
pInputDesc->version = SQLCLI_ODBC_VERSION;
pInputDesc->handle = 0;
pInputDesc->charset = SQLCHARSETSTRING_ISO88591;
pInputDesc->name_mode = desc_handle;
pInputDesc->identifier_len = 0;
pInputDesc->identifier = NULL;
pInputDesc->module = pModule;
retcode = CLI_AllocDesc(pInputDesc, (SQLDESC_ID *)NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
pOutputDesc = &pSrvrStmt->outputDesc;
pOutputDesc->version = SQLCLI_ODBC_VERSION;
pOutputDesc->handle = 0;
pOutputDesc->charset = SQLCHARSETSTRING_ISO88591;
pOutputDesc->name_mode = desc_handle;
pOutputDesc->identifier_len = 0;
pOutputDesc->identifier = NULL;
pOutputDesc->module = pModule;
retcode = CLI_AllocDesc(pOutputDesc, (SQLDESC_ID *)NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
else
{
pInputDesc = &pSrvrStmt->inputDesc;
pInputDesc->version = SQLCLI_ODBC_VERSION;
pInputDesc->handle = 0;
pInputDesc->name_mode = desc_name;
pInputDesc->identifier_len = MAX_DESC_NAME_LEN;
pInputDesc->identifier = pSrvrStmt->inputDescName;
pInputDesc->module = pModule;
retcode = CLI_ResDescName(pInputDesc, pStmt, SQLWHAT_INPUT_DESC);
if (retcode == -8803)
{
pInputDesc->identifier_len = 0;
CLI_ClearDiagnostics(NULL);
retcode = 0;
}
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
pSrvrStmt->inputDescName[pInputDesc->identifier_len] = '\0';
pOutputDesc = &pSrvrStmt->outputDesc;
pOutputDesc->version = SQLCLI_ODBC_VERSION;
pOutputDesc->handle = 0;
pOutputDesc->charset = SQLCHARSETSTRING_ISO88591;
pOutputDesc->name_mode = desc_name;
pOutputDesc->identifier_len = MAX_DESC_NAME_LEN;
pOutputDesc->identifier = pSrvrStmt->outputDescName;
pOutputDesc->module = pModule;
retcode = CLI_ResDescName(pOutputDesc, pStmt, SQLWHAT_OUTPUT_DESC);
if (retcode == -8803)
{
pOutputDesc->identifier_len = 0;
retcode = CLI_ClearDiagnostics(NULL);
retcode = 0;
}
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
pSrvrStmt->outputDescName[pOutputDesc->identifier_len] = '\0';
}
if (srvrGlobal->nowaitOn)
{
retcode = CLI_AssocFileNumber(pStmt, srvrGlobal->nowaitFilenum);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
// Set the input and output Desc to be Wide Descriptors
if ( ((srvrGlobal->moduleCaching) /*&& (srvrGlobal->moduleExists)*/)
|| (!pSrvrStmt->useDefaultDesc))
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("Non-Default descriptor."));
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pInputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pOutputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
else
{
if (pSrvrStmt->inputDescName[0] != '\0')
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("Default descriptor. Input Descriptor Name=%s",
pSrvrStmt->inputDescName));
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pInputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
if (pSrvrStmt->outputDescName[0] != '\0')
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("Default descriptor. Output Descriptor Name=%s",
pSrvrStmt->outputDescName));
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pOutputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
}
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN ALLOCSQLMXHDLS_SPJRS(SRVR_STMT_HDL *pSrvrStmt, SQLSTMT_ID *callpStmt, const char *RSstmtLabel)
{
FUNCTION_ENTRY("ALLOCSQLMXHDLS_SPJRS", ("pSrvrStmt=0x%08x, callpStmt=0x%08x, RSstmtLabel=%s",
pSrvrStmt,
callpStmt,
RSstmtLabel));
#if defined(TAG64)
int _ptr32* tempStmtId;
#endif
long retcode = SQL_SUCCESS;
SQLSTMT_ID *pStmt = &pSrvrStmt->stmt;
SQLDESC_ID *pOutputDesc;
SQLMODULE_ID *pModule = &pSrvrStmt->moduleId;
BOOL sqlWarning;
pStmt->version = SQLCLI_ODBC_VERSION;
pStmt->module = pModule;
pStmt->handle = 0;
pStmt->charset = SQLCHARSETSTRING_ISO88591;
if (pSrvrStmt->stmtName[0] != '\0')
{
pStmt->name_mode = stmt_name;
pStmt->identifier_len = strlen(pSrvrStmt->stmtName);
pStmt->identifier = pSrvrStmt->stmtName;
}
else
{
pStmt->name_mode = stmt_handle;
pStmt->identifier_len = 0;
pStmt->identifier = NULL;
}
DEBUG_OUT(DEBUG_LEVEL_STMT,("***pStmt->name_mode=%ld", pStmt->name_mode));
DEBUG_OUT(DEBUG_LEVEL_STMT,("***pStmt->identifier_len=%ld", pStmt->identifier_len));
DEBUG_OUT(DEBUG_LEVEL_STMT,("***pStmt->identifier=%s", pStmt->identifier));
if (srvrGlobal->nowaitOn)
{
#if defined(TAG64)
tempStmtId=(int _ptr32*)malloc32(sizeof(int));
pStmt->tag=(int)tempStmtId;
tempStmtIdMap[(int)tempStmtId]=pSrvrStmt;
#else
pStmt->tag = (long)pSrvrStmt;
#endif
}
else
pStmt->tag = 0;
if (pModule->module_name == NULL)
{
DEBUG_OUT(DEBUG_LEVEL_STMT,("***pModule->module_name == NULL Call AllocStmtForRs()"));
CLI_AllocStmtForRS(callpStmt,
pSrvrStmt->RSIndex,
pStmt);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
if (pSrvrStmt->useDefaultDesc)
{
pOutputDesc = &pSrvrStmt->outputDesc;
pOutputDesc->version = SQLCLI_ODBC_VERSION;
pOutputDesc->handle = 0;
pOutputDesc->charset = SQLCHARSETSTRING_ISO88591;
pOutputDesc->name_mode = desc_name;
pOutputDesc->identifier_len = MAX_DESC_NAME_LEN;
pOutputDesc->identifier = pSrvrStmt->outputDescName;
pOutputDesc->module = pModule;
retcode = CLI_ResDescName(pOutputDesc, pStmt, SQLWHAT_OUTPUT_DESC);
if (retcode == -8803)
{
pOutputDesc->identifier_len = 0;
retcode = CLI_ClearDiagnostics(NULL);
retcode = 0;
}
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
pSrvrStmt->outputDescName[pOutputDesc->identifier_len] = '\0';
}
else
{
pOutputDesc = &pSrvrStmt->outputDesc;
pOutputDesc->version = SQLCLI_ODBC_VERSION;
pOutputDesc->handle = 0;
pOutputDesc->charset = SQLCHARSETSTRING_ISO88591;
pOutputDesc->name_mode = desc_handle;
pOutputDesc->identifier_len = 0;
pOutputDesc->identifier = NULL;
pOutputDesc->module = pModule;
retcode = CLI_AllocDesc(pOutputDesc, (SQLDESC_ID *)NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
if (srvrGlobal->nowaitOn)
{
retcode = CLI_AssocFileNumber(pStmt, srvrGlobal->nowaitFilenum);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
// Set the output Desc to be Wide Descriptors
if (pSrvrStmt->useDefaultDesc)
{
if (pSrvrStmt->outputDescName[0] != '\0')
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("Default descriptor. Output Descriptor Name=%s",
pSrvrStmt->outputDescName));
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pOutputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
}
else
{
DEBUG_OUT(DEBUG_LEVEL_CLI,("Non-Default descriptor."));
//R321: passing 1 instead of 0 for CLI_SetDescItem
retcode = CLI_SetDescItem(pOutputDesc, 1, SQLDESC_DESCRIPTOR_TYPE, DESCRIPTOR_TYPE_WIDE, NULL);
if (retcode < 0)
{
CLI_ClearDiagnostics(NULL);
CLI_DEBUG_RETURN_SQL(retcode);
}
}
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN EXECUTECALL(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("EXECUTECALL",
("pSrvrStmt=0x%08x",
pSrvrStmt));
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
int rtn;
long columnCount;
long paramCount;
long retcode = SQL_SUCCESS;
BOOL sqlWarning = FALSE;
SQLDESC_ID *pDesc;
SQLDESC_ID *pDescParam;
SQLDESC_ID *pDescValue;
SQLSTMT_ID *pStmt;
SQLRETURN rc;
pStmt = &pSrvrStmt->stmt;
DEBUG_OUT(DEBUG_LEVEL_STMT,("EXECUTECALL : isClosed = %ld", pSrvrStmt->isClosed));
if (!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
if (retcode!=0) retcode = CLI_ClearDiagnostics(pStmt);
pSrvrStmt->isClosed = TRUE;
}
pDesc = &pSrvrStmt->inputDesc;
paramCount = pSrvrStmt->paramCount;
if (paramCount > 0){
pDescValue = pDesc;
}
else {
pDescValue = NULL;
}
DEBUG_ASSERT(pSrvrStmt->isClosed, ("Server Statement is Open before int."));
pSrvrStmt->isClosed = FALSE;
retcode = CLI_Exec(pStmt, pDescValue, 0);
DEBUG_OUT(DEBUG_LEVEL_STMT,("intCALL CLI_EXEC retcode: %ld.", retcode));
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->isClosed = FALSE;
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING){
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("WaitForCompletion() returned %d",rtn));
if (rtn == 0)
{
rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() return with: %ld.", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0:
retcode = 0;
break;
case 9999:
pSrvrStmt->isClosed = TRUE;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
pSrvrStmt->isClosed = TRUE;
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
pSrvrStmt->isClosed = TRUE;
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
else
#endif
{
if (retcode!=SQL_SUCCESS) pSrvrStmt->isClosed = TRUE;
}
// Note this could do a return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pDesc = &pSrvrStmt->outputDesc;
columnCount = pSrvrStmt->columnCount;
if (columnCount > 0) {
pDescParam = pDesc;
}
else {
pDescParam = NULL;
}
DEBUG_OUT(DEBUG_LEVEL_STMT,("***Anitha ---- >pSrvrStmt->isClosed=%ld", pSrvrStmt->isClosed));
retcode = CLI_Fetch(pStmt, pDescParam, 0);
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING) {
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("WaitForCompletion() returned %d",rtn));
if (rtn == 0)
{
rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() return with: %ld.", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0:
retcode = 0;
break;
case 9999:
pSrvrStmt->isClosed = TRUE;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
pSrvrStmt->isClosed = TRUE;
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
pSrvrStmt->isClosed = TRUE;
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
else
#endif
{
if (retcode!=SQL_SUCCESS) pSrvrStmt->isClosed = TRUE;
}
// Return if the fetch failed
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
// SPJRS - Only close when not SPJRS and not already closed
if ((!pSrvrStmt->isSPJRS) && (!pSrvrStmt->isClosed))
{
retcode = CLI_CloseStmt(pStmt);
// Set the close flag so that another close is not tried
pSrvrStmt->isClosed = TRUE;
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
SQLRETURN CONNECT(SRVR_CONNECT_HDL *pSrvrConnect)
{
FUNCTION_ENTRY("CONNECT",
("pSrvrConnect=0x%08x",
pSrvrConnect));
long retcode;
BOOL sqlWarning = FALSE;
retcode = CLI_CreateContext(&pSrvrConnect->contextHandle, NULL, 0);
HANDLE_ERROR(retcode, sqlWarning);
retcode = CLI_SwitchContext(pSrvrConnect->contextHandle, NULL);
HANDLE_ERROR(retcode, sqlWarning);
if (sqlWarning) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN DISCONNECT(SRVR_CONNECT_HDL *pSrvrConnect)
{
FUNCTION_ENTRY("DISCONNECT",
("pSrvrConnect=0x%08x",
pSrvrConnect));
long retcode;
// Hack.
// Executor starts an internal transaction to clean up volatile schemas
// when a context is deleted. But it does not clean up properly when this
// is called from the T2 driver. This is because transactions from the T2
// interface are no-waited. TMF expects AWAITIOX to be called after the
// ENDTRANSACTION to clean up the TFILE entry. However, Executor does not
// make any AWAITIOX calls. So this affects the "active" transaction for
// the process - pthreads thinks it is working on a user transaction when
// it is actually working on the committed Executor transaction. This causes
// the calling thread to hang.
//
// Designing a proper fix for this will take some time. For now, we hack
// around this by resuming the user transaction after the Executor returns
// from the DeleteContext call.
//Start Soln. No.: 10-110830-9447
short txHandle[10];
long txBeginTag;
retcode = CLI_DeleteContext(pSrvrConnect->contextHandle);
// Resume the transaction before handling any errors from the disconnect.
resumeTransaction(txBeginTag);
//End Soln. No.: 10-110830-9447
if (retcode==0) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
}
SQLRETURN SWITCHCONTEXT(SRVR_CONNECT_HDL *pSrvrConnect, long *sqlcode)
{
FUNCTION_ENTRY("SWITCHCONTEXT",
("pSrvrConnect=0x%08x, sqlcode=(out)",
pSrvrConnect));
long retcode;
BOOL sqlWarning = FALSE;
retcode = CLI_SwitchContext(pSrvrConnect->contextHandle, NULL);
if (sqlcode != NULL)
*sqlcode = retcode;
HANDLE_ERROR(retcode, sqlWarning);
if (sqlWarning) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
SQLRETURN GETSQLCODE(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY("GETSQLCODE",("pSrvrStmt=0x%08x",pSrvrStmt));
long retcode;
int sqlcode = 0;
retcode = CLI_GetDiagnosticsCondInfo2(SQLDIAG_SQLCODE,
1, &sqlcode, NULL, 0, NULL);
if (retcode >= SQL_SUCCESS)
CLI_DEBUG_RETURN_SQL(sqlcode);
CLI_DEBUG_RETURN_SQL(retcode);
}
// MFC - new method PREPARE + createModulePlan
SQLRETURN PREPAREFORMFC(SRVR_STMT_HDL* pSrvrStmt)
{
FUNCTION_ENTRY("PREPAREFORMFC",
("pSrvrStmt=0x%08x",
pSrvrStmt));
#ifdef NSK_PLATFORM // Linux port - Todo: Not supported
CLI_DEBUG_SHOW_SERVER_STATEMENT(pSrvrStmt);
long retcode;
SQLRETURN rc;
SQLSTMT_ID *pStmt;
SQLDESC_ID *pInputDesc;
SQLDESC_ID *pOutputDesc;
SRVR_CONNECT_HDL *pConnect;
long numEntries;
char *pStmtName;
BOOL sqlWarning = FALSE;
BOOL rgWarning = FALSE;
int SqlQueryStatementType;
pConnect = (SRVR_CONNECT_HDL *)pSrvrStmt->dialogueId;
pStmt = &pSrvrStmt->stmt;
pOutputDesc = &pSrvrStmt->outputDesc;
pInputDesc = &pSrvrStmt->inputDesc;
if (!pSrvrStmt->isClosed)
{
retcode = CLI_CloseStmt(pStmt);
if (retcode!=0)
{
retcode = CLI_ClearDiagnostics(pStmt);
}
pSrvrStmt->isClosed = TRUE;
}
if (pSrvrStmt->holdability == HOLD_CURSORS_OVER_COMMIT)
{
retcode = CLI_SetStmtAttr(pStmt, SQL_ATTR_CURSOR_HOLDABLE, SQL_HOLDABLE, NULL);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
SQLDESC_ID sqlString_desc;
sqlString_desc.version = SQLCLI_ODBC_VERSION;
sqlString_desc.module = &pSrvrStmt->moduleId;
sqlString_desc.name_mode = string_data;
sqlString_desc.identifier = (const char *)pSrvrStmt->sqlString.dataValue._buffer;
sqlString_desc.handle = 0;
sqlString_desc.identifier_len = pSrvrStmt->sqlString.dataValue._length;
sqlString_desc.charset = SQLCHARSETSTRING_ISO88591;
retcode = CLI_Prepare(pStmt, &sqlString_desc);
int rtn;
#ifndef DISABLE_NOWAIT
if (retcode == NOWAIT_PENDING)
{
rtn = WaitForCompletion(pSrvrStmt, &pSrvrStmt->cond, &pSrvrStmt->mutex);
DEBUG_OUT(DEBUG_LEVEL_CLI,("WaitForCompletion() returned %d",rtn));
if (rtn == 0){
rc = pSrvrStmt->switchContext();
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->switchContext() returned %ld", rc));
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO)) THREAD_RETURN(pSrvrStmt,rc);
switch (pSrvrStmt->nowaitRetcode)
{
case 0:
retcode = 0;
break;
case 9999:
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
default:
retcode = GETSQLCODE(pSrvrStmt);
break;
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("pSrvrStmt->nowaitRetcode=%ld, retcode=%s",
pSrvrStmt->nowaitRetcode,
CliDebugSqlError(retcode)));
}
else
{
pSrvrStmt->nowaitRetcode = rtn;
THREAD_RETURN(pSrvrStmt,NOWAIT_ERROR);
}
}
#endif
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
// MFC - to store the original statement names to use in map
pSrvrStmt->estimatedCost = -1;
retcode = CLI_DescribeStmt(pStmt, pInputDesc, pOutputDesc);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pInputDesc,(int*) &pSrvrStmt->paramCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
retcode = CLI_GetDescEntryCount(pOutputDesc,(int *) &pSrvrStmt->columnCount);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
pSrvrStmt->prepareSetup();
InputDescInfo *pInputDescInfo = NULL;
if (pSrvrStmt->paramCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->inputDescList, pSrvrStmt->paramCount+pSrvrStmt->inputDescParamOffset);
pInputDescInfo = new InputDescInfo[pSrvrStmt->paramCount];
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Input,pInputDescInfo);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
else
{
kdsCreateEmptySQLDescSeq(&pSrvrStmt->inputDescList);
}
// MFC
// CLI_Prepare is over. Now create module definition file
// Dont create for Callable statements, the SQL String will begin with "{" for callable statements.
//CQDs filter -- start
//if(srvrGlobal->moduleCaching && pSrvrStmt->sqlString.dataValue._buffer[0] != '{')
if(srvrGlobal->moduleCaching && pSrvrStmt->isISUD)
{
struct stat checkMF;
int retCode;
std::string moduleFileName = srvrGlobal->compiledModuleLocation;
moduleFileName.append("/");
moduleFileName.append(pConnet->CurrentCatalog);
moduleFileName.append(".");
moduleFileName.append(pConnet->CurrentSchema);
moduleFileName.append(".");
moduleFileName.append(MFCKEY);
char *resMD5 = NULL;
resMD5 = MDMultiple2(pSrvrStmt->dialogueId,pSrvrStmt->sqlString.dataValue._buffer);
moduleFileName.append(resMD5);
//MFC If .lck already exists the module generation is in progress
std::string lockFile(moduleFileName);
lockFile.append(".lck");
retCode = stat(lockFile.c_str(), &checkMF);
if (retCode != 0 && pSrvrStmt->stmtType == EXTERNAL_STMT)
{
retCode = stat(moduleFileName.c_str(), &checkMF);
if(retCode != 0)
{
int fileDesc = open( lockFile.c_str(), O_RDONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IXUSR);
if (fileDesc >= 0 )
{
// MFC creation of .sql file nd then generating a .mdf and a module goes here
close(fileDesc);
CreateModulePlan(pSrvrStmt->paramCount, pInputDescInfo, pSrvrStmt->sqlString.dataValue._buffer,pSrvrStmt->dialogueId,resMD5);
}
}
}
if (resMD5 != NULL )
{
free(resMD5);
resMD5 = NULL;
}
}
//Soln. No.: 10-111229-1174 fix memory leak
MEMORY_DELETE_ARRAY(pInputDescInfo);
// MFC - resume normal flow if a .lck file exists
if (pSrvrStmt->columnCount > 0)
{
kdsCreateSQLDescSeq(&pSrvrStmt->outputDescList, pSrvrStmt->columnCount);
retcode = BuildSQLDesc(pSrvrStmt, SRVR_STMT_HDL::Output);
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
} else {
kdsCreateEmptySQLDescSeq(&pSrvrStmt->outputDescList);
}
/* *****************************************************************************
* The call to CLI_GetStmtAttr to query the statement type was added as a
* performance enhancement. Previous versions of the Trafodion database will not return
* a statement type, but will return a 0 which is SQL_OTHER. In the case were
* SQL_OTHER is returned and JDBC/MX knows what the statement type is, then the
* JDBC/MX statement type will be used. This will allow the JDBC/MX driver to
* run with an older version of the Trafodion.
* ***************************************************************************** */
DEBUG_OUT(DEBUG_LEVEL_CLI,( "getSQLMX_Version: returned %i", GlobalInformation::getSQLMX_Version()));
if (GlobalInformation::getSQLMX_Version() == CLI_VERSION_R2 ) { //If this version of Trafodion is version R2
if (pSrvrStmt->sqlStmtType != TYPE_UNKNOWN) //If this is a SELECT, INVOKE, or SHOWSHAPE
SqlQueryStatementType = SQL_SELECT_NON_UNIQUE; //then force an execute with no fetch
else SqlQueryStatementType = SQL_OTHER; //else allow an executeFetch
}
else
{
retcode = CLI_GetStmtAttr( &pSrvrStmt->stmt, // (IN) SQL statement ID
SQL_ATTR_QUERY_TYPE, // (IN) Request query statement attribute
&SqlQueryStatementType, // (OUT) Place to store query statement type
NULL, // (OUT) Optional string
0, // (IN) Max size of optional string buffer
NULL ); // (IN) Length of item
//If there is an error this statement will return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
}
DEBUG_OUT(DEBUG_LEVEL_CLI,("SQL Query Statement Type=%s",
CliDebugSqlQueryStatementType(SqlQueryStatementType)));
pSrvrStmt->setSqlQueryStatementType(SqlQueryStatementType);
switch (pSrvrStmt->getSqlQueryStatementType())
{
case SQL_CALL_NO_RESULT_SETS:
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("Prepare SQL_CALL_NO_RESULT_SETS query type"));
pSrvrStmt->isSPJRS = false; // Indicate this is an RS.
pSrvrStmt->RSIndex = 0; // Index into RS array
pSrvrStmt->RSMax = 0; // No Result Sets to return
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("RSMax: %d RSIndex: %d isSPJRS: %d ", pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS));
break;
case SQL_CALL_WITH_RESULT_SETS:
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("Prepare SQL_CALL_WITH_RESULT_SETS query type"));
pSrvrStmt->isSPJRS = true;
retcode = RSgetRSmax(pSrvrStmt);
DEBUG_OUT(DEBUG_LEVEL_CLI|DEBUG_LEVEL_STMT,("RSMax: %d RSIndex: %d isSPJRS: %d ", pSrvrStmt->RSMax, pSrvrStmt->RSIndex, pSrvrStmt->isSPJRS));
//If there is an error this statement will return
HANDLE_THREAD_ERROR(retcode, sqlWarning, pSrvrStmt);
break;
}
if (sqlWarning) THREAD_RETURN(pSrvrStmt,SQL_SUCCESS_WITH_INFO);
#endif
THREAD_RETURN(pSrvrStmt,SQL_SUCCESS);
}
// MFC
// Input Descriptor Info here for creating MDF file
InputDescInfo::InputDescInfo()
{
CountPosition = 0;
DataType = 0;
memset(DataTypeString, '\0', 50);
Length = 0;
DateTimeCode = 0;
Precision = 0;
SQLCharset = 0;
ODBCPrecision = 0;
ODBCDataType = 0;
Scale = 0;
Nullable = 0;
IntLeadPrec = 0;
}
InputDescInfo::~InputDescInfo()
{
CountPosition = 0;
DataType = 0;
memset(DataTypeString, '\0', 50);
Length = 0;
DateTimeCode = 0;
Precision = 0;
SQLCharset = 0;
ODBCPrecision = 0;
ODBCDataType = 0;
Nullable = 0;
Scale = 0;
IntLeadPrec =0;
}
// MFC - method to map JDBC data types to Trafodion data types
void InputDescInfo::setData(int countPosition, long dataType, long length, long scale,long nullable,
long dateTimeCode, long precision,long intLeadPrec, long sQLCharset, SRVR_GLOBAL_Def *srvrGlobal)
{
CountPosition = countPosition;
DataType = dataType;
Length = length;
DateTimeCode = dateTimeCode;
Precision = precision;
SQLCharset = sQLCharset;
Scale = scale;
Nullable = nullable;
IntLeadPrec = intLeadPrec;
switch (DataType)
{
case SQLTYPECODE_CHAR:
ODBCPrecision = Length;
ODBCDataType = SQL_CHAR;
strcpy(DataTypeString, "char");
break;
case SQLTYPECODE_VARCHAR:
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
ODBCPrecision = Length;
ODBCDataType = SQL_VARCHAR;
strcpy(DataTypeString, "VARCHAR");
if (Length >= 255)
{
ODBCDataType = SQL_LONGVARCHAR;
strcpy(DataTypeString, "VARCHAR");
}
break;
case SQLTYPECODE_VARCHAR_LONG:
ODBCPrecision = Length;
ODBCDataType = SQL_LONGVARCHAR;
strcpy(DataTypeString, "VARCHAR");
break;
case SQLTYPECODE_SMALLINT:
if (Precision == 0)
{
ODBCPrecision = 5;
ODBCDataType = SQL_SMALLINT;
strcpy(DataTypeString, "short");
}
else
{
ODBCPrecision = Precision;
ODBCDataType = SQL_NUMERIC;
strcpy(DataTypeString, "NUMERIC");
}
break;
case SQLTYPECODE_SMALLINT_UNSIGNED:
if (Precision == 0)
{
ODBCPrecision = 5;
ODBCDataType = SQL_SMALLINT;
strcpy(DataTypeString, "unsigned short");
}
else
{
ODBCPrecision = Precision;
ODBCDataType = SQL_NUMERIC;
strcpy(DataTypeString, "unsigned NUMERIC");
}
break;
case SQLTYPECODE_INTEGER:
if (Precision == 0)
{
ODBCPrecision = 10;
ODBCDataType = SQL_INTEGER;
strcpy(DataTypeString, "int");
}
else
{
ODBCPrecision = Precision;
ODBCDataType = SQL_NUMERIC;
strcpy(DataTypeString, "NUMERIC");
}
break;
case SQLTYPECODE_INTEGER_UNSIGNED:
if (Precision == 0)
{
ODBCPrecision = 10;
ODBCDataType = SQL_INTEGER;
strcpy(DataTypeString, "unsigned int");
}
else
{
ODBCPrecision = Precision;
ODBCDataType = SQL_NUMERIC;
strcpy(DataTypeString, "unsigned NUMERIC");
}
break;
case SQLTYPECODE_LARGEINT:
if (Precision == 0)
{
ODBCPrecision = 19;
ODBCDataType = SQL_BIGINT;
strcpy(DataTypeString, "long long");
}
else
{
ODBCPrecision = Precision;
ODBCDataType = SQL_NUMERIC;
strcpy(DataTypeString, "NUMERIC");
}
break;
case SQLTYPECODE_IEEE_REAL:
case SQLTYPECODE_TDM_REAL:
ODBCDataType = SQL_REAL;
ODBCPrecision = 7;
strcpy(DataTypeString, "float");
break;
case SQLTYPECODE_IEEE_DOUBLE:
case SQLTYPECODE_TDM_DOUBLE:
ODBCDataType = SQL_DOUBLE;
ODBCPrecision = 15;
strcpy(DataTypeString, "double");
break;
case SQLTYPECODE_DATETIME:
switch (DateTimeCode)
{
case SQLDTCODE_DATE: //1
ODBCDataType = SQL_DATE;
ODBCPrecision = 10;
strcpy(DataTypeString, "DATE");
break;
case SQLDTCODE_TIME: //2
ODBCDataType = SQL_TIME;
strcpy(DataTypeString, "TIME");
if (Precision == 0)
{
ODBCPrecision = 8;
}
else
{
ODBCDataType = SQL_TIMESTAMP;
ODBCPrecision = 20+Precision;
strcpy(DataTypeString, "TIMESTAMP");
}
break;
case SQLDTCODE_TIMESTAMP: //3
ODBCDataType = SQL_TIMESTAMP;
strcpy(DataTypeString, "TIMESTAMP");
if (Precision == 0)
{
ODBCPrecision = 19;
}
else
{
ODBCPrecision = 20+Precision;
}
break;
//
// Mapping Non-standard SQL/MP DATETIME types to DATE/TIME/TIMESTAMP
//
default:
ODBCDataType = SQL_TYPE_NULL;
ODBCPrecision = 0;
strcpy(DataTypeString, "SQL_TYPE_NULL");
break;
} // switch datetime ends
break;
case SQLTYPECODE_DECIMAL_UNSIGNED:
ODBCPrecision = Length;
ODBCDataType = SQL_DECIMAL;
strcpy(DataTypeString, "unsigned DECIMAL");
break;
case SQLTYPECODE_DECIMAL:
ODBCPrecision = Length;
ODBCDataType = SQL_DECIMAL;
strcpy(DataTypeString, "DECIMAL");
break;
case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: // Tandem extension
ODBCDataType = SQL_DOUBLE; // Since there is no corresponding JDBC DataType, Map it as a double
ODBCPrecision = 15;
strcpy(DataTypeString, "double");
break;
case SQLTYPECODE_DECIMAL_LARGE: // Tandem extension
ODBCDataType = SQL_DOUBLE; // Since there is no corresponding JDBC DataType, Map it as a double
ODBCPrecision = 15;
strcpy(DataTypeString, "double");
break;
case SQLTYPECODE_INTERVAL: // Interval will be sent in ANSIVARCHAR format
switch (DateTimeCode)
{
case SQLINTCODE_YEAR:
ODBCDataType = SQL_INTERVAL_YEAR;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL YEAR");
break;
case SQLINTCODE_MONTH:
ODBCDataType = SQL_INTERVAL_MONTH;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL MONTH");
break;
case SQLINTCODE_DAY:
ODBCDataType = SQL_INTERVAL_DAY;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL DAY");
break;
case SQLINTCODE_HOUR:
ODBCDataType = SQL_INTERVAL_HOUR;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL HOUR");
break;
case SQLINTCODE_MINUTE:
ODBCDataType = SQL_INTERVAL_MINUTE;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL MINUTE");
break;
case SQLINTCODE_SECOND:
ODBCDataType = SQL_INTERVAL_SECOND;
ODBCPrecision = Precision;
strcpy(DataTypeString, "INTERVAL SECOND");
break;
case SQLINTCODE_YEAR_MONTH:
ODBCDataType = SQL_INTERVAL_YEAR_TO_MONTH;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL YEAR TO MONTH");
break;
case SQLINTCODE_DAY_HOUR:
ODBCDataType = SQL_INTERVAL_DAY_TO_HOUR;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL DAY TO HOUR");
break;
case SQLINTCODE_DAY_MINUTE:
ODBCDataType = SQL_INTERVAL_DAY_TO_MINUTE;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL DAY TO MINUTE");
break;
case SQLINTCODE_DAY_SECOND:
ODBCDataType = SQL_INTERVAL_DAY_TO_SECOND;
ODBCPrecision = Precision;
strcpy(DataTypeString, "INTERVAL DAY TO SECOND");
break;
case SQLINTCODE_HOUR_MINUTE:
ODBCDataType = SQL_INTERVAL_HOUR_TO_MINUTE;
ODBCPrecision = 0;
strcpy(DataTypeString, "INTERVAL HOUR TO MINUTE");
break;
case SQLINTCODE_HOUR_SECOND:
ODBCDataType = SQL_INTERVAL_HOUR_TO_SECOND;
ODBCPrecision = Precision;
strcpy(DataTypeString, "INTERVAL HOUR TO SECOND");
break;
case SQLINTCODE_MINUTE_SECOND:
ODBCDataType = SQL_INTERVAL_MINUTE_TO_SECOND;
ODBCPrecision = Precision;
strcpy(DataTypeString, "INTERVAL MINUTE TO SECOND");
break;
default:
ODBCDataType = SQL_TYPE_NULL;
ODBCPrecision = 0;
strcpy(DataTypeString, "SQL_TYPE_NULL");
break;
}
break;
case SQLTYPECODE_CLOB:
ODBCPrecision = Length;
ODBCDataType = TYPE_CLOB;
strcpy(DataTypeString, "CLOB");
break;
case SQLTYPECODE_BLOB:
ODBCPrecision = Length;
ODBCDataType = TYPE_BLOB;
strcpy(DataTypeString, "BLOB");
break;
default:
ODBCDataType = SQL_TYPE_NULL;
ODBCPrecision = 0;
strcpy(DataTypeString, "SQL_TYPE_NULL");
break;
}
}
// MFC BuildDesc and return InputDescInfo
SQLRETURN BuildSQLDesc(SRVR_STMT_HDL*pSrvrStmt, SRVR_STMT_HDL::DESC_TYPE descType,InputDescInfo *pInputDescInfo)
{
FUNCTION_ENTRY("BuildSQLDesc", ("pSrvrStmt=0x%08x, pSrvrStmt->stmtName = %s, SQL Statement = %s, descType=%s",
pSrvrStmt,
pSrvrStmt->stmtName,
pSrvrStmt->sqlString.dataValue._buffer,
CliDebugDescTypeStr(descType)));
long retcode = SQL_SUCCESS;
short i;
short j;
short k;
BOOL sqlWarning = FALSE;
long *totalMemLen = pSrvrStmt->getDescBufferLenPtr(descType);
long numEntries = pSrvrStmt->getDescEntryCount(descType);
SQLDESC_ID *pDesc = pSrvrStmt->getDesc(descType);
SQLItemDescList_def *SQLDesc = pSrvrStmt->getDescList(descType);
SQLItemDesc_def *SQLItemDesc = (SQLItemDesc_def *)SQLDesc->_buffer + SQLDesc->_length;
SRVR_DESC_HDL *implDesc = pSrvrStmt->allocImplDesc(descType);
// The following routine is hard coded for at least 15 items, so make sure it does not change
DEBUG_ASSERT(NO_OF_DESC_ITEMS>= 16,("NO_OF_DESC_ITEMS(%d) is less than 16",NO_OF_DESC_ITEMS));
*totalMemLen = 0;
for (i = 0; i < numEntries; i++) {
SQLItemDesc = (SQLItemDesc_def *)SQLDesc->_buffer + SQLDesc->_length;
// Initialize the desc entry in SQLDESC_ITEM struct
for (j = 0; j < NO_OF_DESC_ITEMS ; j++) {
gDescItems[j].entry = i+1;
}
gDescItems[10].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[11].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[12].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[13].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[14].num_val_or_len = MAX_ANSI_NAME_LEN+1;
retcode = CLI_GetDescItems2(pDesc,
NO_OF_DESC_ITEMS,
(SQLDESC_ITEM *)&gDescItems);
HANDLE_ERROR(retcode, sqlWarning);
SQLItemDesc->dataType = gDescItems[0].num_val_or_len;
SQLItemDesc->maxLen = gDescItems[1].num_val_or_len;
SQLItemDesc->precision = (short)gDescItems[2].num_val_or_len;
SQLItemDesc->scale = (short)gDescItems[3].num_val_or_len;
SQLItemDesc->nullInfo = (BOOL)gDescItems[4].num_val_or_len;
SQLItemDesc->paramMode = gDescItems[5].num_val_or_len;
SQLItemDesc->intLeadPrec = gDescItems[6].num_val_or_len;
SQLItemDesc->datetimeCode = gDescItems[7].num_val_or_len;
SQLItemDesc->SQLCharset = gDescItems[8].num_val_or_len;
SQLItemDesc->fsDataType = gDescItems[9].num_val_or_len;
for (k = 10; k < 15; k++) {
gDescItems[k].string_val[gDescItems[k].num_val_or_len] = '\0';
}
SQLItemDesc->vc_ind_length = gDescItems[15].num_val_or_len;
SQLItemDesc->maxLen = AdjustCharLength(descType, SQLItemDesc->SQLCharset, SQLItemDesc->maxLen);
GetJDBCValues( SQLItemDesc, // Input
*totalMemLen,
gDescItems[14].string_val);
implDesc[i].charSet = SQLItemDesc->SQLCharset;
implDesc[i].dataType = SQLItemDesc->dataType;
implDesc[i].length = SQLItemDesc->maxLen;
implDesc[i].precision = SQLItemDesc->ODBCPrecision;
implDesc[i].scale = SQLItemDesc->scale;
implDesc[i].sqlDatetimeCode = SQLItemDesc->datetimeCode;
implDesc[i].FSDataType = SQLItemDesc->fsDataType;
implDesc[i].paramMode = SQLItemDesc->paramMode;
implDesc[i].vc_ind_length = SQLItemDesc->vc_ind_length;
SQLItemDesc->version = 0;
strcpy(SQLItemDesc->catalogNm, gDescItems[10].string_val);
strcpy(SQLItemDesc->schemaNm, gDescItems[11].string_val);
strcpy(SQLItemDesc->tableNm, gDescItems[12].string_val);
strcpy(SQLItemDesc->colNm, gDescItems[13].string_val);
strcpy(SQLItemDesc->colLabel, gDescItems[14].string_val);
SQLDesc->_length++;
}
if ((srvrGlobal->moduleCaching) &&(descType == SRVR_STMT_HDL::Input)&& (pSrvrStmt->stmtType == EXTERNAL_STMT))
{
retcode = BuildSQLDesc2ForModFile(pSrvrStmt->inputDesc, pSrvrStmt->paramCount, pInputDescInfo);
HANDLE_ERROR(retcode, sqlWarning);
}
retcode = SET_DATA_PTR(pSrvrStmt, descType);
HANDLE_ERROR(retcode, sqlWarning);
if (sqlWarning) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS_WITH_INFO);
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
//MFC - Build input descriptors for module file generation
SQLRETURN BuildSQLDesc2ForModFile(SQLDESC_ID pDesc,long numEntries,InputDescInfo *&pInputDescInfo)
{
long retcode = SQL_SUCCESS;
BOOL sqlWarning = FALSE;
long DataType;
long DateTimeCode;
long Length;
long Precision;
long Scale;
long SQLCharset;
long FSDataType;
long IntLeadPrec;
long Nullable;
for (int i = 0; i < numEntries; i++)
{
// Initialize the desc entry in SQLDESC_ITEM struct
for (int j = 0; j < NO_OF_DESC_ITEMS ; j++)
{
gDescItems[j].entry = i+1;
}
gDescItems[10].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[11].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[12].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[13].num_val_or_len = MAX_ANSI_NAME_LEN+1;
gDescItems[14].num_val_or_len = MAX_ANSI_NAME_LEN+1;
retcode = CLI_GetDescItems2(&pDesc,
NO_OF_DESC_ITEMS,
(SQLDESC_ITEM *)&gDescItems);
DataType = gDescItems[0].num_val_or_len;
Length = gDescItems[1].num_val_or_len;
Precision = gDescItems[2].num_val_or_len;
Scale = gDescItems[3].num_val_or_len;
Nullable = gDescItems[4].num_val_or_len;
DateTimeCode = gDescItems[7].num_val_or_len;
SQLCharset = gDescItems[8].num_val_or_len;
FSDataType = gDescItems[9].num_val_or_len;
IntLeadPrec = gDescItems[6].num_val_or_len;
for (int k = 10; k < NO_OF_DESC_ITEMS; k++) {
gDescItems[k].string_val[gDescItems[k].num_val_or_len] = '\0';
}
if (DataType == SQLTYPECODE_NUMERIC || DataType == SQLTYPECODE_NUMERIC_UNSIGNED)
{
switch (FSDataType)
{
case 130:
DataType = SQLTYPECODE_SMALLINT;
break;
case 131:
DataType = SQLTYPECODE_SMALLINT_UNSIGNED;
break;
case 132:
case 156: //MFC support for BigNum
DataType = SQLTYPECODE_INTEGER;
break;
case 133:
case 155: //MFC support for BigNum
DataType = SQLTYPECODE_INTEGER_UNSIGNED;
break;
case 134:
DataType = SQLTYPECODE_LARGEINT;
break;
default:
break;
}
}
pInputDescInfo[i].setData(i, DataType, Length,Scale,Nullable, DateTimeCode, Precision,IntLeadPrec,SQLCharset, srvrGlobal);
}
if (sqlWarning)
{
return SQL_SUCCESS_WITH_INFO;
}
else
{
return SQL_SUCCESS;
}
}
// MFC method to create the module file and store it on disk
void CreateModulePlan(long inputParamCount, InputDescInfo *inputDescInfo, char *inputsqlString,long dialogueId,const char *resMD5)
{
SRVR_CONNECT_HDL *pConnect = (SRVR_CONNECT_HDL *)dialogueId;
FILE *ModuleCachingFile = NULL;
int containDecimal = false;
char temp_Str[256];
memset(temp_Str, '\0', 256);
char temp_Param[20];
memset(temp_Param, '\0', 20);
int noOfParam = inputParamCount - 1;
std::string ModuleName;
bool *indparam = new bool[inputParamCount];
memset(indparam, false, inputParamCount);
ModuleName.append(pConnect->CurrentCatalog);
ModuleName.append(".");
ModuleName.append(pConnect->CurrentSchema);
ModuleName.append(".");
ModuleName.append(MFCKEY);
ModuleName.append(resMD5);
std::string ModCachfilename;
ModCachfilename.append(srvrGlobal->compiledModuleLocation);
ModCachfilename.append("/");
ModCachfilename.append(ModuleName);
ModCachfilename.append(".sql");
// Open the module file
ModuleCachingFile = fopen(ModCachfilename.c_str(),"wt");
fprintf(ModuleCachingFile,"#if(0)\n%s \n#endif \n\n", inputsqlString);
fprintf(ModuleCachingFile,"# include<stdio.h>\n\n");
fprintf(ModuleCachingFile,"EXEC SQL MODULE %s NAMES ARE ISO88591;\n",ModuleName.c_str());
fprintf(ModuleCachingFile,"int main ()\n");
fprintf(ModuleCachingFile,"{\n");
fprintf(ModuleCachingFile," EXEC SQL BEGIN DECLARE SECTION;\n");
//Declare variables for every input
for (int pcount = 0; pcount < inputParamCount; pcount++)
{
switch(inputDescInfo[pcount].DataType)
{
case SQLTYPECODE_CHAR:
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
break;
case SQLTYPECODE_VARCHAR:
if (inputDescInfo[pcount].Length >= 255)
{
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
if (inputDescInfo[pcount].Length >= 255)
{
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_VARCHAR_LONG:
{
fprintf(ModuleCachingFile, "%s param%d[%d];\n",inputDescInfo[pcount].DataTypeString, pcount, (inputDescInfo[pcount].Length)+1);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_SMALLINT:
if (inputDescInfo[pcount].Precision == 0)
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_LARGEINT:
if (inputDescInfo[pcount].Precision == 0)
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_SMALLINT_UNSIGNED:
if (inputDescInfo[pcount].Precision == 0)
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_INTEGER:
if (inputDescInfo[pcount].Precision == 0)
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_INTEGER_UNSIGNED:
if (inputDescInfo[pcount].Precision == 0)
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
else
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_IEEE_FLOAT:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_IEEE_DOUBLE:
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_DATETIME:
switch (inputDescInfo[pcount].DateTimeCode)
{
case SQLDTCODE_DATE: //1
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLDTCODE_TIME: //2
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
if (inputDescInfo[pcount].Precision == 0)
{
//ODBCPrecision = 8;
}
else
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLDTCODE_TIMESTAMP: //3
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Precision, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
if (inputDescInfo[pcount].Precision == 0)
{
//ODBCPrecision = 19;
}
else
{
//ODBCPrecision = 20+Precision;
}
break;
default:
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
}
break;
case SQLTYPECODE_DECIMAL_UNSIGNED:
{
containDecimal = true;
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Length,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_DECIMAL:
{
containDecimal = true;
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].Length,inputDescInfo[pcount].Scale,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED: // Tandem extension
{
containDecimal = true;
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_DECIMAL_LARGE: // Tandem extension
{
containDecimal = true;
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLTYPECODE_INTERVAL: // Interval will be sent in ANSIVARCHAR format
switch (inputDescInfo[pcount].DateTimeCode)
{
case SQLINTCODE_YEAR:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_MONTH:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_DAY:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_HOUR:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_MINUTE:
{
fprintf(ModuleCachingFile, "%s(%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_SECOND:
{
fprintf(ModuleCachingFile, "%s(%d,%d) param%d;\n",inputDescInfo[pcount].DataTypeString,inputDescInfo[pcount].IntLeadPrec,inputDescInfo[pcount].Precision,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_YEAR_MONTH:
{
fprintf(ModuleCachingFile, "INTERVAL YEAR(%d) TO MONTH param%d;\n", inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_DAY_HOUR:
{
fprintf(ModuleCachingFile, "INTERVAL DAY(%d) TO HOUR param%d;\n", inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_DAY_MINUTE:
{
fprintf(ModuleCachingFile, "INTERVAL DAY(%d) TO MINUTE param%d;\n", inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_DAY_SECOND:
{
fprintf(ModuleCachingFile, "INTERVAL DAY(%d) TO SECOND(%d) param%d;\n", inputDescInfo[pcount].IntLeadPrec,inputDescInfo[pcount].Precision,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_HOUR_MINUTE:
{
fprintf(ModuleCachingFile, "INTERVAL HOUR(%d) TO MINUTE param%d;\n", inputDescInfo[pcount].IntLeadPrec,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_HOUR_SECOND:
{
fprintf(ModuleCachingFile, "INTERVAL HOUR(%d) TO SECOND(%d) param%d;\n", inputDescInfo[pcount].IntLeadPrec,inputDescInfo[pcount].Precision,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
case SQLINTCODE_MINUTE_SECOND:
{
fprintf(ModuleCachingFile, "INTERVAL MINUTE(%d) TO SECOND(%d) param%d;\n", inputDescInfo[pcount].IntLeadPrec,inputDescInfo[pcount].Precision,pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
default:
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
}
// Calculate the length based on Precision and IntLeadPrec
// The max. length is for Day to Fraction(6)
// Sign = 1
// Day = IntLeadPrec + 1 ( 1 for Blank space)
// Hour = 3 ( 2+1)
// Minute = 3 (2+1)
// Seconds = 3 (2+1)
// Fraction = Precision
break;
default:
{
fprintf(ModuleCachingFile, "%s param%d;\n",inputDescInfo[pcount].DataTypeString, pcount);
if(inputDescInfo[pcount].Nullable)
{
indparam[pcount] = true;
fprintf(ModuleCachingFile,"short param%d_ind = -1;\n",pcount);
}
}
break;
}
}
fprintf(ModuleCachingFile,"EXEC SQL END DECLARE SECTION ;\n");
SRVR_CONNECT_HDL *connectHandle =(SRVR_CONNECT_HDL*)dialogueId;
std::list<std::string>::iterator iter;
for( iter = connectHandle->listOfCQDs.begin(); iter != connectHandle->listOfCQDs.end(); ++iter)
{
fprintf(ModuleCachingFile,"EXEC SQL %s;\n", iter->c_str());
}
if(strcmp(pConnect->CurrentSchema, "SEABASE") != 0 && strcmp(srvrGlobal->CurrentCatalog, "TRAFODION") != 0)
{
fprintf(ModuleCachingFile,"EXEC SQL DECLARE SCHEMA %s.%s ; \n",srvrGlobal->CurrentCatalog,srvrGlobal->CurrentSchema);
fprintf(ModuleCachingFile,"EXEC SQL SET SCHEMA %s.%s ; \n", srvrGlobal->CurrentCatalog,srvrGlobal->CurrentSchema);
}
std::string inputstring = inputsqlString;
std::string strParam = ":param";
std::string _inputstring = inputsqlString;
char* tempsqlstr = (char*)malloc(strlen(inputsqlString) +1);
memset(tempsqlstr, '\0', strlen(inputsqlString) +1);
strcpy(tempsqlstr, inputsqlString);
strToUpper(tempsqlstr);
char *saveptr=NULL;
char *sqlType = strtok_r(tempsqlstr," \t\n",&saveptr);
int pos = -1;
// This is becuase we need the indicator variables declared for Insert,Update & Delete kind of statements
while(inputstring.rfind("?",pos) != -1 && noOfParam >= 0)
{
memset(temp_Param, '\0', 20);
pos = inputstring.rfind("?",pos);
sprintf(temp_Param, "%d", noOfParam);
strParam.append(temp_Param);
if(indparam[noOfParam])
{
strParam.append(" :");
strParam.append("param");
strParam.append(temp_Param);
strParam.append("_ind ");
}
_inputstring.replace(inputstring.rfind("?",pos), 1, strParam);
strParam = ":param";
noOfParam--;
pos--;
}
inputstring = _inputstring;
delete [] indparam;
if(sqlType != NULL && strcmp(sqlType, "SELECT") == 0 )
{
fprintf(ModuleCachingFile,"EXEC SQL DECLARE MXSTMT01 CURSOR FOR %s ;\n",inputstring.c_str());
}
else
{
fprintf(ModuleCachingFile,"EXEC SQL %s ;\n",inputstring.c_str());
}
fprintf(ModuleCachingFile,"return 0; \n }\n");
fclose(ModuleCachingFile);
if( tempsqlstr != NULL )
{
free(tempsqlstr);
tempsqlstr = NULL;
}
std::string strModuleFileName = std::string(ModCachfilename).substr(0, std::string(ModCachfilename).find(".sql"));
std::string string_Command;
int exeret = -1;
string_Command.append("/usr/tandem/sqlmx/bin/mxsqlc ");
string_Command.append(strModuleFileName.c_str());
string_Command.append(".sql -m ");
string_Command.append(strModuleFileName.c_str());
string_Command.append(".mdf -t 1234567890 -a -o");
#ifdef _LP64
string_Command.append(" -U 64");
/* #else
string_Command.append(" -U 32");
*/
#endif
//Solution 10-090915-4598 -- start
string_Command.append(" > ");
string_Command.append(strModuleFileName.c_str());
string_Command.append(".err 2>&1");
//Solution 10-090915-4598 -- end
// Workaround for Solution 10-121212-5698
// In system() the child process is unable to access the memory location where command string is located
// 1) explicitly allocated memory on heap
// 2) copy the command string to newly allocated heap memory
// 3) pass that string to system()
//int exeret = system(string_Command.c_str());
char* temp_cmd = (char*)malloc(string_Command.length() + 1);
if( temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_Command.length() +1 );
strncpy(temp_cmd, string_Command.c_str(), string_Command.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
if(exeret == 0 && containDecimal == true)
{
std::string string_ReplaceDecimal;
string_ReplaceDecimal.append("/bin/sed -e 's/LSDECIMAL/DECIMAL/g' ");
string_ReplaceDecimal.append(strModuleFileName);
string_ReplaceDecimal.append(".mdf > ");
string_ReplaceDecimal.append(strModuleFileName);
string_ReplaceDecimal.append(".mdfc");
// Workaround for Solution 10-121212-5698
//exeret = system(string_ReplaceDecimal.c_str());
char* temp_cmd = (char*)malloc(string_ReplaceDecimal.length() + 1);
if(temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_ReplaceDecimal.length() +1 );
strncpy(temp_cmd, string_ReplaceDecimal.c_str(), string_ReplaceDecimal.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
if(exeret == 0)
{
string_ReplaceDecimal.erase();
string_ReplaceDecimal.append("mv -f ");
string_ReplaceDecimal.append(strModuleFileName);
string_ReplaceDecimal.append(".mdfc ");
string_ReplaceDecimal.append(strModuleFileName);
string_ReplaceDecimal.append(".mdf");
// Workaround for Solution 10-121212-5698
//exeret = system(string_ReplaceDecimal.c_str());
char* temp_cmd = (char*)malloc(string_ReplaceDecimal.length() + 1);
if(temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_ReplaceDecimal.length() +1 );
strncpy(temp_cmd, string_ReplaceDecimal.c_str(), string_ReplaceDecimal.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
}
}
std::string string_Script;
if(exeret == 0)
{
string_Script.append("/G/SYSTEM/SYSTEM/mxcmp -g moduleLocal=");
string_Script.append(srvrGlobal->compiledModuleLocation);
string_Script.append(" ");
string_Script.append(strModuleFileName);
string_Script.append(".mdf");
//Solution 10-090915-4598 -- start
string_Script.append(" > ");
string_Script.append(strModuleFileName);
string_Script.append(".err 2>&1");
//Solution 10-090915-4598 -- end
// Workaround for Solution 10-121212-5698
//exeret = system(string_Script.c_str());
char* temp_cmd = (char*)malloc(string_Script.length() + 1);
if(temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_Script.length() +1 );
strncpy(temp_cmd, string_Script.c_str(), string_Script.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
}
std::string string_Script2;
if(exeret == 0)
{
string_Script2.append("rm -f ");
string_Script2.append(strModuleFileName);
string_Script2.append(".lck ");
string_Script2.append(strModuleFileName);
string_Script2.append(".c ");
/* string_Script2.append(strModuleFileName);
string_Script2.append(".lst ");*/
string_Script2.append(strModuleFileName);
string_Script2.append(".dep ");
//Solution 10-090915-4598 -- start
string_Script2.append(strModuleFileName);
string_Script2.append(".err ");
// Workaround for Solution 10-121212-5698
//exeret = system(string_Script2.c_str());
char* temp_cmd = (char*)malloc(string_Script2.length() + 1);
if(temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_Script2.length() +1 );
strncpy(temp_cmd, string_Script2.c_str(), string_Script2.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
}
else
{
string_Script2.append("rm -f ");
string_Script2.append(strModuleFileName);
string_Script2.append(".c ");
/* string_Script2.append(strModuleFileName);
string_Script2.append(".lst ");
*/
string_Script2.append(strModuleFileName);
string_Script2.append(".dep ");
/* string_Script2.append(strModuleFileName);
string_Script2.append(".sql");
*/
// Workaround for Solution 10-121212-5698
//exeret = system(string_Script2.c_str());
char* temp_cmd = (char*)malloc(string_Script2.length() + 1);
if(temp_cmd != NULL)
{
memset(temp_cmd, '\0', string_Script2.length() +1 );
strncpy(temp_cmd, string_Script2.c_str(), string_Script2.length() );
exeret = system(temp_cmd);
free(temp_cmd);
temp_cmd = NULL;
}
}
}
SQLRETURN COMMIT_ROWSET(long dialogueId, bool& bSQLMessageSet, odbc_SQLSvc_SQLError* SQLError, Int32 currentRowCount)
{
SQLRETURN retcode;
long sqlcode;
SQLValueList_def inValueList;
inValueList._buffer = NULL;
inValueList._length = 0;
SRVR_STMT_HDL *CmwSrvrStmt = getInternalSrvrStmt(dialogueId, "STMT_COMMIT_1", &sqlcode);
/* Should process the error here if CmwSrvrStmt is NULL */
if(!CmwSrvrStmt || sqlcode == SQL_INVALID_HANDLE)
{
kdsCreateSQLErrorException(SQLError, 1, bSQLMessageSet);
kdsCopySQLErrorExceptionAndRowCount(SQLError,
"Internal Error: From Commit Rowsets, getInternalSrvrStmt() failed to get the prepared \"STMT_COMMIT_1\" statement",
sqlcode,
"HY000",
currentRowCount+1);
}
// This should be changed to use the rowsets Execute() function once the code is checked in
retcode = CmwSrvrStmt->Execute(NULL,1,TYPE_UNKNOWN,&inValueList,SQL_ASYNC_ENABLE_OFF,0, /* */NULL);
if (retcode == SQL_ERROR)
{
ERROR_DESC_def *error_desc_def = CmwSrvrStmt->sqlError.errorList._buffer;
if (CmwSrvrStmt->sqlError.errorList._length != 0 )
{
if(error_desc_def->sqlcode != -8605 )
{
kdsCreateSQLErrorException(SQLError, 1, bSQLMessageSet);
kdsCopySQLErrorExceptionAndRowCount(SQLError, error_desc_def->errorText, error_desc_def->sqlcode, error_desc_def->sqlstate, currentRowCount+1);
}
else
retcode = SQL_SUCCESS;
}
else
{
kdsCreateSQLErrorException(SQLError, 1, bSQLMessageSet);
kdsCopySQLErrorExceptionAndRowCount(SQLError, "Internal Error: From Commit Rowsets ", retcode, "", currentRowCount+1);
}
}
else if (retcode != SQL_SUCCESS)
{
kdsCreateSQLErrorException(SQLError, 1, bSQLMessageSet);
kdsCopySQLErrorExceptionAndRowCount(SQLError, "Internal Error: From Commit Rowsets ", retcode, "", currentRowCount+1);
}
return retcode;
}