mirror of
https://github.com/postgres/postgres.git
synced 2025-10-18 00:03:40 -04:00
1) Prepare to separate 4 kinds of Descriptor handles. 2) Detect the transaction status more naturally. 3) Improve Parse Statement functionality for the use of updatable cursors. 4) Improve updatable cursors. 5) Implement SQLGetDescField() and improve SQLColAttribute(). 6) etc.
658 lines
15 KiB
C
658 lines
15 KiB
C
/*--------
|
|
* Module: options.c
|
|
*
|
|
* Description: This module contains routines for getting/setting
|
|
* connection and statement options.
|
|
*
|
|
* Classes: n/a
|
|
*
|
|
* API functions: SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
|
|
* SQLGetStmtOption
|
|
*
|
|
* Comments: See "notice.txt" for copyright and license information.
|
|
*--------
|
|
*/
|
|
|
|
#include "psqlodbc.h"
|
|
#include <string.h>
|
|
|
|
#include "environ.h"
|
|
#include "connection.h"
|
|
#include "statement.h"
|
|
#include "qresult.h"
|
|
#include "pgapifunc.h"
|
|
|
|
|
|
|
|
RETCODE set_statement_option(ConnectionClass *conn,
|
|
StatementClass *stmt,
|
|
UWORD fOption,
|
|
UDWORD vParam);
|
|
|
|
|
|
RETCODE
|
|
set_statement_option(ConnectionClass *conn,
|
|
StatementClass *stmt,
|
|
UWORD fOption,
|
|
UDWORD vParam)
|
|
{
|
|
static char *func = "set_statement_option";
|
|
char changed = FALSE;
|
|
ConnInfo *ci = NULL;
|
|
UDWORD setval;
|
|
|
|
if (conn)
|
|
ci = &(conn->connInfo);
|
|
else if (stmt)
|
|
ci = &(SC_get_conn(stmt)->connInfo);
|
|
switch (fOption)
|
|
{
|
|
case SQL_ASYNC_ENABLE: /* ignored */
|
|
break;
|
|
|
|
case SQL_BIND_TYPE:
|
|
/* now support multi-column and multi-row binding */
|
|
if (conn)
|
|
conn->ardOptions.bind_size = vParam;
|
|
if (stmt)
|
|
SC_get_ARD(stmt)->bind_size = vParam;
|
|
break;
|
|
|
|
case SQL_CONCURRENCY:
|
|
|
|
/*
|
|
* positioned update isn't supported so cursor concurrency is
|
|
* read-only
|
|
*/
|
|
mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);
|
|
setval = SQL_CONCUR_READ_ONLY;
|
|
if (SQL_CONCUR_READ_ONLY == vParam)
|
|
;
|
|
if (ci->drivers.lie)
|
|
setval = vParam;
|
|
else if (ci->updatable_cursors)
|
|
setval = SQL_CONCUR_ROWVER;
|
|
if (conn)
|
|
conn->stmtOptions.scroll_concurrency = setval;
|
|
else if (stmt)
|
|
stmt->options.scroll_concurrency = setval;
|
|
if (setval != vParam)
|
|
changed = TRUE;
|
|
mylog("-> %d\n", setval);
|
|
break;
|
|
|
|
case SQL_CURSOR_TYPE:
|
|
|
|
/*
|
|
* if declare/fetch, then type can only be forward. otherwise,
|
|
* it can only be forward or static.
|
|
*/
|
|
mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);
|
|
setval = SQL_CURSOR_FORWARD_ONLY;
|
|
if (ci->drivers.lie)
|
|
setval = vParam;
|
|
else if (ci->drivers.use_declarefetch)
|
|
;
|
|
else if (SQL_CURSOR_STATIC == vParam)
|
|
setval = vParam;
|
|
/** else if (SQL_CURSOR_KEYSET_DRIVEN == vParam && ci->updatable)
|
|
setval = vParam; **/
|
|
|
|
if (conn)
|
|
conn->stmtOptions.cursor_type = setval;
|
|
else if (stmt)
|
|
stmt->options.cursor_type = setval;
|
|
if (setval != vParam)
|
|
changed = TRUE;
|
|
mylog("-> %d\n", setval);
|
|
break;
|
|
|
|
case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
|
|
mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);
|
|
|
|
if (conn)
|
|
conn->stmtOptions.keyset_size = vParam;
|
|
if (stmt)
|
|
stmt->options.keyset_size = vParam;
|
|
|
|
break;
|
|
|
|
/*-------
|
|
* if (ci->drivers.lie)
|
|
* stmt->keyset_size = vParam;
|
|
* else
|
|
* {
|
|
* stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
* stmt->errormsg = "Driver does not support keyset size option";
|
|
* SC_log_error(func, "", stmt);
|
|
* return SQL_ERROR;
|
|
* }
|
|
*-------
|
|
*/
|
|
|
|
case SQL_MAX_LENGTH: /* ignored, but saved */
|
|
mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
|
|
if (conn)
|
|
conn->stmtOptions.maxLength = vParam;
|
|
if (stmt)
|
|
stmt->options.maxLength = vParam;
|
|
break;
|
|
|
|
case SQL_MAX_ROWS: /* ignored, but saved */
|
|
mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
|
|
if (conn)
|
|
conn->stmtOptions.maxRows = vParam;
|
|
if (stmt)
|
|
stmt->options.maxRows = vParam;
|
|
break;
|
|
|
|
case SQL_NOSCAN: /* ignored */
|
|
mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
|
|
break;
|
|
|
|
case SQL_QUERY_TIMEOUT: /* ignored */
|
|
mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
|
|
/* "0" returned in SQLGetStmtOption */
|
|
break;
|
|
|
|
case SQL_RETRIEVE_DATA:
|
|
mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
|
|
if (conn)
|
|
conn->stmtOptions.retrieve_data = vParam;
|
|
if (stmt)
|
|
stmt->options.retrieve_data = vParam;
|
|
break;
|
|
|
|
case SQL_ROWSET_SIZE:
|
|
mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
|
|
|
|
/*
|
|
* Save old rowset size for SQLExtendedFetch purposes If the
|
|
* rowset_size is being changed since the last call to fetch
|
|
* rows.
|
|
*/
|
|
|
|
if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0)
|
|
stmt->save_rowset_size = SC_get_ARD(stmt)->rowset_size;
|
|
|
|
if (vParam < 1)
|
|
{
|
|
vParam = 1;
|
|
changed = TRUE;
|
|
}
|
|
|
|
if (conn)
|
|
conn->ardOptions.rowset_size = vParam;
|
|
if (stmt)
|
|
SC_get_ARD(stmt)->rowset_size = vParam;
|
|
break;
|
|
|
|
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
|
|
if (stmt)
|
|
{
|
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
|
SC_log_error(func, "", stmt);
|
|
}
|
|
if (conn)
|
|
{
|
|
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
|
CC_log_error(func, "", conn);
|
|
}
|
|
return SQL_ERROR;
|
|
|
|
case SQL_USE_BOOKMARKS:
|
|
if (stmt)
|
|
stmt->options.use_bookmarks = vParam;
|
|
if (conn)
|
|
conn->stmtOptions.use_bookmarks = vParam;
|
|
break;
|
|
|
|
default:
|
|
{
|
|
char option[64];
|
|
|
|
if (stmt)
|
|
{
|
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
stmt->errormsg = "Unknown statement option (Set)";
|
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
|
SC_log_error(func, option, stmt);
|
|
}
|
|
if (conn)
|
|
{
|
|
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
conn->errormsg = "Unknown statement option (Set)";
|
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
|
CC_log_error(func, option, conn);
|
|
}
|
|
|
|
return SQL_ERROR;
|
|
}
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
if (stmt)
|
|
{
|
|
stmt->errormsg = "Requested value changed.";
|
|
stmt->errornumber = STMT_OPTION_VALUE_CHANGED;
|
|
}
|
|
if (conn)
|
|
{
|
|
conn->errormsg = "Requested value changed.";
|
|
conn->errornumber = STMT_OPTION_VALUE_CHANGED;
|
|
}
|
|
return SQL_SUCCESS_WITH_INFO;
|
|
}
|
|
else
|
|
return SQL_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Implements only SQL_AUTOCOMMIT */
|
|
RETCODE SQL_API
|
|
PGAPI_SetConnectOption(
|
|
HDBC hdbc,
|
|
UWORD fOption,
|
|
UDWORD vParam)
|
|
{
|
|
static char *func = "PGAPI_SetConnectOption";
|
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|
char changed = FALSE;
|
|
RETCODE retval;
|
|
int i;
|
|
|
|
mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam);
|
|
if (!conn)
|
|
{
|
|
CC_log_error(func, "", NULL);
|
|
return SQL_INVALID_HANDLE;
|
|
}
|
|
|
|
switch (fOption)
|
|
{
|
|
/*
|
|
* Statement Options (apply to all stmts on the connection and
|
|
* become defaults for new stmts)
|
|
*/
|
|
case SQL_ASYNC_ENABLE:
|
|
case SQL_BIND_TYPE:
|
|
case SQL_CONCURRENCY:
|
|
case SQL_CURSOR_TYPE:
|
|
case SQL_KEYSET_SIZE:
|
|
case SQL_MAX_LENGTH:
|
|
case SQL_MAX_ROWS:
|
|
case SQL_NOSCAN:
|
|
case SQL_QUERY_TIMEOUT:
|
|
case SQL_RETRIEVE_DATA:
|
|
case SQL_ROWSET_SIZE:
|
|
case SQL_SIMULATE_CURSOR:
|
|
case SQL_USE_BOOKMARKS:
|
|
|
|
/* Affect all current Statements */
|
|
for (i = 0; i < conn->num_stmts; i++)
|
|
{
|
|
if (conn->stmts[i])
|
|
set_statement_option(NULL, conn->stmts[i], fOption, vParam);
|
|
}
|
|
|
|
/*
|
|
* Become the default for all future statements on this
|
|
* connection
|
|
*/
|
|
retval = set_statement_option(conn, NULL, fOption, vParam);
|
|
|
|
if (retval == SQL_SUCCESS_WITH_INFO)
|
|
changed = TRUE;
|
|
else if (retval == SQL_ERROR)
|
|
return SQL_ERROR;
|
|
|
|
break;
|
|
|
|
/*
|
|
* Connection Options
|
|
*/
|
|
|
|
case SQL_ACCESS_MODE: /* ignored */
|
|
break;
|
|
|
|
case SQL_AUTOCOMMIT:
|
|
if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn))
|
|
break;
|
|
else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn))
|
|
break;
|
|
if (CC_is_in_trans(conn))
|
|
CC_commit(conn);
|
|
|
|
mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
|
|
|
|
switch (vParam)
|
|
{
|
|
case SQL_AUTOCOMMIT_OFF:
|
|
CC_set_autocommit_off(conn);
|
|
break;
|
|
|
|
case SQL_AUTOCOMMIT_ON:
|
|
CC_set_autocommit_on(conn);
|
|
break;
|
|
|
|
default:
|
|
conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT";
|
|
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
|
|
CC_log_error(func, "", conn);
|
|
return SQL_ERROR;
|
|
}
|
|
break;
|
|
|
|
case SQL_CURRENT_QUALIFIER: /* ignored */
|
|
break;
|
|
|
|
case SQL_LOGIN_TIMEOUT: /* ignored */
|
|
break;
|
|
|
|
case SQL_PACKET_SIZE: /* ignored */
|
|
break;
|
|
|
|
case SQL_QUIET_MODE: /* ignored */
|
|
break;
|
|
|
|
case SQL_TXN_ISOLATION: /* ignored */
|
|
break;
|
|
|
|
/* These options should be handled by driver manager */
|
|
case SQL_ODBC_CURSORS:
|
|
case SQL_OPT_TRACE:
|
|
case SQL_OPT_TRACEFILE:
|
|
case SQL_TRANSLATE_DLL:
|
|
case SQL_TRANSLATE_OPTION:
|
|
CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn);
|
|
break;
|
|
|
|
default:
|
|
{
|
|
char option[64];
|
|
|
|
conn->errormsg = "Unknown connect option (Set)";
|
|
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
|
if (fOption == 30002 && vParam)
|
|
{
|
|
int cmp;
|
|
#ifdef UNICODE_SUPPORT
|
|
char *asPara;
|
|
if (conn->unicode)
|
|
{
|
|
asPara = ucs2_to_utf8((SQLWCHAR *) vParam, -1, NULL);
|
|
cmp = strcmp(asPara, "Microsoft Jet");
|
|
free(asPara);
|
|
}
|
|
else
|
|
#endif /* UNICODE_SUPPORT */
|
|
cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
|
|
if (0 == cmp)
|
|
{
|
|
mylog("Microsoft Jet !!!!\n");
|
|
conn->errornumber = 0;
|
|
conn->ms_jet = 1;
|
|
return SQL_SUCCESS;
|
|
}
|
|
}
|
|
CC_log_error(func, option, conn);
|
|
return SQL_ERROR;
|
|
}
|
|
}
|
|
|
|
if (changed)
|
|
{
|
|
conn->errornumber = CONN_OPTION_VALUE_CHANGED;
|
|
conn->errormsg = "Requested value changed.";
|
|
return SQL_SUCCESS_WITH_INFO;
|
|
}
|
|
else
|
|
return SQL_SUCCESS;
|
|
}
|
|
|
|
|
|
/* This function just can tell you whether you are in Autcommit mode or not */
|
|
RETCODE SQL_API
|
|
PGAPI_GetConnectOption(
|
|
HDBC hdbc,
|
|
UWORD fOption,
|
|
PTR pvParam)
|
|
{
|
|
static char *func = "PGAPI_GetConnectOption";
|
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|
ConnInfo *ci = &(conn->connInfo);
|
|
|
|
mylog("%s: entering...\n", func);
|
|
|
|
if (!conn)
|
|
{
|
|
CC_log_error(func, "", NULL);
|
|
return SQL_INVALID_HANDLE;
|
|
}
|
|
|
|
switch (fOption)
|
|
{
|
|
case SQL_ACCESS_MODE: /* NOT SUPPORTED */
|
|
*((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
|
|
break;
|
|
|
|
case SQL_AUTOCOMMIT:
|
|
*((UDWORD *) pvParam) = (UDWORD) (CC_is_in_autocommit(conn) ?
|
|
SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
|
|
break;
|
|
|
|
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
|
|
if (pvParam)
|
|
((char *) pvParam)[0] = ((char *) pvParam)[1] = '\0';
|
|
|
|
break;
|
|
|
|
case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */
|
|
*((UDWORD *) pvParam) = 0;
|
|
break;
|
|
|
|
case SQL_PACKET_SIZE: /* NOT SUPPORTED */
|
|
*((UDWORD *) pvParam) = ci->drivers.socket_buffersize;
|
|
break;
|
|
|
|
case SQL_QUIET_MODE: /* NOT SUPPORTED */
|
|
*((UDWORD *) pvParam) = (UDWORD) NULL;
|
|
break;
|
|
|
|
case SQL_TXN_ISOLATION: /* NOT SUPPORTED */
|
|
*((UDWORD *) pvParam) = SQL_TXN_READ_COMMITTED;
|
|
break;
|
|
|
|
/* These options should be handled by driver manager */
|
|
case SQL_ODBC_CURSORS:
|
|
case SQL_OPT_TRACE:
|
|
case SQL_OPT_TRACEFILE:
|
|
case SQL_TRANSLATE_DLL:
|
|
case SQL_TRANSLATE_OPTION:
|
|
CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn);
|
|
break;
|
|
|
|
default:
|
|
{
|
|
char option[64];
|
|
|
|
conn->errormsg = "Unknown connect option (Get)";
|
|
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
|
sprintf(option, "fOption=%d", fOption);
|
|
CC_log_error(func, option, conn);
|
|
return SQL_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return SQL_SUCCESS;
|
|
}
|
|
|
|
|
|
RETCODE SQL_API
|
|
PGAPI_SetStmtOption(
|
|
HSTMT hstmt,
|
|
UWORD fOption,
|
|
UDWORD vParam)
|
|
{
|
|
static char *func = "PGAPI_SetStmtOption";
|
|
StatementClass *stmt = (StatementClass *) hstmt;
|
|
|
|
mylog("%s: entering...\n", func);
|
|
|
|
/*
|
|
* Though we could fake Access out by just returning SQL_SUCCESS all
|
|
* the time, but it tries to set a huge value for SQL_MAX_LENGTH and
|
|
* expects the driver to reduce it to the real value.
|
|
*/
|
|
if (!stmt)
|
|
{
|
|
SC_log_error(func, "", NULL);
|
|
return SQL_INVALID_HANDLE;
|
|
}
|
|
|
|
return set_statement_option(NULL, stmt, fOption, vParam);
|
|
}
|
|
|
|
|
|
RETCODE SQL_API
|
|
PGAPI_GetStmtOption(
|
|
HSTMT hstmt,
|
|
UWORD fOption,
|
|
PTR pvParam)
|
|
{
|
|
static char *func = "PGAPI_GetStmtOption";
|
|
StatementClass *stmt = (StatementClass *) hstmt;
|
|
QResultClass *res;
|
|
ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
|
|
|
|
mylog("%s: entering...\n", func);
|
|
|
|
/*
|
|
* thought we could fake Access out by just returning SQL_SUCCESS all
|
|
* the time, but it tries to set a huge value for SQL_MAX_LENGTH and
|
|
* expects the driver to reduce it to the real value
|
|
*/
|
|
if (!stmt)
|
|
{
|
|
SC_log_error(func, "", NULL);
|
|
return SQL_INVALID_HANDLE;
|
|
}
|
|
|
|
switch (fOption)
|
|
{
|
|
case SQL_GET_BOOKMARK:
|
|
case SQL_ROW_NUMBER:
|
|
|
|
res = SC_get_Curres(stmt);
|
|
|
|
if (stmt->manual_result || !ci->drivers.use_declarefetch)
|
|
{
|
|
/* make sure we're positioned on a valid row */
|
|
if ((stmt->currTuple < 0) ||
|
|
(stmt->currTuple >= QR_get_num_tuples(res)))
|
|
{
|
|
stmt->errormsg = "Not positioned on a valid row.";
|
|
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
|
SC_log_error(func, "", stmt);
|
|
return SQL_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (stmt->currTuple == -1 || !res || !res->tupleField)
|
|
{
|
|
stmt->errormsg = "Not positioned on a valid row.";
|
|
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
|
SC_log_error(func, "", stmt);
|
|
return SQL_ERROR;
|
|
}
|
|
}
|
|
|
|
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
|
|
{
|
|
stmt->errormsg = "Operation invalid because use bookmarks not enabled.";
|
|
stmt->errornumber = STMT_OPERATION_INVALID;
|
|
SC_log_error(func, "", stmt);
|
|
return SQL_ERROR;
|
|
}
|
|
|
|
*((UDWORD *) pvParam) = SC_get_bookmark(stmt);
|
|
|
|
break;
|
|
|
|
case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
|
|
*((SDWORD *) pvParam) = SQL_ASYNC_ENABLE_OFF;
|
|
break;
|
|
|
|
case SQL_BIND_TYPE:
|
|
*((SDWORD *) pvParam) = SC_get_ARD(stmt)->bind_size;
|
|
break;
|
|
|
|
case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
|
|
mylog("GetStmtOption(): SQL_CONCURRENCY %d\n", stmt->options.scroll_concurrency);
|
|
*((SDWORD *) pvParam) = stmt->options.scroll_concurrency;
|
|
break;
|
|
|
|
case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
|
|
mylog("GetStmtOption(): SQL_CURSOR_TYPE %d\n", stmt->options.cursor_type);
|
|
*((SDWORD *) pvParam) = stmt->options.cursor_type;
|
|
break;
|
|
|
|
case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
|
|
mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
|
|
*((SDWORD *) pvParam) = stmt->options.keyset_size;
|
|
break;
|
|
|
|
case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
|
|
*((SDWORD *) pvParam) = stmt->options.maxLength;
|
|
break;
|
|
|
|
case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
|
|
*((SDWORD *) pvParam) = stmt->options.maxRows;
|
|
mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows);
|
|
break;
|
|
|
|
case SQL_NOSCAN: /* NOT SUPPORTED */
|
|
*((SDWORD *) pvParam) = SQL_NOSCAN_ON;
|
|
break;
|
|
|
|
case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
|
|
*((SDWORD *) pvParam) = 0;
|
|
break;
|
|
|
|
case SQL_RETRIEVE_DATA:
|
|
*((SDWORD *) pvParam) = stmt->options.retrieve_data;
|
|
break;
|
|
|
|
case SQL_ROWSET_SIZE:
|
|
*((SDWORD *) pvParam) = SC_get_ARD(stmt)->rowset_size;
|
|
break;
|
|
|
|
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
|
|
*((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
|
|
break;
|
|
|
|
case SQL_USE_BOOKMARKS:
|
|
*((SDWORD *) pvParam) = stmt->options.use_bookmarks;
|
|
break;
|
|
|
|
default:
|
|
{
|
|
char option[64];
|
|
|
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
|
stmt->errormsg = "Unknown statement option (Get)";
|
|
sprintf(option, "fOption=%d", fOption);
|
|
SC_log_error(func, option, stmt);
|
|
return SQL_ERROR;
|
|
}
|
|
}
|
|
|
|
return SQL_SUCCESS;
|
|
}
|