19 Star 39 Fork 46

openGauss / openGauss-connector-odbc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
pgapi30.c 58.82 KB
一键复制 编辑 原始数据 按行查看 历史
zhangxubo 提交于 2022-03-11 17:10 . add 3.0.0 patch file
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125
/*-------
* 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;
}
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

搜索帮助