代码拉取完成,页面将自动刷新
同步操作将从 openGauss/openGauss-connector-odbc 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*-------
* Module: pgapi30.c
*
* Description: This module contains routines related to ODBC 3.0
* most of their implementations are temporary
* and must be rewritten properly.
* 2001/07/23 inoue
*
* Classes: n/a
*
* API functions: PGAPI_ColAttribute, PGAPI_GetDiagRec,
PGAPI_GetConnectAttr, PGAPI_GetStmtAttr,
PGAPI_SetConnectAttr, PGAPI_SetStmtAttr
*-------
*/
#include "psqlodbc.h"
#include "misc.h"
#include <stdio.h>
#include <string.h>
#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "descriptor.h"
#include "qresult.h"
#include "pgapifunc.h"
#include "loadlib.h"
#include "dlg_specific.h"
/* SQLError -> SQLDiagRec */
RETCODE SQL_API
PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
SQLINTEGER *NativeError, SQLCHAR *MessageText,
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
{
RETCODE ret;
MYLOG(0, "entering type=%d rec=%d\n", HandleType, RecNumber);
switch (HandleType)
{
case SQL_HANDLE_ENV:
ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate,
NativeError, MessageText,
BufferLength, TextLength, 0);
break;
case SQL_HANDLE_DBC:
ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate,
NativeError, MessageText, BufferLength,
TextLength, 0);
break;
case SQL_HANDLE_STMT:
ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate,
NativeError, MessageText, BufferLength,
TextLength, 0);
break;
case SQL_HANDLE_DESC:
ret = PGAPI_DescError(Handle, RecNumber, Sqlstate,
NativeError,
MessageText, BufferLength,
TextLength, 0);
break;
default:
ret = SQL_ERROR;
}
MYLOG(0, "leaving %d\n", ret);
return ret;
}
/*
* Minimal implementation.
*
*/
RETCODE SQL_API
PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
PTR DiagInfoPtr, SQLSMALLINT BufferLength,
SQLSMALLINT *StringLengthPtr)
{
RETCODE ret = SQL_ERROR, rtn;
ConnectionClass *conn;
StatementClass *stmt;
SQLLEN rc;
SQLSMALLINT pcbErrm;
ssize_t rtnlen = -1;
int rtnctype = SQL_C_CHAR;
MYLOG(0, "entering rec=%d\n", RecNumber);
switch (HandleType)
{
case SQL_HANDLE_ENV:
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
case SQL_DIAG_SERVER_NAME:
rtnlen = 0;
if (DiagInfoPtr && BufferLength > rtnlen)
{
ret = SQL_SUCCESS;
*((char *) DiagInfoPtr) = '\0';
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_MESSAGE_TEXT:
ret = PGAPI_EnvError(Handle, RecNumber,
NULL, NULL, DiagInfoPtr,
BufferLength, StringLengthPtr, 0);
break;
case SQL_DIAG_NATIVE:
rtnctype = SQL_C_LONG;
ret = PGAPI_EnvError(Handle, RecNumber,
NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
0, NULL, 0);
break;
case SQL_DIAG_NUMBER:
rtnctype = SQL_C_LONG;
ret = PGAPI_EnvError(Handle, RecNumber,
NULL, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCEEDED(ret))
{
*((SQLINTEGER *) DiagInfoPtr) = 1;
}
break;
case SQL_DIAG_SQLSTATE:
rtnlen = 5;
ret = PGAPI_EnvError(Handle, RecNumber,
DiagInfoPtr, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCESS_WITH_INFO == ret)
ret = SQL_SUCCESS;
break;
case SQL_DIAG_RETURNCODE: /* driver manager returns */
break;
case SQL_DIAG_CURSOR_ROW_COUNT:
case SQL_DIAG_ROW_COUNT:
case SQL_DIAG_DYNAMIC_FUNCTION:
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
/* options for statement type only */
break;
}
break;
case SQL_HANDLE_DBC:
conn = (ConnectionClass *) Handle;
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
rtnlen = 0;
if (DiagInfoPtr && BufferLength > rtnlen)
{
ret = SQL_SUCCESS;
*((char *) DiagInfoPtr) = '\0';
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_SERVER_NAME:
rtnlen = strlen(CC_get_DSN(conn));
if (DiagInfoPtr)
{
strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_MESSAGE_TEXT:
ret = PGAPI_ConnectError(Handle, RecNumber,
NULL, NULL, DiagInfoPtr,
BufferLength, StringLengthPtr, 0);
break;
case SQL_DIAG_NATIVE:
rtnctype = SQL_C_LONG;
ret = PGAPI_ConnectError(Handle, RecNumber,
NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
0, NULL, 0);
break;
case SQL_DIAG_NUMBER:
rtnctype = SQL_C_LONG;
ret = PGAPI_ConnectError(Handle, RecNumber,
NULL, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCEEDED(ret))
{
*((SQLINTEGER *) DiagInfoPtr) = 1;
}
break;
case SQL_DIAG_SQLSTATE:
rtnlen = 5;
ret = PGAPI_ConnectError(Handle, RecNumber,
DiagInfoPtr, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCESS_WITH_INFO == ret)
ret = SQL_SUCCESS;
break;
case SQL_DIAG_RETURNCODE: /* driver manager returns */
break;
case SQL_DIAG_CURSOR_ROW_COUNT:
case SQL_DIAG_ROW_COUNT:
case SQL_DIAG_DYNAMIC_FUNCTION:
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
/* options for statement type only */
break;
}
break;
case SQL_HANDLE_STMT:
conn = (ConnectionClass *) SC_get_conn(((StatementClass *) Handle));
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
rtnlen = 0;
if (DiagInfoPtr && BufferLength > rtnlen)
{
ret = SQL_SUCCESS;
*((char *) DiagInfoPtr) = '\0';
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_SERVER_NAME:
rtnlen = strlen(CC_get_DSN(conn));
if (DiagInfoPtr)
{
strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_MESSAGE_TEXT:
ret = PGAPI_StmtError(Handle, RecNumber,
NULL, NULL, DiagInfoPtr,
BufferLength, StringLengthPtr, 0);
break;
case SQL_DIAG_NATIVE:
rtnctype = SQL_C_LONG;
ret = PGAPI_StmtError(Handle, RecNumber,
NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
0, NULL, 0);
break;
case SQL_DIAG_NUMBER:
rtnctype = SQL_C_LONG;
*((SQLINTEGER *) DiagInfoPtr) = 0;
ret = SQL_NO_DATA_FOUND;
stmt = (StatementClass *) Handle;
rtn = PGAPI_StmtError(Handle, -1, NULL,
NULL, NULL, 0, &pcbErrm, 0);
switch (rtn)
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
ret = SQL_SUCCESS;
if (pcbErrm > 0 && stmt->pgerror)
*((SQLINTEGER *) DiagInfoPtr) = (pcbErrm - 1)/ stmt->pgerror->recsize + 1;
break;
default:
break;
}
break;
case SQL_DIAG_SQLSTATE:
rtnlen = 5;
ret = PGAPI_StmtError(Handle, RecNumber,
DiagInfoPtr, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCESS_WITH_INFO == ret)
ret = SQL_SUCCESS;
break;
case SQL_DIAG_CURSOR_ROW_COUNT:
rtnctype = SQL_C_LONG;
stmt = (StatementClass *) Handle;
rc = -1;
if (stmt->status == STMT_FINISHED)
{
QResultClass *res = SC_get_Curres(stmt);
if (stmt->proc_return > 0)
rc = 0;
else if (res && QR_NumResultCols(res) > 0 && !SC_is_fetchcursor(stmt))
rc = QR_get_num_total_tuples(res) - res->dl_count;
}
*((SQLLEN *) DiagInfoPtr) = rc;
MYLOG(DETAIL_LOG_LEVEL, "rc=" FORMAT_LEN "\n", rc);
ret = SQL_SUCCESS;
break;
case SQL_DIAG_ROW_COUNT:
rtnctype = SQL_C_LONG;
stmt = (StatementClass *) Handle;
*((SQLLEN *) DiagInfoPtr) = stmt->diag_row_count;
ret = SQL_SUCCESS;
break;
case SQL_DIAG_ROW_NUMBER:
rtnctype = SQL_C_LONG;
*((SQLLEN *) DiagInfoPtr) = SQL_ROW_NUMBER_UNKNOWN;
ret = SQL_SUCCESS;
break;
case SQL_DIAG_COLUMN_NUMBER:
rtnctype = SQL_C_LONG;
*((SQLINTEGER *) DiagInfoPtr) = SQL_COLUMN_NUMBER_UNKNOWN;
ret = SQL_SUCCESS;
break;
case SQL_DIAG_RETURNCODE: /* driver manager returns */
break;
}
break;
case SQL_HANDLE_DESC:
conn = DC_get_conn(((DescriptorClass *) Handle));
switch (DiagIdentifier)
{
case SQL_DIAG_CLASS_ORIGIN:
case SQL_DIAG_SUBCLASS_ORIGIN:
case SQL_DIAG_CONNECTION_NAME:
rtnlen = 0;
if (DiagInfoPtr && BufferLength > rtnlen)
{
ret = SQL_SUCCESS;
*((char *) DiagInfoPtr) = '\0';
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_SERVER_NAME:
rtnlen = strlen(CC_get_DSN(conn));
if (DiagInfoPtr)
{
strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
}
else
ret = SQL_SUCCESS_WITH_INFO;
break;
case SQL_DIAG_MESSAGE_TEXT:
case SQL_DIAG_NATIVE:
case SQL_DIAG_NUMBER:
break;
case SQL_DIAG_SQLSTATE:
rtnlen = 5;
ret = PGAPI_DescError(Handle, RecNumber,
DiagInfoPtr, NULL, NULL,
0, NULL, 0);
if (SQL_SUCCESS_WITH_INFO == ret)
ret = SQL_SUCCESS;
break;
case SQL_DIAG_RETURNCODE: /* driver manager returns */
break;
case SQL_DIAG_CURSOR_ROW_COUNT:
case SQL_DIAG_ROW_COUNT:
case SQL_DIAG_DYNAMIC_FUNCTION:
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
rtnctype = SQL_C_LONG;
/* options for statement type only */
break;
}
break;
default:
ret = SQL_ERROR;
}
if (SQL_C_LONG == rtnctype)
{
if (SQL_SUCCESS_WITH_INFO == ret)
ret = SQL_SUCCESS;
if (StringLengthPtr)
*StringLengthPtr = sizeof(SQLINTEGER);
}
else if (rtnlen >= 0)
{
if (rtnlen >= BufferLength)
{
if (SQL_SUCCESS == ret)
ret = SQL_SUCCESS_WITH_INFO;
if (BufferLength > 0)
((char *) DiagInfoPtr) [BufferLength - 1] = '\0';
}
if (StringLengthPtr)
*StringLengthPtr = (SQLSMALLINT) rtnlen;
}
MYLOG(0, "leaving %d\n", ret);
return ret;
}
/* SQLGetConnectOption -> SQLGetconnectAttr */
RETCODE SQL_API
PGAPI_GetConnectAttr(HDBC ConnectionHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER BufferLength, SQLINTEGER *StringLength)
{
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
RETCODE ret = SQL_SUCCESS;
SQLINTEGER len = 4;
if (Value == NULL) {
CC_set_error(conn, CONN_VALUE_OUT_OF_RANGE, "Invalid Connection value", "PGAPI_GetConnectOption");
return SQL_ERROR;
}
MYLOG(0, "entering %d\n", Attribute);
switch (Attribute)
{
case SQL_ATTR_ASYNC_ENABLE:
*((SQLINTEGER *) Value) = SQL_ASYNC_ENABLE_OFF;
break;
case SQL_ATTR_AUTO_IPD:
*((SQLINTEGER *) Value) = SQL_FALSE;
break;
case SQL_ATTR_CONNECTION_DEAD:
*((SQLUINTEGER *) Value) = CC_not_connected(conn);
break;
case SQL_ATTR_CONNECTION_TIMEOUT:
*((SQLUINTEGER *) Value) = 0;
break;
case SQL_ATTR_METADATA_ID:
*((SQLUINTEGER *) Value) = conn->stmtOptions.metadata_id;
break;
case SQL_ATTR_PGOPT_DEBUG:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.debug;
break;
case SQL_ATTR_PGOPT_COMMLOG:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.commlog;
break;
case SQL_ATTR_PGOPT_PARSE:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.parse;
break;
case SQL_ATTR_PGOPT_USE_DECLAREFETCH:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.use_declarefetch;
break;
case SQL_ATTR_PGOPT_SERVER_SIDE_PREPARE:
*((SQLINTEGER *) Value) = conn->connInfo.use_server_side_prepare;
break;
case SQL_ATTR_PGOPT_FETCH:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.fetch_max;
break;
case SQL_ATTR_PGOPT_UNKNOWNSIZES:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.unknown_sizes;
break;
case SQL_ATTR_PGOPT_TEXTASLONGVARCHAR:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.text_as_longvarchar;
break;
case SQL_ATTR_PGOPT_UNKNOWNSASLONGVARCHAR:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.unknowns_as_longvarchar;
break;
case SQL_ATTR_PGOPT_BOOLSASCHAR:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.bools_as_char;
break;
case SQL_ATTR_PGOPT_MAXVARCHARSIZE:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.max_varchar_size;
break;
case SQL_ATTR_PGOPT_MAXLONGVARCHARSIZE:
*((SQLINTEGER *) Value) = conn->connInfo.drivers.max_longvarchar_size;
break;
case SQL_ATTR_PGOPT_MSJET:
*((SQLINTEGER *) Value) = conn->ms_jet;
break;
default:
ret = PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value, &len, BufferLength);
}
if (StringLength)
*StringLength = len;
return ret;
}
static SQLHDESC
descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType)
{
StatementClass *stmt = (StatementClass *) StatementHandle;
switch (descType)
{
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
return (HSTMT) stmt->ard;
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
return (HSTMT) stmt->apd;
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
return (HSTMT) stmt->ird;
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
return (HSTMT) stmt->ipd;
}
return (HSTMT) 0;
}
static void column_bindings_set(ARDFields *opts, int cols, BOOL maxset)
{
int i;
if (cols == opts->allocated)
return;
if (cols > opts->allocated)
{
extend_column_bindings(opts, cols);
return;
}
if (maxset) return;
for (i = opts->allocated; i > cols; i--)
reset_a_column_binding(opts, i);
opts->allocated = cols;
if (0 == cols)
{
free(opts->bindings);
opts->bindings = NULL;
}
}
static RETCODE SQL_API
ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
ARDFields *opts = &(desc->ardf);
SQLSMALLINT row_idx;
BOOL unbind = TRUE;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
opts->size_of_rowset = CAST_UPTR(SQLULEN, Value);
return ret;
case SQL_DESC_ARRAY_STATUS_PTR:
opts->row_operation_ptr = Value;
return ret;
case SQL_DESC_BIND_OFFSET_PTR:
opts->row_offset_ptr = Value;
return ret;
case SQL_DESC_BIND_TYPE:
opts->bind_size = CAST_UPTR(SQLUINTEGER, Value);
return ret;
case SQL_DESC_COUNT:
column_bindings_set(opts, CAST_PTR(SQLSMALLINT, Value), FALSE);
return ret;
case SQL_DESC_TYPE:
case SQL_DESC_DATETIME_INTERVAL_CODE:
case SQL_DESC_CONCISE_TYPE:
column_bindings_set(opts, RecNumber, TRUE);
break;
}
if (RecNumber < 0 || RecNumber > opts->allocated)
{
DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR, "invalid column number");
return SQL_ERROR;
}
if (0 == RecNumber) /* bookmark column */
{
BindInfoClass *bookmark = ARD_AllocBookmark(opts);
switch (FieldIdentifier)
{
case SQL_DESC_DATA_PTR:
bookmark->buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
bookmark->indicator = Value;
break;
case SQL_DESC_OCTET_LENGTH_PTR:
bookmark->used = Value;
break;
default:
DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR, "invalid column number");
ret = SQL_ERROR;
}
return ret;
}
row_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_TYPE:
opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
switch (opts->bindings[row_idx].returntype)
{
case SQL_DATETIME:
case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP:
switch ((LONG_PTR) Value)
{
case SQL_CODE_DATE:
opts->bindings[row_idx].returntype = SQL_C_TYPE_DATE;
break;
case SQL_CODE_TIME:
opts->bindings[row_idx].returntype = SQL_C_TYPE_TIME;
break;
case SQL_CODE_TIMESTAMP:
opts->bindings[row_idx].returntype = SQL_C_TYPE_TIMESTAMP;
break;
}
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_DATA_PTR:
unbind = FALSE;
opts->bindings[row_idx].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
unbind = FALSE;
opts->bindings[row_idx].indicator = Value;
break;
case SQL_DESC_OCTET_LENGTH_PTR:
unbind = FALSE;
opts->bindings[row_idx].used = Value;
break;
case SQL_DESC_OCTET_LENGTH:
opts->bindings[row_idx].buflen = CAST_PTR(SQLLEN, Value);
break;
case SQL_DESC_PRECISION:
opts->bindings[row_idx].precision = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_SCALE:
opts->bindings[row_idx].scale = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_LENGTH:
case SQL_DESC_NUM_PREC_RADIX:
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
if (unbind)
opts->bindings[row_idx].buffer = NULL;
return ret;
}
static void parameter_bindings_set(APDFields *opts, int params, BOOL maxset)
{
int i;
if (params == opts->allocated)
return;
if (params > opts->allocated)
{
extend_parameter_bindings(opts, params);
return;
}
if (maxset) return;
for (i = opts->allocated; i > params; i--)
reset_a_parameter_binding(opts, i);
opts->allocated = params;
if (0 == params)
{
free(opts->parameters);
opts->parameters = NULL;
}
}
static void parameter_ibindings_set(IPDFields *opts, int params, BOOL maxset)
{
int i;
if (params == opts->allocated)
return;
if (params > opts->allocated)
{
extend_iparameter_bindings(opts, params);
return;
}
if (maxset) return;
for (i = opts->allocated; i > params; i--)
reset_a_iparameter_binding(opts, i);
opts->allocated = params;
if (0 == params)
{
free(opts->parameters);
opts->parameters = NULL;
}
}
static RETCODE SQL_API
APDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
APDFields *opts = &(desc->apdf);
SQLSMALLINT para_idx;
BOOL unbind = TRUE;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
opts->paramset_size = CAST_UPTR(SQLUINTEGER, Value);
return ret;
case SQL_DESC_ARRAY_STATUS_PTR:
opts->param_operation_ptr = Value;
return ret;
case SQL_DESC_BIND_OFFSET_PTR:
opts->param_offset_ptr = Value;
return ret;
case SQL_DESC_BIND_TYPE:
opts->param_bind_type = CAST_UPTR(SQLUINTEGER, Value);
return ret;
case SQL_DESC_COUNT:
parameter_bindings_set(opts, CAST_PTR(SQLSMALLINT, Value), FALSE);
return ret;
case SQL_DESC_TYPE:
case SQL_DESC_DATETIME_INTERVAL_CODE:
case SQL_DESC_CONCISE_TYPE:
parameter_bindings_set(opts, RecNumber, TRUE);
break;
}
if (RecNumber <=0)
{
MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
"bad parameter number");
return SQL_ERROR;
}
if (RecNumber > opts->allocated)
{
MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
parameter_bindings_set(opts, RecNumber, TRUE);
}
para_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_TYPE:
opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
switch (opts->parameters[para_idx].CType)
{
case SQL_DATETIME:
case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP:
switch ((LONG_PTR) Value)
{
case SQL_CODE_DATE:
opts->parameters[para_idx].CType = SQL_C_TYPE_DATE;
break;
case SQL_CODE_TIME:
opts->parameters[para_idx].CType = SQL_C_TYPE_TIME;
break;
case SQL_CODE_TIMESTAMP:
opts->parameters[para_idx].CType = SQL_C_TYPE_TIMESTAMP;
break;
}
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_DATA_PTR:
unbind = FALSE;
opts->parameters[para_idx].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
unbind = FALSE;
opts->parameters[para_idx].indicator = Value;
break;
case SQL_DESC_OCTET_LENGTH:
opts->parameters[para_idx].buflen = CAST_PTR(Int4, Value);
break;
case SQL_DESC_OCTET_LENGTH_PTR:
unbind = FALSE;
opts->parameters[para_idx].used = Value;
break;
case SQL_DESC_PRECISION:
opts->parameters[para_idx].precision = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_SCALE:
opts->parameters[para_idx].scale = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_LENGTH:
case SQL_DESC_NUM_PREC_RADIX:
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invaid descriptor identifier");
}
if (unbind)
opts->parameters[para_idx].buffer = NULL;
return ret;
}
static RETCODE SQL_API
IRDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
IRDFields *opts = &(desc->irdf);
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
opts->rowStatusArray = (SQLUSMALLINT *) Value;
break;
case SQL_DESC_ROWS_PROCESSED_PTR:
opts->rowsFetched = (SQLULEN *) Value;
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_COUNT: /* read-only */
case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */
case SQL_DESC_BASE_COLUMN_NAME: /* read-only */
case SQL_DESC_BASE_TABLE_NAME: /* read-only */
case SQL_DESC_CASE_SENSITIVE: /* read-only */
case SQL_DESC_CATALOG_NAME: /* read-only */
case SQL_DESC_CONCISE_TYPE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */
case SQL_DESC_DISPLAY_SIZE: /* read-only */
case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
case SQL_DESC_LABEL: /* read-only */
case SQL_DESC_LENGTH: /* read-only */
case SQL_DESC_LITERAL_PREFIX: /* read-only */
case SQL_DESC_LITERAL_SUFFIX: /* read-only */
case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
case SQL_DESC_NAME: /* read-only */
case SQL_DESC_NULLABLE: /* read-only */
case SQL_DESC_NUM_PREC_RADIX: /* read-only */
case SQL_DESC_OCTET_LENGTH: /* read-only */
case SQL_DESC_PRECISION: /* read-only */
case SQL_DESC_ROWVER: /* read-only */
case SQL_DESC_SCALE: /* read-only */
case SQL_DESC_SCHEMA_NAME: /* read-only */
case SQL_DESC_SEARCHABLE: /* read-only */
case SQL_DESC_TABLE_NAME: /* read-only */
case SQL_DESC_TYPE: /* read-only */
case SQL_DESC_TYPE_NAME: /* read-only */
case SQL_DESC_UNNAMED: /* read-only */
case SQL_DESC_UNSIGNED: /* read-only */
case SQL_DESC_UPDATABLE: /* read-only */
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
return ret;
}
static RETCODE SQL_API
IPDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
IPDFields *ipdopts = &(desc->ipdf);
SQLSMALLINT para_idx;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
ipdopts->param_status_ptr = (SQLUSMALLINT *) Value;
return ret;
case SQL_DESC_ROWS_PROCESSED_PTR:
ipdopts->param_processed_ptr = (SQLULEN *) Value;
return ret;
case SQL_DESC_COUNT:
parameter_ibindings_set(ipdopts, CAST_PTR(SQLSMALLINT, Value), FALSE);
return ret;
case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */
if (SQL_UNNAMED != CAST_PTR(SQLSMALLINT, Value))
{
ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
return ret;
}
case SQL_DESC_NAME:
case SQL_DESC_TYPE:
case SQL_DESC_DATETIME_INTERVAL_CODE:
case SQL_DESC_CONCISE_TYPE:
parameter_ibindings_set(ipdopts, RecNumber, TRUE);
break;
}
if (RecNumber <= 0 || RecNumber > ipdopts->allocated)
{
MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, ipdopts->allocated);
DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
"bad parameter number");
return SQL_ERROR;
}
para_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_TYPE:
if (ipdopts->parameters[para_idx].SQLType != CAST_PTR(SQLSMALLINT, Value))
{
reset_a_iparameter_binding(ipdopts, RecNumber);
ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value);
}
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
switch (ipdopts->parameters[para_idx].SQLType)
{
case SQL_DATETIME:
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
switch ((LONG_PTR) Value)
{
case SQL_CODE_DATE:
ipdopts->parameters[para_idx].SQLType = SQL_TYPE_DATE;
break;
case SQL_CODE_TIME:
ipdopts->parameters[para_idx].SQLType = SQL_TYPE_TIME;
break;
case SQL_CODE_TIMESTAMP:
ipdopts->parameters[para_idx].SQLType = SQL_TYPE_TIMESTAMP;
break;
}
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_NAME:
if (Value)
STR_TO_NAME(ipdopts->parameters[para_idx].paramName, Value);
else
NULL_THE_NAME(ipdopts->parameters[para_idx].paramName);
break;
case SQL_DESC_PARAMETER_TYPE:
ipdopts->parameters[para_idx].paramType = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_SCALE:
ipdopts->parameters[para_idx].decimal_digits = CAST_PTR(SQLSMALLINT, Value);
break;
case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */
if (SQL_UNNAMED != CAST_PTR(SQLSMALLINT, Value))
{
ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
else
NULL_THE_NAME(ipdopts->parameters[para_idx].paramName);
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_CASE_SENSITIVE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
case SQL_DESC_LENGTH:
case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
case SQL_DESC_NULLABLE: /* read-only */
case SQL_DESC_NUM_PREC_RADIX:
case SQL_DESC_OCTET_LENGTH:
case SQL_DESC_PRECISION:
case SQL_DESC_ROWVER: /* read-only */
case SQL_DESC_TYPE_NAME: /* read-only */
case SQL_DESC_UNSIGNED: /* read-only */
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
return ret;
}
static RETCODE SQL_API
ARDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
SQLINTEGER *StringLength)
{
RETCODE ret = SQL_SUCCESS;
SQLLEN ival = 0;
SQLINTEGER len, rettype = 0;
PTR ptr = NULL;
const ARDFields *opts = &(desc->ardf);
SQLSMALLINT row_idx;
len = sizeof(SQLINTEGER);
if (0 == RecNumber) /* bookmark */
{
BindInfoClass *bookmark = opts->bookmark;
switch (FieldIdentifier)
{
case SQL_DESC_DATA_PTR:
rettype = SQL_IS_POINTER;
ptr = bookmark ? bookmark->buffer : NULL;
break;
case SQL_DESC_INDICATOR_PTR:
rettype = SQL_IS_POINTER;
ptr = bookmark ? bookmark->indicator : NULL;
break;
case SQL_DESC_OCTET_LENGTH_PTR:
rettype = SQL_IS_POINTER;
ptr = bookmark ? bookmark->used : NULL;
break;
}
if (ptr)
{
*((void **) Value) = ptr;
if (StringLength)
*StringLength = len;
return ret;
}
}
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
case SQL_DESC_ARRAY_STATUS_PTR:
case SQL_DESC_BIND_OFFSET_PTR:
case SQL_DESC_BIND_TYPE:
case SQL_DESC_COUNT:
break;
default:
if (RecNumber <= 0 || RecNumber > opts->allocated)
{
DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR,
"invalid column number");
return SQL_ERROR;
}
}
row_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
ival = opts->size_of_rowset;
break;
case SQL_DESC_ARRAY_STATUS_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->row_operation_ptr;
break;
case SQL_DESC_BIND_OFFSET_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->row_offset_ptr;
break;
case SQL_DESC_BIND_TYPE:
ival = opts->bind_size;
break;
case SQL_DESC_TYPE:
rettype = SQL_IS_SMALLINT;
switch (opts->bindings[row_idx].returntype)
{
case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP:
ival = SQL_DATETIME;
break;
default:
ival = opts->bindings[row_idx].returntype;
}
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
rettype = SQL_IS_SMALLINT;
switch (opts->bindings[row_idx].returntype)
{
case SQL_C_TYPE_DATE:
ival = SQL_CODE_DATE;
break;
case SQL_C_TYPE_TIME:
ival = SQL_CODE_TIME;
break;
case SQL_C_TYPE_TIMESTAMP:
ival = SQL_CODE_TIMESTAMP;
break;
default:
ival = 0;
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
rettype = SQL_IS_SMALLINT;
ival = opts->bindings[row_idx].returntype;
break;
case SQL_DESC_DATA_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->bindings[row_idx].buffer;
break;
case SQL_DESC_INDICATOR_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->bindings[row_idx].indicator;
break;
case SQL_DESC_OCTET_LENGTH_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->bindings[row_idx].used;
break;
case SQL_DESC_COUNT:
rettype = SQL_IS_SMALLINT;
ival = opts->allocated;
break;
case SQL_DESC_OCTET_LENGTH:
ival = opts->bindings[row_idx].buflen;
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
rettype = SQL_IS_SMALLINT;
if (DC_get_embedded(desc))
ival = SQL_DESC_ALLOC_AUTO;
else
ival = SQL_DESC_ALLOC_USER;
break;
case SQL_DESC_PRECISION:
rettype = SQL_IS_SMALLINT;
ival = opts->bindings[row_idx].precision;
break;
case SQL_DESC_SCALE:
rettype = SQL_IS_SMALLINT;
ival = opts->bindings[row_idx].scale;
break;
case SQL_DESC_NUM_PREC_RADIX:
ival = 10;
break;
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_LENGTH:
default:
ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
switch (rettype)
{
case 0:
case SQL_IS_INTEGER:
len = sizeof(SQLINTEGER);
*((SQLINTEGER *) Value) = (SQLINTEGER) ival;
break;
case SQL_IS_SMALLINT:
len = sizeof(SQLSMALLINT);
*((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
break;
case SQL_IS_POINTER:
len = sizeof(SQLPOINTER);
*((void **) Value) = ptr;
break;
}
if (StringLength)
*StringLength = len;
return ret;
}
static RETCODE SQL_API
APDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
SQLINTEGER *StringLength)
{
RETCODE ret = SQL_SUCCESS;
SQLLEN ival = 0;
SQLINTEGER len, rettype = 0;
PTR ptr = NULL;
const APDFields *opts = (const APDFields *) &(desc->apdf);
SQLSMALLINT para_idx;
len = sizeof(SQLINTEGER);
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
case SQL_DESC_ARRAY_STATUS_PTR:
case SQL_DESC_BIND_OFFSET_PTR:
case SQL_DESC_BIND_TYPE:
case SQL_DESC_COUNT:
break;
default:if (RecNumber <= 0 || RecNumber > opts->allocated)
{
MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
"bad parameter number");
return SQL_ERROR;
}
}
para_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
rettype = SQL_IS_LEN;
ival = opts->paramset_size;
break;
case SQL_DESC_ARRAY_STATUS_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->param_operation_ptr;
break;
case SQL_DESC_BIND_OFFSET_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->param_offset_ptr;
break;
case SQL_DESC_BIND_TYPE:
ival = opts->param_bind_type;
break;
case SQL_DESC_TYPE:
rettype = SQL_IS_SMALLINT;
switch (opts->parameters[para_idx].CType)
{
case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP:
ival = SQL_DATETIME;
break;
default:
ival = opts->parameters[para_idx].CType;
}
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
rettype = SQL_IS_SMALLINT;
switch (opts->parameters[para_idx].CType)
{
case SQL_C_TYPE_DATE:
ival = SQL_CODE_DATE;
break;
case SQL_C_TYPE_TIME:
ival = SQL_CODE_TIME;
break;
case SQL_C_TYPE_TIMESTAMP:
ival = SQL_CODE_TIMESTAMP;
break;
default:
ival = 0;
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
rettype = SQL_IS_SMALLINT;
ival = opts->parameters[para_idx].CType;
break;
case SQL_DESC_DATA_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->parameters[para_idx].buffer;
break;
case SQL_DESC_INDICATOR_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->parameters[para_idx].indicator;
break;
case SQL_DESC_OCTET_LENGTH:
ival = opts->parameters[para_idx].buflen;
break;
case SQL_DESC_OCTET_LENGTH_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->parameters[para_idx].used;
break;
case SQL_DESC_COUNT:
ret = SQL_IS_SMALLINT;
ival = opts->allocated;
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
rettype = SQL_IS_SMALLINT;
if (DC_get_embedded(desc))
ival = SQL_DESC_ALLOC_AUTO;
else
ival = SQL_DESC_ALLOC_USER;
break;
case SQL_DESC_NUM_PREC_RADIX:
ival = 10;
break;
case SQL_DESC_PRECISION:
rettype = SQL_IS_SMALLINT;
ival = opts->parameters[para_idx].precision;
break;
case SQL_DESC_SCALE:
rettype = SQL_IS_SMALLINT;
ival = opts->parameters[para_idx].scale;
break;
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_LENGTH:
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifer");
}
switch (rettype)
{
case SQL_IS_LEN:
len = sizeof(SQLLEN);
*((SQLLEN *) Value) = ival;
break;
case 0:
case SQL_IS_INTEGER:
len = sizeof(SQLINTEGER);
*((SQLINTEGER *) Value) = (SQLINTEGER) ival;
break;
case SQL_IS_SMALLINT:
len = sizeof(SQLSMALLINT);
*((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
break;
case SQL_IS_POINTER:
len = sizeof(SQLPOINTER);
*((void **) Value) = ptr;
break;
}
if (StringLength)
*StringLength = len;
return ret;
}
static RETCODE SQL_API
IRDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
SQLINTEGER *StringLength)
{
RETCODE ret = SQL_SUCCESS;
SQLLEN ival = 0;
SQLINTEGER len = 0, rettype = 0;
PTR ptr = NULL;
BOOL bCallColAtt = FALSE;
const IRDFields *opts = &(desc->irdf);
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->rowStatusArray;
break;
case SQL_DESC_ROWS_PROCESSED_PTR:
rettype = SQL_IS_POINTER;
ptr = opts->rowsFetched;
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
rettype = SQL_IS_SMALLINT;
ival = SQL_DESC_ALLOC_AUTO;
break;
case SQL_DESC_COUNT: /* read-only */
case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */
case SQL_DESC_CASE_SENSITIVE: /* read-only */
case SQL_DESC_CONCISE_TYPE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */
case SQL_DESC_DISPLAY_SIZE: /* read-only */
case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
case SQL_DESC_LENGTH: /* read-only */
case SQL_DESC_NULLABLE: /* read-only */
case SQL_DESC_NUM_PREC_RADIX: /* read-only */
case SQL_DESC_OCTET_LENGTH: /* read-only */
case SQL_DESC_PRECISION: /* read-only */
case SQL_DESC_ROWVER: /* read-only */
case SQL_DESC_SCALE: /* read-only */
case SQL_DESC_SEARCHABLE: /* read-only */
case SQL_DESC_TYPE: /* read-only */
case SQL_DESC_UNNAMED: /* read-only */
case SQL_DESC_UNSIGNED: /* read-only */
case SQL_DESC_UPDATABLE: /* read-only */
bCallColAtt = TRUE;
break;
case SQL_DESC_BASE_COLUMN_NAME: /* read-only */
case SQL_DESC_BASE_TABLE_NAME: /* read-only */
case SQL_DESC_CATALOG_NAME: /* read-only */
case SQL_DESC_LABEL: /* read-only */
case SQL_DESC_LITERAL_PREFIX: /* read-only */
case SQL_DESC_LITERAL_SUFFIX: /* read-only */
case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
case SQL_DESC_NAME: /* read-only */
case SQL_DESC_SCHEMA_NAME: /* read-only */
case SQL_DESC_TABLE_NAME: /* read-only */
case SQL_DESC_TYPE_NAME: /* read-only */
rettype = SQL_NTS;
bCallColAtt = TRUE;
break;
default:
ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
if (bCallColAtt)
{
SQLSMALLINT pcbL;
StatementClass *stmt;
stmt = opts->stmt;
ret = PGAPI_ColAttributes(stmt, RecNumber,
FieldIdentifier, Value, (SQLSMALLINT) BufferLength,
&pcbL, &ival);
len = pcbL;
}
switch (rettype)
{
case 0:
case SQL_IS_INTEGER:
len = sizeof(SQLINTEGER);
*((SQLINTEGER *) Value) = (SQLINTEGER) ival;
break;
case SQL_IS_UINTEGER:
len = sizeof(SQLUINTEGER);
*((SQLUINTEGER *) Value) = (SQLUINTEGER) ival;
break;
case SQL_IS_SMALLINT:
len = sizeof(SQLSMALLINT);
*((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
break;
case SQL_IS_POINTER:
len = sizeof(SQLPOINTER);
*((void **) Value) = ptr;
break;
case SQL_NTS:
break;
}
if (StringLength)
*StringLength = len;
return ret;
}
static RETCODE SQL_API
IPDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
SQLINTEGER *StringLength)
{
RETCODE ret = SQL_SUCCESS;
SQLINTEGER ival = 0, len = 0, rettype = 0;
PTR ptr = NULL;
const IPDFields *ipdopts = (const IPDFields *) &(desc->ipdf);
SQLSMALLINT para_idx;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
case SQL_DESC_ROWS_PROCESSED_PTR:
case SQL_DESC_COUNT:
break;
default:if (RecNumber <= 0 || RecNumber > ipdopts->allocated)
{
MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, ipdopts->allocated);
DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
"bad parameter number");
return SQL_ERROR;
}
}
para_idx = RecNumber - 1;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
rettype = SQL_IS_POINTER;
ptr = ipdopts->param_status_ptr;
break;
case SQL_DESC_ROWS_PROCESSED_PTR:
rettype = SQL_IS_POINTER;
ptr = ipdopts->param_processed_ptr;
break;
case SQL_DESC_UNNAMED:
rettype = SQL_IS_SMALLINT;
ival = NAME_IS_NULL(ipdopts->parameters[para_idx].paramName) ? SQL_UNNAMED : SQL_NAMED;
break;
case SQL_DESC_TYPE:
rettype = SQL_IS_SMALLINT;
switch (ipdopts->parameters[para_idx].SQLType)
{
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
ival = SQL_DATETIME;
break;
default:
ival = ipdopts->parameters[para_idx].SQLType;
}
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
rettype = SQL_IS_SMALLINT;
switch (ipdopts->parameters[para_idx].SQLType)
{
case SQL_TYPE_DATE:
ival = SQL_CODE_DATE;
break;
case SQL_TYPE_TIME:
ival = SQL_CODE_TIME;
break;
case SQL_TYPE_TIMESTAMP:
ival = SQL_CODE_TIMESTAMP;
break;
default:
ival = 0;
}
break;
case SQL_DESC_CONCISE_TYPE:
rettype = SQL_IS_SMALLINT;
ival = ipdopts->parameters[para_idx].SQLType;
break;
case SQL_DESC_COUNT:
rettype = SQL_IS_SMALLINT;
ival = ipdopts->allocated;
break;
case SQL_DESC_PARAMETER_TYPE:
rettype = SQL_IS_SMALLINT;
ival = ipdopts->parameters[para_idx].paramType;
break;
case SQL_DESC_PRECISION:
rettype = SQL_IS_SMALLINT;
switch (ipdopts->parameters[para_idx].SQLType)
{
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
case SQL_DATETIME:
ival = ipdopts->parameters[para_idx].decimal_digits;
break;
}
break;
case SQL_DESC_SCALE:
rettype = SQL_IS_SMALLINT;
switch (ipdopts->parameters[para_idx].SQLType)
{
case SQL_NUMERIC:
ival = ipdopts->parameters[para_idx].decimal_digits;
break;
}
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
rettype = SQL_IS_SMALLINT;
ival = SQL_DESC_ALLOC_AUTO;
break;
case SQL_DESC_CASE_SENSITIVE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
case SQL_DESC_LENGTH:
case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
case SQL_DESC_NAME:
case SQL_DESC_NULLABLE: /* read-only */
case SQL_DESC_NUM_PREC_RADIX:
case SQL_DESC_OCTET_LENGTH:
case SQL_DESC_ROWVER: /* read-only */
case SQL_DESC_TYPE_NAME: /* read-only */
case SQL_DESC_UNSIGNED: /* read-only */
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
"invalid descriptor identifier");
}
switch (rettype)
{
case 0:
case SQL_IS_INTEGER:
len = sizeof(SQLINTEGER);
*((SQLINTEGER *) Value) = ival;
break;
case SQL_IS_SMALLINT:
len = sizeof(SQLSMALLINT);
*((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
break;
case SQL_IS_POINTER:
len = sizeof(SQLPOINTER);
*((void **)Value) = ptr;
break;
}
if (StringLength)
*StringLength = len;
return ret;
}
/* SQLGetStmtOption -> SQLGetStmtAttr */
RETCODE SQL_API
PGAPI_GetStmtAttr(HSTMT StatementHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER BufferLength, SQLINTEGER *StringLength)
{
CSTR func = "PGAPI_GetStmtAttr";
StatementClass *stmt = (StatementClass *) StatementHandle;
RETCODE ret = SQL_SUCCESS;
SQLINTEGER len = 0;
MYLOG(0, "entering Handle=%p %d\n", StatementHandle, Attribute);
switch (Attribute)
{
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
*((void **) Value) = stmt->options.bookmark_ptr;
len = sizeof(SQLPOINTER);
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
*((SQLULEN **) Value) = SC_get_APDF(stmt)->param_offset_ptr;
len = sizeof(SQLPOINTER);
break;
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
*((SQLUINTEGER *) Value) = SC_get_APDF(stmt)->param_bind_type;
len = sizeof(SQLUINTEGER);
break;
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
*((SQLUSMALLINT **) Value) = SC_get_APDF(stmt)->param_operation_ptr;
len = sizeof(SQLPOINTER);
break;
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
*((SQLUSMALLINT **) Value) = SC_get_IPDF(stmt)->param_status_ptr;
len = sizeof(SQLPOINTER);
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
*((SQLULEN **) Value) = SC_get_IPDF(stmt)->param_processed_ptr;
len = sizeof(SQLPOINTER);
break;
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
*((SQLULEN *) Value) = SC_get_APDF(stmt)->paramset_size;
len = sizeof(SQLUINTEGER);
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
*((SQLULEN **) Value) = SC_get_ARDF(stmt)->row_offset_ptr;
len = 4;
break;
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
*((SQLUSMALLINT **) Value) = SC_get_ARDF(stmt)->row_operation_ptr;
len = 4;
break;
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
*((SQLUSMALLINT **) Value) = SC_get_IRDF(stmt)->rowStatusArray;
len = 4;
break;
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
*((SQLULEN **) Value) = SC_get_IRDF(stmt)->rowsFetched;
len = 4;
break;
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
*((SQLULEN *) Value) = SC_get_ARDF(stmt)->size_of_rowset;
len = 4;
break;
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
len = 4;
*((HSTMT *) Value) = descHandleFromStatementHandle(StatementHandle, Attribute);
break;
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
len = 4;
if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type)
*((SQLUINTEGER *) Value) = SQL_NONSCROLLABLE;
else
*((SQLUINTEGER *) Value) = SQL_SCROLLABLE;
break;
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
len = 4;
if (SQL_CONCUR_READ_ONLY == stmt->options.scroll_concurrency)
*((SQLUINTEGER *) Value) = SQL_INSENSITIVE;
else
*((SQLUINTEGER *) Value) = SQL_UNSPECIFIED;
break;
case SQL_ATTR_METADATA_ID: /* 10014 */
*((SQLUINTEGER *) Value) = stmt->options.metadata_id;
break;
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
*((SQLUINTEGER *) Value) = SQL_FALSE;
break;
case SQL_ATTR_AUTO_IPD: /* 10001 */
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER, "Unsupported statement option (Get)", func);
return SQL_ERROR;
default:
ret = PGAPI_GetStmtOption(StatementHandle, (SQLSMALLINT) Attribute, Value, &len, BufferLength);
}
if (ret == SQL_SUCCESS && StringLength)
*StringLength = len;
return ret;
}
/* SQLSetConnectOption -> SQLSetConnectAttr */
RETCODE SQL_API
PGAPI_SetConnectAttr(HDBC ConnectionHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER StringLength)
{
CSTR func = "PGAPI_SetConnectAttr";
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
RETCODE ret = SQL_SUCCESS;
BOOL unsupported = FALSE;
int newValue;
MYLOG(0, "entering for %p: %d %p\n", ConnectionHandle, Attribute, Value);
switch (Attribute)
{
case SQL_ATTR_METADATA_ID:
conn->stmtOptions.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
break;
case SQL_ATTR_ANSI_APP:
if (SQL_AA_FALSE != CAST_PTR(SQLINTEGER, Value))
{
MYLOG(0, "the application is ansi\n");
if (CC_is_in_unicode_driver(conn)) /* the driver is unicode */
CC_set_in_ansi_app(conn); /* but the app is ansi */
}
else
{
MYLOG(0, "the application is unicode\n");
}
return SQL_SUCCESS;
case SQL_ATTR_ENLIST_IN_DTC:
#ifdef WIN32
#ifdef _HANDLE_ENLIST_IN_DTC_
MYLOG(0, "SQL_ATTR_ENLIST_IN_DTC %p request received\n", Value);
if (conn->connInfo.xa_opt != 0)
{
/*
* When a new global transaction is about
* to begin, isolate the existent global
* transaction.
*/
if (NULL != Value && CC_is_in_global_trans(conn))
CALL_IsolateDtcConn(conn, TRUE);
return CALL_EnlistInDtc(conn, Value, conn->connInfo.xa_opt);
}
#endif /* _HANDLE_ENLIST_IN_DTC_ */
#endif /* WIN32 */
unsupported = TRUE;
break;
case SQL_ATTR_AUTO_IPD:
if (SQL_FALSE != Value)
unsupported = TRUE;
break;
case SQL_ATTR_ASYNC_ENABLE:
case SQL_ATTR_CONNECTION_DEAD:
case SQL_ATTR_CONNECTION_TIMEOUT:
unsupported = TRUE;
break;
case SQL_ATTR_PGOPT_DEBUG:
newValue = CAST_UPTR(SQLCHAR, Value);
if (newValue > 0)
{
logs_on_off(-1, conn->connInfo.drivers.debug, 0);
conn->connInfo.drivers.debug = newValue;
logs_on_off(1, conn->connInfo.drivers.debug, 0);
MYLOG(0, "debug => %d\n", conn->connInfo.drivers.debug);
}
else if (newValue == 0 && conn->connInfo.drivers.debug > 0)
{
MYLOG(0, "debug => %d\n", newValue);
logs_on_off(-1, conn->connInfo.drivers.debug, 0);
conn->connInfo.drivers.debug = newValue;
logs_on_off(1, 0, 0);
}
break;
case SQL_ATTR_PGOPT_COMMLOG:
newValue = CAST_UPTR(SQLCHAR, Value);
if (newValue > 0)
{
logs_on_off(-1, 0, conn->connInfo.drivers.commlog);
conn->connInfo.drivers.commlog = newValue;
logs_on_off(1, 0, conn->connInfo.drivers.commlog);
MYLOG(0, "commlog => %d\n", conn->connInfo.drivers.commlog);
}
else if (newValue == 0 && conn->connInfo.drivers.commlog > 0)
{
MYLOG(0, "commlog => %d\n", newValue);
logs_on_off(-1, 0, conn->connInfo.drivers.commlog);
conn->connInfo.drivers.debug = newValue;
logs_on_off(1, 0, 0);
}
break;
case SQL_ATTR_PGOPT_PARSE:
conn->connInfo.drivers.parse = CAST_UPTR(SQLCHAR, Value);
MYLOG(0, "parse => %d\n", conn->connInfo.drivers.parse);
break;
case SQL_ATTR_PGOPT_USE_DECLAREFETCH:
conn->connInfo.drivers.use_declarefetch = CAST_UPTR(SQLCHAR, Value);
ci_updatable_cursors_set(&conn->connInfo);
MYLOG(0, "declarefetch => %d\n", conn->connInfo.drivers.use_declarefetch);
break;
case SQL_ATTR_PGOPT_SERVER_SIDE_PREPARE:
conn->connInfo.use_server_side_prepare = CAST_UPTR(SQLCHAR, Value);
MYLOG(0, "server_side_prepare => %d\n", conn->connInfo.use_server_side_prepare);
break;
case SQL_ATTR_PGOPT_FETCH:
conn->connInfo.drivers.fetch_max = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "fetch => %d\n", conn->connInfo.drivers.fetch_max);
break;
case SQL_ATTR_PGOPT_UNKNOWNSIZES:
conn->connInfo.drivers.unknown_sizes = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "unknown_sizes => %d\n", conn->connInfo.drivers.unknown_sizes);
break;
case SQL_ATTR_PGOPT_TEXTASLONGVARCHAR:
conn->connInfo.drivers.text_as_longvarchar = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "text_as_longvarchar => %d\n", conn->connInfo.drivers.text_as_longvarchar);
break;
case SQL_ATTR_PGOPT_UNKNOWNSASLONGVARCHAR:
conn->connInfo.drivers.unknowns_as_longvarchar = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "unknowns_as_long_varchar => %d\n", conn->connInfo.drivers.unknowns_as_longvarchar);
break;
case SQL_ATTR_PGOPT_BOOLSASCHAR:
conn->connInfo.drivers.bools_as_char = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "bools_as_char => %d\n", conn->connInfo.drivers.bools_as_char);
break;
case SQL_ATTR_PGOPT_MAXVARCHARSIZE:
conn->connInfo.drivers.max_varchar_size = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "max_varchar_size => %d\n", conn->connInfo.drivers.max_varchar_size);
break;
case SQL_ATTR_PGOPT_MAXLONGVARCHARSIZE:
conn->connInfo.drivers.max_longvarchar_size = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "max_longvarchar_size => %d\n", conn->connInfo.drivers.max_longvarchar_size);
break;
case SQL_ATTR_PGOPT_WCSDEBUG:
conn->connInfo.wcs_debug = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "wcs_debug => %d\n", conn->connInfo.wcs_debug);
break;
case SQL_ATTR_PGOPT_MSJET:
conn->ms_jet = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "ms_jet => %d\n", conn->ms_jet);
break;
default:
if (Attribute < 65536)
ret = PGAPI_SetConnectOption(ConnectionHandle, (SQLUSMALLINT) Attribute, (SQLLEN) Value);
else
unsupported = TRUE;
}
if (unsupported)
{
char msg[64];
SPRINTF_FIXED(msg, "Couldn't set unsupported connect attribute " FORMAT_INTEGER, Attribute);
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, msg, func);
return SQL_ERROR;
}
return ret;
}
/* new function */
RETCODE SQL_API
PGAPI_GetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
PTR Value, SQLINTEGER BufferLength,
SQLINTEGER *StringLength)
{
CSTR func = "PGAPI_GetDescField";
RETCODE ret = SQL_SUCCESS;
DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
MYLOG(0, "entering h=%p rec=%d field=%d blen=%d\n", DescriptorHandle, RecNumber, FieldIdentifier, BufferLength);
switch (DC_get_desc_type(desc))
{
case SQL_ATTR_APP_ROW_DESC:
ret = ARDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
break;
case SQL_ATTR_APP_PARAM_DESC:
ret = APDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
break;
case SQL_ATTR_IMP_ROW_DESC:
ret = IRDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
break;
case SQL_ATTR_IMP_PARAM_DESC:
ret = IPDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
break;
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
}
if (ret == SQL_ERROR)
{
if (!DC_get_errormsg(desc))
{
switch (DC_get_errornumber(desc))
{
case DESC_INVALID_DESCRIPTOR_IDENTIFIER:
DC_set_errormsg(desc, "can't SQLGetDescField for this descriptor identifier");
break;
case DESC_INVALID_COLUMN_NUMBER_ERROR:
DC_set_errormsg(desc, "can't SQLGetDescField for this column number");
break;
case DESC_BAD_PARAMETER_NUMBER_ERROR:
DC_set_errormsg(desc, "can't SQLGetDescField for this parameter number");
break;
}
}
DC_log_error(func, "", desc);
}
return ret;
}
/* new function */
RETCODE SQL_API
PGAPI_SetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
PTR Value, SQLINTEGER BufferLength)
{
CSTR func = "PGAPI_SetDescField";
RETCODE ret = SQL_SUCCESS;
DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
MYLOG(0, "entering h=%p(%d) rec=%d field=%d val=%p,%d\n", DescriptorHandle, DC_get_desc_type(desc), RecNumber, FieldIdentifier, Value, BufferLength);
switch (DC_get_desc_type(desc))
{
case SQL_ATTR_APP_ROW_DESC:
ret = ARDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_APP_PARAM_DESC:
ret = APDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_IMP_ROW_DESC:
ret = IRDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_IMP_PARAM_DESC:
ret = IPDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
break;
default:ret = SQL_ERROR;
DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
}
if (ret == SQL_ERROR)
{
if (!DC_get_errormsg(desc))
{
switch (DC_get_errornumber(desc))
{
case DESC_INVALID_DESCRIPTOR_IDENTIFIER:
DC_set_errormsg(desc, "can't SQLSetDescField for this descriptor identifier");
break;
case DESC_INVALID_COLUMN_NUMBER_ERROR:
DC_set_errormsg(desc, "can't SQLSetDescField for this column number");
break;
case DESC_BAD_PARAMETER_NUMBER_ERROR:
DC_set_errormsg(desc, "can't SQLSetDescField for this parameter number");
break;
}
}
DC_log_error(func, "", desc);
}
return ret;
}
/* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
RETCODE SQL_API
PGAPI_SetStmtAttr(HSTMT StatementHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER StringLength)
{
RETCODE ret = SQL_SUCCESS;
CSTR func = "PGAPI_SetStmtAttr";
StatementClass *stmt = (StatementClass *) StatementHandle;
MYLOG(0, "entering Handle=%p %d," FORMAT_ULEN "(%p)\n", StatementHandle, Attribute, (SQLULEN) Value, Value);
switch (Attribute)
{
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
if (SQL_FALSE == Value)
break;
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
case SQL_ATTR_AUTO_IPD: /* 10001 */
SC_set_error(stmt, DESC_OPTION_NOT_FOR_THE_DRIVER, "Unsupported statement option (Set)", func);
return SQL_ERROR;
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
case SQL_ATTR_IMP_ROW_DESC: /* 10012 (read-only) */
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 (read-only) */
/*
* case SQL_ATTR_PREDICATE_PTR: case
* SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
*/
SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER, "Unsupported statement option (Set)", func);
return SQL_ERROR;
case SQL_ATTR_METADATA_ID: /* 10014 */
stmt->options.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
break;
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
if (SQL_NULL_HDESC == Value)
{
stmt->ard = &(stmt->ardi);
}
else
{
stmt->ard = (DescriptorClass *) Value;
MYLOG(DETAIL_LOG_LEVEL, "set ard=%p\n", stmt->ard);
}
break;
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
if (SQL_NULL_HDESC == Value)
{
stmt->apd = &(stmt->apdi);
}
else
{
stmt->apd = (DescriptorClass *) Value;
}
break;
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
stmt->options.bookmark_ptr = Value;
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
SC_get_APDF(stmt)->param_offset_ptr = (SQLULEN *) Value;
break;
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
SC_get_APDF(stmt)->param_bind_type = CAST_UPTR(SQLUINTEGER, Value);
break;
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
SC_get_APDF(stmt)->param_operation_ptr = Value;
break;
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
SC_get_IPDF(stmt)->param_status_ptr = (SQLUSMALLINT *) Value;
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
SC_get_IPDF(stmt)->param_processed_ptr = (SQLULEN *) Value;
break;
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
SC_get_APDF(stmt)->paramset_size = CAST_UPTR(SQLULEN, Value);
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
SC_get_ARDF(stmt)->row_offset_ptr = (SQLULEN *) Value;
break;
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
SC_get_ARDF(stmt)->row_operation_ptr = Value;
break;
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
SC_get_IRDF(stmt)->rowStatusArray = (SQLUSMALLINT *) Value;
break;
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
SC_get_IRDF(stmt)->rowsFetched = (SQLULEN *) Value;
break;
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
SC_get_ARDF(stmt)->size_of_rowset = CAST_UPTR(SQLULEN, Value);
break;
default:
return PGAPI_SetStmtOption(StatementHandle, (SQLUSMALLINT) Attribute, (SQLULEN) Value);
}
return ret;
}
/* SQL_NEED_DATA callback for PGAPI_BulkOperations */
typedef struct
{
StatementClass *stmt;
SQLSMALLINT operation;
char need_data_callback;
char auto_commit_needed;
ARDFields *opts;
int idx, processed;
} bop_cdata;
static
RETCODE bulk_ope_callback(RETCODE retcode, void *para)
{
CSTR func = "bulk_ope_callback";
RETCODE ret = retcode;
bop_cdata *s = (bop_cdata *) para;
SQLULEN global_idx;
ConnectionClass *conn;
QResultClass *res;
IRDFields *irdflds;
PG_BM pg_bm;
if (s->need_data_callback)
{
MYLOG(0, "entering in\n");
s->processed++;
s->idx++;
}
else
{
s->idx = s->processed = 0;
}
s->need_data_callback = FALSE;
res = SC_get_Curres(s->stmt);
for (; SQL_ERROR != ret && s->idx < s->opts->size_of_rowset; s->idx++)
{
if (SQL_ADD != s->operation)
{
pg_bm = SC_Resolve_bookmark(s->opts, s->idx);
QR_get_last_bookmark(res, s->idx, &pg_bm.keys);
global_idx = pg_bm.index;
}
/* Note opts->row_operation_ptr is ignored */
switch (s->operation)
{
case SQL_ADD:
ret = SC_pos_add(s->stmt, (UWORD) s->idx);
break;
case SQL_UPDATE_BY_BOOKMARK:
ret = SC_pos_update(s->stmt, (UWORD) s->idx, global_idx, &(pg_bm.keys));
break;
case SQL_DELETE_BY_BOOKMARK:
ret = SC_pos_delete(s->stmt, (UWORD) s->idx, global_idx, &(pg_bm.keys));
break;
}
if (SQL_NEED_DATA == ret)
{
bop_cdata *cbdata = (bop_cdata *) malloc(sizeof(bop_cdata));
if (!cbdata)
{
SC_set_error(s->stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for cbdata.", func);
return SQL_ERROR;
}
memcpy(cbdata, s, sizeof(bop_cdata));
cbdata->need_data_callback = TRUE;
if (0 == enqueueNeedDataCallback(s->stmt, bulk_ope_callback, cbdata))
ret = SQL_ERROR;
return ret;
}
s->processed++;
}
conn = SC_get_conn(s->stmt);
if (s->auto_commit_needed)
CC_set_autocommit(conn, TRUE);
irdflds = SC_get_IRDF(s->stmt);
if (irdflds->rowsFetched)
*(irdflds->rowsFetched) = s->processed;
if (res)
res->recent_processed_row_count = s->stmt->diag_row_count = s->processed;
return ret;
}
RETCODE SQL_API
PGAPI_BulkOperations(HSTMT hstmt, SQLSMALLINT operationX)
{
CSTR func = "PGAPI_BulkOperations";
bop_cdata s;
RETCODE ret;
ConnectionClass *conn;
BindInfoClass *bookmark;
MYLOG(0, "entering operation = %d\n", operationX);
s.stmt = (StatementClass *) hstmt;
s.operation = operationX;
SC_clear_error(s.stmt);
s.opts = SC_get_ARDF(s.stmt);
s.auto_commit_needed = FALSE;
if (SQL_FETCH_BY_BOOKMARK != s.operation)
{
conn = SC_get_conn(s.stmt);
if (s.auto_commit_needed = (char) CC_does_autocommit(conn), s.auto_commit_needed)
CC_set_autocommit(conn, FALSE);
}
if (SQL_ADD != s.operation)
{
if (!(bookmark = s.opts->bookmark) || !(bookmark->buffer))
{
SC_set_error(s.stmt, DESC_INVALID_OPTION_IDENTIFIER, "bookmark isn't specified", func);
return SQL_ERROR;
}
}
if (SQL_FETCH_BY_BOOKMARK == operationX)
ret = SC_fetch_by_bookmark(s.stmt);
else
{
s.need_data_callback = FALSE;
ret = bulk_ope_callback(SQL_SUCCESS, &s);
}
return ret;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。