2 Star 0 Fork 0

Chan-i / psqlodbc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
pgapi30.c 59.93 KB
一键复制 编辑 原始数据 按行查看 历史
foxi 提交于 2022-11-07 10:19 . SQLGetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165
/*-------
* 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 (!res)
return SQL_ERROR;*/
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;
MYLOG(0, "entering " FORMAT_INTEGER "\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;
case SQL_ATTR_PGOPT_BATCHSIZE:
*((SQLINTEGER *) Value) = conn->connInfo.batch_size;
break;
case SQL_ATTR_PGOPT_IGNORETIMEOUT:
*((SQLINTEGER *) Value) = conn->connInfo.ignore_timeout;
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);
/* 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:
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:
rettype = 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;
if (Value == NULL)
{
SC_log_error(func, NULL_STRING, NULL);
return SQL_ERROR;
}
MYLOG(0, "entering Handle=%p " FORMAT_INTEGER "\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)
#ifdef SBZW
*((SQLUINTEGER *) Value) = SQL_SCROLLABLE;
#else
*((SQLUINTEGER *) Value) = SQL_NONSCROLLABLE;
#endif
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: " FORMAT_INTEGER " %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_ERROR;*/
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;
case SQL_ATTR_PGOPT_BATCHSIZE:
conn->connInfo.batch_size = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "batch size => %d\n", conn->connInfo.batch_size);
break;
case SQL_ATTR_PGOPT_IGNORETIMEOUT:
conn->connInfo.ignore_timeout = CAST_PTR(SQLINTEGER, Value);
MYLOG(0, "ignore_timeout => %d\n", conn->connInfo.ignore_timeout);
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=" FORMAT_SMALLI " field=" FORMAT_SMALLI " blen=" FORMAT_INTEGER "\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=" FORMAT_SMALLI " field=" FORMAT_SMALLI " val=%p," FORMAT_INTEGER "\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;
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 " FORMAT_INTEGER "," FORMAT_ULEN "(%p)\n", StatementHandle, Attribute, (SQLULEN) Value, Value);
if (Value == NULL)
{
return SQL_ERROR;
}
switch (Attribute)
{
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
if (SQL_FALSE == Value)
break;
#ifndef SBZW
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
#endif
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;
#ifdef SBZW
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
break;
#endif
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;
}
}
/* StartRollbackState(s.stmt); */
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;
}
1
https://gitee.com/Moeah/psqlodbc.git
git@gitee.com:Moeah/psqlodbc.git
Moeah
psqlodbc
psqlodbc
develop-15s-bug

搜索帮助