19 Star 39 Fork 46

openGauss / openGauss-connector-odbc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
options.c 19.65 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
/*--------
* 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 "readme.txt" for copyright and license information.
*--------
*/
#include "psqlodbc.h"
#include "unicode_support.h"
#include <string.h>
#include "misc.h"
#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "qresult.h"
#include "pgapifunc.h"
static RETCODE
set_statement_option(ConnectionClass *conn,
StatementClass *stmt,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "set_statement_option";
char changed = FALSE;
ConnInfo *ci = NULL;
SQLULEN setval;
if (conn)
ci = &(conn->connInfo);
else
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 = (SQLUINTEGER) vParam;
if (stmt)
SC_get_ARDF(stmt)->bind_size = (SQLUINTEGER) vParam;
break;
case SQL_CONCURRENCY:
/*
* positioned update isn't supported so cursor concurrency is
* read-only
*/
MYLOG(0, "SQL_CONCURRENCY = " FORMAT_LEN " ", vParam);
setval = SQL_CONCUR_READ_ONLY;
if (SQL_CONCUR_READ_ONLY == vParam)
;
else if (ci->drivers.lie)
setval = vParam;
else if (0 != ci->updatable_cursors)
setval = SQL_CONCUR_ROWVER;
if (conn)
conn->stmtOptions.scroll_concurrency = (SQLUINTEGER) setval;
else if (stmt)
{
if (SC_get_Result(stmt))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);
return SQL_ERROR;
}
stmt->options.scroll_concurrency =
stmt->options_orig.scroll_concurrency = (SQLUINTEGER) setval;
}
if (setval != vParam)
changed = TRUE;
MYPRINTF(0, "-> " FORMAT_LEN "\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(0, "SQL_CURSOR_TYPE = " FORMAT_LEN " ", vParam);
setval = SQL_CURSOR_FORWARD_ONLY;
if (ci->drivers.lie)
setval = vParam;
else if (SQL_CURSOR_STATIC == vParam)
setval = vParam;
else if (SQL_CURSOR_KEYSET_DRIVEN == vParam)
{
if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
setval = vParam;
else
setval = SQL_CURSOR_STATIC; /* at least scrollable */
}
else if (SQL_CURSOR_DYNAMIC == vParam)
{
if (0 != (ci->updatable_cursors & ALLOW_DYNAMIC_CURSORS))
setval = vParam;
else if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
setval = SQL_CURSOR_KEYSET_DRIVEN;
else
setval = SQL_CURSOR_STATIC; /* at least scrollable */
}
if (conn)
conn->stmtOptions.cursor_type = (SQLUINTEGER) setval;
else if (stmt)
{
if (SC_get_Result(stmt))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);
return SQL_ERROR;
}
stmt->options_orig.cursor_type =
stmt->options.cursor_type = (SQLUINTEGER) setval;
}
if (setval != vParam)
changed = TRUE;
MYPRINTF(0, "-> " FORMAT_LEN "\n", setval);
break;
case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
MYLOG(0, "SQL_KEYSET_SIZE, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.keyset_size = vParam;
if (stmt)
{
stmt->options_orig.keyset_size = vParam;
if (!SC_get_Result(stmt))
stmt->options.keyset_size = vParam;
if (stmt->options.keyset_size != (SQLLEN) vParam)
changed = TRUE;
}
break;
case SQL_MAX_LENGTH: /* ignored, but saved */
MYLOG(0, "SQL_MAX_LENGTH, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.maxLength = vParam;
if (stmt)
{
stmt->options_orig.maxLength = vParam;
if (!SC_get_Result(stmt))
stmt->options.maxLength = vParam;
if (stmt->options.maxLength != (SQLLEN) vParam)
changed = TRUE;
}
break;
case SQL_MAX_ROWS: /* ignored, but saved */
MYLOG(0, "SQL_MAX_ROWS, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.maxRows = vParam;
if (stmt)
{
stmt->options_orig.maxRows = vParam;
if (!SC_get_Result(stmt))
stmt->options.maxRows = vParam;
if (stmt->options.maxRows != (SQLLEN)vParam)
changed = TRUE;
}
break;
case SQL_NOSCAN: /* ignored */
MYLOG(0, "SQL_NOSCAN, vParam = " FORMAT_LEN "\n", vParam);
break;
case SQL_QUERY_TIMEOUT: /* ignored */
MYLOG(0, "SQL_QUERY_TIMEOUT, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.stmt_timeout = (SQLULEN) vParam;
if (stmt)
{
stmt->options.stmt_timeout = (SQLULEN) vParam;
stmt->options.timeout = (SQLUINTEGER)vParam;
}
break;
case SQL_RETRIEVE_DATA:
MYLOG(0, "SQL_RETRIEVE_DATA, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.retrieve_data = (SQLUINTEGER) vParam;
if (stmt)
stmt->options.retrieve_data = (SQLUINTEGER) vParam;
break;
case SQL_ROWSET_SIZE:
MYLOG(0, "SQL_ROWSET_SIZE, vParam = " FORMAT_LEN "\n", vParam);
if (vParam < 1)
{
vParam = 1;
changed = TRUE;
}
if (conn)
conn->ardOptions.size_of_rowset_odbc2 = vParam;
if (stmt)
SC_get_ARDF(stmt)->size_of_rowset_odbc2 = vParam;
break;
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
if (stmt)
{
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library.", func);
}
if (conn)
{
CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library.", func);
}
return SQL_ERROR;
case SQL_USE_BOOKMARKS:
if (stmt)
{
MYLOG(0, "USE_BOOKMARKS %s\n", (vParam == SQL_UB_OFF) ? "off" : ((vParam == SQL_UB_VARIABLE) ? "variable" : "fixed"));
setval = vParam;
stmt->options.use_bookmarks = (SQLUINTEGER) setval;
}
if (conn)
conn->stmtOptions.use_bookmarks = (SQLUINTEGER) vParam;
break;
case 1204: /* SQL_COPT_SS_PRESERVE_CURSORS ? */
if (stmt)
{
SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
else if (conn)
{
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
return SQL_ERROR;
case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
if (stmt)
{
#ifndef NOT_USED
if (0 != vParam)
changed = TRUE;
break;
#else
SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
#endif /* NOT_USED */
}
else if (conn)
{
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
return SQL_ERROR;
default:
{
char option[64];
if (stmt)
{
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN, fOption, vParam);
SC_log_error(func, option, stmt);
}
if (conn)
{
CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN, fOption, vParam);
CC_log_error(func, option, conn);
}
return SQL_ERROR;
}
}
if (changed)
{
if (stmt)
{
SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "Requested value changed.", func);
}
if (conn)
{
CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.", func);
}
return SQL_SUCCESS_WITH_INFO;
}
else
return SQL_SUCCESS;
}
/* Implements only SQL_AUTOCOMMIT */
RETCODE SQL_API
PGAPI_SetConnectOption(HDBC hdbc,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "PGAPI_SetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
char changed = FALSE;
RETCODE retval;
BOOL autocomm_on;
MYLOG(0, "entering fOption = %d vParam = " FORMAT_LEN "\n", 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:
/*
* 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:
switch (vParam)
{
case SQL_AUTOCOMMIT_ON:
autocomm_on = TRUE;
break;
case SQL_AUTOCOMMIT_OFF:
autocomm_on = FALSE;
break;
default:
CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT", func);
return SQL_ERROR;
}
if (autocomm_on && SQL_AUTOCOMMIT_OFF != conn->autocommit_public)
break;
else if (!autocomm_on && SQL_AUTOCOMMIT_OFF == conn->autocommit_public)
break;
conn->autocommit_public = (autocomm_on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
MYLOG(0, "AUTOCOMMIT: transact_status=%d, vparam=" FORMAT_LEN "\n", conn->transact_status, vParam);
#ifdef _HANDLE_ENLIST_IN_DTC_
if (CC_is_in_global_trans(conn))
{
CC_set_error(conn, CONN_ILLEGAL_TRANSACT_STATE, "Don't change AUTOCOMMIT mode in a distributed transaction", func);
return SQL_ERROR;
}
#endif /* _HANDLE_ENLIST_IN_DTC_ */
CC_set_autocommit(conn, autocomm_on);
break;
case SQL_CURRENT_QUALIFIER: /* ignored */
break;
case SQL_LOGIN_TIMEOUT:
conn->login_timeout = (SQLUINTEGER) vParam;
break;
case SQL_PACKET_SIZE: /* ignored */
break;
case SQL_QUIET_MODE: /* ignored */
break;
case SQL_TXN_ISOLATION:
if (conn->isolation == vParam)
break;
/*
* If the connection is not established, just record the setting to
* reflect it upon connection.
*/
if (CC_not_connected(conn))
{
conn->isolation = (UInt4) vParam;
break;
}
/* The ODBC spec prohibits changing the isolation level while in manual transaction. */
if (CC_is_in_trans(conn))
{
if (CC_does_autocommit(conn) && !CC_is_in_error_trans(conn))
CC_commit(conn);
else
{
CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch isolation level while a transaction is in progress", func);
return SQL_ERROR;
}
}
if (!CC_set_transact(conn, (UInt4) vParam))
return SQL_ERROR;
conn->isolation = (UInt4) vParam;
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];
CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_LEN, fOption, vParam);
#ifdef WIN32
if (fOption == 30002 && vParam)
{
int cmp;
#ifdef UNICODE_SUPPORT
if (CC_is_in_unicode_driver(conn))
{
char *asPara = ucs2_to_utf8((SQLWCHAR *) vParam, SQL_NTS, NULL, FALSE);
cmp = strcmp(asPara, "Microsoft Jet");
free(asPara);
}
else
#endif /* UNICODE_SUPPORT */
cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
if (0 == cmp)
{
MYLOG(0, "Microsoft Jet !!!!\n");
CC_set_errornumber(conn, 0);
conn->ms_jet = 1;
return SQL_SUCCESS;
}
}
#endif /* WIN32 */
CC_log_error(func, option, conn);
return SQL_ERROR;
}
}
if (changed)
{
CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.", func);
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,
SQLUSMALLINT fOption,
PTR pvParam,
SQLINTEGER *StringLength,
SQLINTEGER BufferLength)
{
CSTR func = "PGAPI_GetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
const char *p = NULL;
SQLLEN len = sizeof(SQLINTEGER);
SQLRETURN result = SQL_SUCCESS;
MYLOG(0, "entering...\n");
if (!conn)
{
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
switch (fOption)
{
case SQL_ACCESS_MODE: /* NOT SUPPORTED */
*((SQLUINTEGER *) pvParam) = SQL_MODE_READ_WRITE;
break;
case SQL_AUTOCOMMIT:
*((SQLUINTEGER *) pvParam) = conn->autocommit_public;
break;
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
len = 0;
p = CurrCatString(conn);
break;
case SQL_LOGIN_TIMEOUT:
*((SQLUINTEGER *) pvParam) = conn->login_timeout;
break;
case SQL_PACKET_SIZE: /* NOT SUPPORTED */
*((SQLUINTEGER *) pvParam) = 4096;
break;
case SQL_QUERY_TIMEOUT:
*((SQLULEN *) pvParam) = conn->stmtOptions.stmt_timeout;
break;
case SQL_QUIET_MODE: /* NOT SUPPORTED */
*((SQLULEN *) pvParam) = 0;
break;
case SQL_TXN_ISOLATION:
if (conn->isolation == 0)
{
if (CC_not_connected(conn))
return SQL_NO_DATA;
conn->isolation = CC_get_isolation(conn);
}
*((SQLUINTEGER *) pvParam) = conn->isolation;
break;
#ifdef SQL_ATTR_CONNECTION_DEAD
case SQL_ATTR_CONNECTION_DEAD:
#else
case 1209:
#endif /* SQL_ATTR_CONNECTION_DEAD */
MYLOG(0, "CONNECTION_DEAD status=%d", conn->status);
*((SQLUINTEGER *) pvParam) = CC_not_connected(conn);
MYPRINTF(0, " val=%d\n", *((SQLUINTEGER *) pvParam));
break;
case SQL_ATTR_ANSI_APP:
*((SQLUINTEGER *) pvParam) = CC_is_in_ansi_app(conn);
MYLOG(0, "ANSI_APP val=%d\n", *((SQLUINTEGER *) pvParam));
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];
CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Get)", func);
SPRINTF_FIXED(option, "fOption=%d", fOption);
CC_log_error(func, option, conn);
return SQL_ERROR;
break;
}
}
if (NULL != p && 0 == len)
{
/* char/binary data */
len = strlen(p);
if (pvParam)
{
#ifdef UNICODE_SUPPORT
if (CC_is_in_unicode_driver(conn))
{
len = utf8_to_ucs2(p, len, (SQLWCHAR *) pvParam , BufferLength / WCLEN);
len *= WCLEN;
}
else
#endif /* UNICODE_SUPPORT */
strncpy_null((char *) pvParam, p, (size_t) BufferLength);
if (len >= BufferLength)
{
result = SQL_SUCCESS_WITH_INFO;
CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the pvParam.", func);
}
}
}
if (StringLength)
*StringLength = (SQLINTEGER) len;
return result;
}
RETCODE SQL_API
PGAPI_SetStmtOption(HSTMT hstmt,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "PGAPI_SetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt;
RETCODE retval;
MYLOG(0, " entering...\n");
/*
* 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;
}
retval = set_statement_option(NULL, stmt, fOption, vParam);
return retval;
}
RETCODE SQL_API
PGAPI_GetStmtOption(HSTMT hstmt,
SQLUSMALLINT fOption,
PTR pvParam,
SQLINTEGER *StringLength,
SQLINTEGER BufferLength)
{
CSTR func = "PGAPI_GetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *res;
SQLLEN ridx;
SQLINTEGER len = sizeof(SQLINTEGER);
Int4 bookmark;
MYLOG(0, "entering...\n");
/*
* 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 (!res)
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The cursor has no result.", func);
return SQL_ERROR;
}
ridx = GIdx2CacheIdx(stmt->currTuple, stmt, res);
if (!SC_is_fetchcursor(stmt))
{
/* make sure we're positioned on a valid row */
if ((ridx < 0) ||
(((SQLULEN) ridx) >= QR_get_num_cached_tuples(res)))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.", func);
return SQL_ERROR;
}
}
else
{
if (stmt->currTuple < 0 || !res->tupleField)
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.", func);
return SQL_ERROR;
}
}
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
{
SC_set_error(stmt, STMT_OPERATION_INVALID, "Operation invalid because use bookmarks not enabled.", func);
return SQL_ERROR;
}
bookmark = SC_make_int4_bookmark(stmt->currTuple);
memcpy(pvParam, &bookmark, sizeof(UInt4));
break;
case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_ASYNC_ENABLE_OFF;
break;
case SQL_BIND_TYPE:
*((SQLINTEGER *) pvParam) = SC_get_ARDF(stmt)->bind_size;
break;
case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
MYLOG(0, "SQL_CONCURRENCY %d\n", stmt->options.scroll_concurrency);
*((SQLINTEGER *) pvParam) = stmt->options.scroll_concurrency;
break;
case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
MYLOG(0, "SQL_CURSOR_TYPE %d\n", stmt->options.cursor_type);
*((SQLINTEGER *) pvParam) = stmt->options.cursor_type;
break;
case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
MYLOG(0, "SQL_KEYSET_SIZE\n");
*((SQLLEN *) pvParam) = stmt->options.keyset_size;
break;
case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
*((SQLLEN *) pvParam) = stmt->options.maxLength;
break;
case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
*((SQLLEN *) pvParam) = stmt->options.maxRows;
MYLOG(0, "MAX_ROWS, returning " FORMAT_LEN "\n", stmt->options.maxRows);
break;
case SQL_NOSCAN: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_NOSCAN_ON;
break;
case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
*((SQLULEN *) pvParam) = stmt->options.stmt_timeout;
break;
case SQL_RETRIEVE_DATA:
*((SQLINTEGER *) pvParam) = stmt->options.retrieve_data;
break;
case SQL_ROWSET_SIZE:
*((SQLLEN *) pvParam) = SC_get_ARDF(stmt)->size_of_rowset_odbc2;
break;
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_SC_NON_UNIQUE;
break;
case SQL_USE_BOOKMARKS:
*((SQLINTEGER *) pvParam) = stmt->options.use_bookmarks;
break;
case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
*((SQLINTEGER *) pvParam) = 0;
break;
default:
{
char option[64];
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Get)", func);
SPRINTF_FIXED(option, "fOption=%d", fOption);
SC_log_error(func, option, stmt);
return SQL_ERROR;
}
}
if (StringLength)
*StringLength = len;
return SQL_SUCCESS;
}
C
1
https://gitee.com/opengauss/openGauss-connector-odbc.git
git@gitee.com:opengauss/openGauss-connector-odbc.git
opengauss
openGauss-connector-odbc
openGauss-connector-odbc
master

搜索帮助