119
123
/* Copy default statement options based from Connection options */
120
124
stmt->options = stmt->options_orig = conn->stmtOptions;
121
stmt->ardopts = conn->ardOptions;
122
stmt->ardopts.bookmark = (BindInfoClass *) malloc(sizeof(BindInfoClass));
123
stmt->ardopts.bookmark->buffer = NULL;
124
stmt->ardopts.bookmark->used = NULL;
125
stmt->ardi.ardopts = conn->ardOptions;
126
ardopts = SC_get_ARDF(stmt);
127
bookmark = ARD_AllocBookmark(ardopts);
126
129
stmt->stmt_size_limit = CC_get_max_query_len(conn);
127
130
/* Save the handle for later */
213
* For Declare/Fetch, setting the parameters to close the cursor.
216
SC_set_handle(StatementClass *self,QResultClass *res)
218
res->conn = self->hdbc;
220
res->cursor = malloc(sizeof(self->cursor_name));
221
strcpy(res->cursor,self->cursor_name);
208
226
* StatementClass implementation
218
236
opt->cursor_type = SQL_CURSOR_FORWARD_ONLY;
219
237
opt->retrieve_data = SQL_RD_ON;
220
238
opt->use_bookmarks = SQL_UB_OFF;
221
#if (ODBCVER >= 0x0300)
222
239
opt->metadata_id = SQL_FALSE;
228
* ARDFields initialize
231
InitializeARDFields(ARDFields *opt)
233
memset(opt, 0, sizeof(ARDFields));
234
#if (ODBCVER >= 0x0300)
235
opt->size_of_rowset = 1;
237
opt->bind_size = 0; /* default is to bind by column */
238
opt->size_of_rowset_odbc2 = 1;
241
* APDFields initialize
244
InitializeAPDFields(APDFields *opt)
246
memset(opt, 0, sizeof(APDFields));
247
opt->paramset_size = 1;
248
opt->param_bind_type = 0; /* default is to bind by column */
255
246
StatementClass *rv;
248
mylog("SC_Constructor: entering ...\n");
257
249
rv = (StatementClass *) malloc(sizeof(StatementClass));
252
mylog("SC_Constructor: created stmt = %u\n",rv);
260
253
rv->hdbc = NULL; /* no connection associated yet */
261
254
rv->phstmt = NULL;
262
255
rv->result = NULL;
263
256
rv->curres = NULL;
264
rv->manual_result = FALSE;
257
rv->manual_result = TRUE;
265
258
rv->prepare = FALSE;
266
259
rv->prepared = FALSE;
267
260
rv->status = STMT_ALLOCATED;
268
261
rv->internal = FALSE;
269
262
rv->transition_status = 0;
263
rv->num_params = -1; /* unknown */
271
265
rv->__error_message = NULL;
272
266
rv->__error_number = 0;
273
267
rv->errormsg_created = FALSE;
268
rv->__sqlstate[0] = '\0';
275
270
rv->statement = NULL;
276
271
rv->stmt_with_params = NULL;
304
299
/* Clear Statement Options -- defaults will be set in AllocStmt */
305
300
memset(&rv->options, 0, sizeof(StatementOptions));
306
memset(&rv->ardopts, 0, sizeof(ARDFields));
307
memset(&rv->apdopts, 0, sizeof(APDFields));
308
memset(&rv->irdopts, 0, sizeof(IRDFields));
309
memset(&rv->ipdopts, 0, sizeof(IPDFields));
301
InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->ardi),
302
rv, SQL_ATTR_APP_ROW_DESC);
303
InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->apdi),
304
rv, SQL_ATTR_APP_PARAM_DESC);
305
InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->irdi),
306
rv, SQL_ATTR_IMP_ROW_DESC);
307
InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->ipdi),
308
rv, SQL_ATTR_IMP_PARAM_DESC);
311
310
rv->pre_executing = FALSE;
312
311
rv->inaccurate_result = FALSE;
315
314
rv->error_recsize = -1;
316
315
rv->diag_row_count = 0;
317
316
rv->stmt_time = 0;
317
rv->execute_delegate = NULL;
318
rv->allocated_callbacks = 0;
319
rv->num_callbacks = 0;
320
rv->callbacks = NULL;
321
GetDataInfoInitialize(SC_get_GDTI(rv));
322
PutDataInfoInitialize(SC_get_PDTI(rv));
318
323
INIT_STMT_CS(rv);
324
void ARDFields_free(ARDFields * self)
328
free(self->bookmark);
329
self->bookmark = NULL;
332
* the memory pointed to by the bindings is not deallocated by the
333
* driver but by the application that uses that driver, so we don't
336
ARD_unbind_cols(self, TRUE);
339
void APDFields_free(APDFields * self)
342
APD_free_params(self, STMT_FREE_PARAMS_ALL);
345
void IRDFields_free(IRDFields * self)
347
/* Free the parsed field information */
352
for (i = 0; i < (int) self->nfields; i++)
356
if (self->fi[i]->schema)
357
free(self->fi[i]->schema);
366
void IPDFields_free(IPDFields * self)
369
IPD_free_params(self, STMT_FREE_PARAMS_ALL);
373
329
SC_Destructor(StatementClass *self)
409
366
/* Free the parsed field information */
410
ARDFields_free(&(self->ardopts));
411
APDFields_free(&(self->apdopts));
412
IRDFields_free(&(self->irdopts));
413
IPDFields_free(&(self->ipdopts));
367
DC_Destructor((DescriptorClass *) SC_get_ARDi(self));
368
DC_Destructor((DescriptorClass *) SC_get_APDi(self));
369
DC_Destructor((DescriptorClass *) SC_get_IRDi(self));
370
DC_Destructor((DescriptorClass *) SC_get_IPDi(self));
415
372
if (self->__error_message)
416
373
free(self->__error_message);
374
cancelNeedDataState(self);
376
free(self->callbacks);
378
GDATA_unbind_cols(SC_get_GDTI(self), TRUE);
417
380
DELETE_STMT_CS(self);
381
if (self->pdata_info.pdata != 0)
382
free(self->pdata_info.pdata);
420
385
mylog("SC_Destructor: EXIT\n");
431
396
SC_free_params(StatementClass *self, char option)
433
APD_free_params(SC_get_APD(self), option);
434
IPD_free_params(SC_get_IPD(self), option);
398
if (option != STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY)
400
APD_free_params(SC_get_APDF(self), option);
401
IPD_free_params(SC_get_IPDF(self), option);
403
PDATA_free_params(SC_get_PDTI(self), option);
435
404
self->data_at_exec = -1;
436
405
self->current_exec_param = -1;
437
406
self->put_data = FALSE;
452
421
/* ignore leading whitespace in query string */
453
while (*statement && (isspace((unsigned char) *statement) || *statement == '('))
422
while (*statement && (isspace((UCHAR) *statement) || *statement == '('))
456
425
for (i = 0; Statement_Type[i].s; i++)
457
426
if (!strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))
458
427
return Statement_Type[i].type;
429
/* determine START TRANSACTION */
430
if (!strnicmp(statement, "START", 5))
433
/* ignore whitespace in query string */
434
while (*statement && isspace((UCHAR) *statement))
436
if (!strnicmp(statement, "TRANSACTION", 11))
437
return STMT_TYPE_BEGIN;
460
439
return STMT_TYPE_OTHER;
443
SC_set_current_col(StatementClass *stmt, int col)
445
if (col == stmt->current_col)
448
reset_a_getdata_info(SC_get_GDTI(stmt), col + 1);
449
stmt->current_col = col;
451
return stmt->current_col;
464
455
SC_set_prepared(StatementClass *stmt, BOOL prepared)
470
461
ConnectionClass *conn = SC_get_conn(stmt);
471
if (CONN_CONNECTED == conn->status)
463
if (conn && CONN_CONNECTED == conn->status)
474
char dealloc_stmt[128];
476
sprintf(dealloc_stmt, "DEALLOCATE _PLAN%0x", stmt);
477
res = CC_send_query(conn, dealloc_stmt, NULL, 0);
467
sprintf(plannm, "_PLAN%p", stmt);
468
if (CC_is_in_error_trans(conn))
470
CC_mark_a_plan_to_discard(conn, plannm);
475
char dealloc_stmt[128];
477
sprintf(dealloc_stmt, "DEALLOCATE \"%s\"", plannm);
478
res = CC_send_query(conn, dealloc_stmt, NULL, 0);
482
484
stmt->prepared = prepared;
502
504
free(self->execute_statement);
503
505
self->execute_statement = NULL;
505
SC_set_prepared(self,FALSE);
507
self->prepare = FALSE;
508
SC_set_prepared(self, FALSE);
509
self->statement_type = STMT_TYPE_UNKNOWN; /* unknown */
510
self->status = STMT_READY;
511
self->num_params = -1; /* unknown */
507
513
if (self->stmt_with_params)
527
BOOL SC_opencheck(StatementClass *self, const char *func)
531
if (self->status == STMT_EXECUTING)
533
SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.");
537
* We get here if a statement is prepared and executed to get the metadata.
539
if (self->prepare && self->status == STMT_PREMATURE)
541
mylog("SC_opencheck: self->prepare && self->status == STMT_PREMATURE\n");
545
if (res = SC_get_Curres(self), NULL != res)
547
if (res->backend_tuples)
549
SC_set_error(self, STMT_SEQUENCE_ERROR, "The cursor is open.");
550
SC_log_error(func, "", self);
559
SC_initialize_and_recycle(StatementClass *self)
561
SC_initialize_stmts(self, TRUE);
562
if (!SC_recycle_statement(self))
522
569
* Called from SQLPrepare if STMT_PREMATURE, or
523
570
* from SQLExecute if STMT_FINISHED, or
600
650
* Reset only parameters that have anything to do with results
602
652
self->status = STMT_READY;
603
self->manual_result = FALSE; /* very important */
653
self->manual_result = TRUE; /* very important */
605
654
self->currTuple = -1;
606
655
self->rowset_start = -1;
607
self->current_col = -1;
656
SC_set_current_col(self, -1);
608
657
self->bind_row = 0;
609
658
self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;
648
698
if (self->statement_type == STMT_TYPE_SELECT)
650
700
char old_pre_executing = self->pre_executing;
652
703
self->pre_executing = TRUE;
653
704
self->inaccurate_result = FALSE;
706
ret = PGAPI_Execute(self, 0);
657
708
self->pre_executing = old_pre_executing;
659
if (self->status == STMT_FINISHED)
710
if (self->status == STMT_FINISHED &&
711
(SQL_SUCCESS == ret ||
712
SQL_SUCCESS_WITH_INFO == ret))
661
714
mylog(" preprocess: after status = FINISHED, so set PREMATURE\n");
662
715
self->status = STMT_PREMATURE;
678
731
SC_unbind_cols(StatementClass *self)
680
ARDFields *opts = SC_get_ARD(self);
733
ARDFields *opts = SC_get_ARDF(self);
734
GetDataInfo *gdata = SC_get_GDTI(self);
735
BindInfoClass *bookmark;
682
737
ARD_unbind_cols(opts, FALSE);
683
opts->bookmark->buffer = NULL;
684
opts->bookmark->used = NULL;
738
GDATA_unbind_cols(gdata, FALSE);
739
if (bookmark = opts->bookmark, bookmark != NULL)
741
bookmark->buffer = NULL;
742
bookmark->used = NULL;
741
SocketClass *sock = conn->sock;
743
800
if (!detailmsg && CC_get_errormsg(conn) && (CC_get_errormsg(conn))[0] != '\0')
745
802
pos = strlen(msg);
746
803
sprintf(&msg[pos], ";\n%s", CC_get_errormsg(conn));
749
if (sock && sock->errormsg && sock->errormsg[0] != '\0')
752
sprintf(&msg[pos], ";\n%s", sock->errormsg);
755
808
return msg[0] ? strdup(msg) : NULL;
880
SC_set_sqlstate(StatementClass *self, const char *sqlstate)
883
snprintf(self->__sqlstate, SQLSTATE_LENGTH, "%s", sqlstate);
885
self->__sqlstate[0] = '\0';
889
SC_get_sqlstate(StatementClass *self)
891
return self->__sqlstate;
828
896
SC_get_time(StatementClass *stmt)
861
934
ColumnInfoClass *coli;
935
BindInfoClass *bookmark;
863
937
/* TupleField *tupleField; */
864
938
ConnInfo *ci = &(SC_get_conn(self)->connInfo);
866
940
self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;
942
/* Issue the fetch query here in case of declare fetch for subsequent rows */
943
if (SC_is_fetchcursor(self) && ((self->currTuple % ci->drivers.fetch_max) >= QR_get_num_total_tuples(res) - 1))
946
qi.cursor = self->cursor_name;
947
qi.row_size = ci->drivers.fetch_max;
948
sprintf(fetch, "fetch %d in %s",ci->drivers.fetch_max ,self->cursor_name);
950
/* Cleanup the QR. We need to kill off the cursor first, or this willcrash */
952
if (self->result->cursor)
954
free(self->result->cursor);
955
self->result->cursor = NULL;
960
QR_Destructor(self->result);
964
/* Finished cleanup */
966
res = CC_send_query(self->hdbc, fetch, &qi, qflag);
967
SC_set_Result(self,res);
867
970
coli = QR_get_fields(res); /* the column info */
869
971
mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch);
871
if (self->manual_result || !SC_is_fetchcursor(self))
973
if (self->manual_result)
873
if (self->currTuple >= QR_get_num_total_tuples(res) - 1 ||
874
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
877
* if at the end of the tuples, return "no data found" and set
878
* the cursor past the end of the result set
880
self->currTuple = QR_get_num_total_tuples(res);
881
return SQL_NO_DATA_FOUND;
975
if(!SC_is_fetchcursor(self))
977
if (self->currTuple >= QR_get_num_total_tuples(res) - 1 ||
978
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
981
* if at the end of the tuples, return "no data found" and set
982
* the cursor past the end of the result set
984
self->currTuple = QR_get_num_total_tuples(res);
985
return SQL_NO_DATA_FOUND;
990
if ((((self->currTuple + 1) % ci->drivers.fetch_max) >= QR_get_num_total_tuples(res)) &&
991
QR_get_num_total_tuples(res) < ci->drivers.fetch_max)
993
SC_no_fetchcursor(self);
994
self->currTuple = QR_get_num_total_tuples(res);
995
return SQL_NO_DATA_FOUND;
884
999
mylog("**** SC_fetch: manual_result\n");
921
1037
self->last_fetch_count++;
922
1038
self->last_fetch_count_include_ommitted++;
924
opts = SC_get_ARD(self);
1040
opts = SC_get_ARDF(self);
926
1042
* If the bookmark column was bound then return a bookmark. Since this
927
1043
* is used with SQLExtendedFetch, and the rowset size may be greater
928
1044
* than 1, and an application can use row or column wise binding, use
929
1045
* the code in copy_and_convert_field() to handle that.
931
if (opts->bookmark->buffer)
1047
if ((bookmark = opts->bookmark) && bookmark->buffer)
934
1050
UInt4 offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0;
936
sprintf(buf, "%ld", SC_get_bookmark(self));
937
result = copy_and_convert_field(self, 0, buf,
938
SQL_C_ULONG, opts->bookmark->buffer + offset, 0,
939
opts->bookmark->used ? opts->bookmark->used + (offset >> 2) : NULL);
1052
sprintf(buf, "%ld", (long int) SC_get_bookmark(self));
1053
SC_set_current_col(self, -1);
1054
result = copy_and_convert_field(self, 0, buf, SQL_C_ULONG,
1055
bookmark->buffer + offset, 0,
1056
(SDWORD *) (bookmark->used ? bookmark->used + (offset >> 2) : NULL));
942
1059
if (self->options.retrieve_data == SQL_RD_OFF) /* data isn't required */
943
1060
return SQL_SUCCESS;
1061
gdata = SC_get_GDTI(self);
1062
if (gdata->allocated != opts->allocated)
1063
extend_getdata_info(gdata, opts->allocated, TRUE);
944
1064
for (lf = 0; lf < num_cols; lf++)
946
1066
mylog("fetch: cols=%d, lf=%d, opts = %u, opts->bindings = %u, buffer[] = %u\n", num_cols, lf, opts, opts->bindings, opts->bindings[lf].buffer);
948
1068
/* reset for SQLGetData */
949
opts->bindings[lf].data_left = -1;
1069
gdata->gdata[lf].data_left = -1;
951
1071
if (opts->bindings[lf].buffer != NULL)
960
1080
if (self->manual_result)
962
value = QR_get_value_manual(res, self->currTuple, lf);
1082
if ((ci->drivers.use_declarefetch) && (self->currTuple >= QR_get_num_total_tuples(res)))
1083
value = QR_get_value_manual(res, (self->currTuple >= ci->drivers.fetch_max) ? (self->currTuple % ci->drivers.fetch_max) : self->currTuple, lf);
1085
value = QR_get_value_manual(res, self->currTuple, lf);
963
1086
mylog("manual_result\n");
965
1088
else if (SC_is_fetchcursor(self))
1149
#define return DONT_CALL_RETURN_FROM_HERE???
1028
1152
SC_execute(StatementClass *self)
1030
1154
CSTR func = "SC_execute";
1031
1155
ConnectionClass *conn;
1033
char was_ok, was_nonfatal, was_rows_affected = 1;
1034
/* was_rows_affected is set to 0 iff an UPDATE or DELETE affects
1035
* no rows. In this instance the driver should return
1036
* SQL_NO_DATA_FOUND instead of SQL_SUCCESS.
1157
char was_ok, was_nonfatal;
1039
1158
QResultClass *res = NULL;
1040
1159
Int2 oldstatus,
1044
1163
UDWORD qflag = 0;
1045
BOOL auto_begin = FALSE, is_in_trans;
1165
int func_cs_count = 0;
1048
1168
conn = SC_get_conn(self);
1058
1178
* 2) we are in autocommit off state and the statement isn't of type
1061
ENTER_CONN_CS(conn);
1181
ENTER_INNER_CONN_CS(conn, func_cs_count);
1062
1182
if (CONN_EXECUTING == conn->status)
1064
LEAVE_CONN_CS(conn);
1065
1184
SC_set_error(self, STMT_SEQUENCE_ERROR, "Connection is already in use.");
1066
SC_log_error(func, "", self);
1067
1185
mylog("%s: problem with connection\n", func);
1070
1188
is_in_trans = CC_is_in_trans(conn);
1071
1189
if (!self->internal && !is_in_trans &&
1072
1190
(SC_is_fetchcursor(self) ||
1073
(!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER)))
1191
(!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_BEGIN)))
1075
1193
mylog(" about to begin a transaction on statement = %u\n", self);
1077
1194
if (PG_VERSION_GE(conn, 7.1))
1078
1195
qflag |= GO_INTO_TRANSACTION;
1079
else if (!CC_begin(conn))
1081
LEAVE_CONN_CS(conn);
1196
else if (!CC_begin(conn))
1082
1198
SC_set_error(self, STMT_EXEC_ERROR, "Could not begin a transaction");
1083
SC_log_error(func, "", self);
1088
1203
oldstatus = conn->status;
1159
1274
if (CONN_DOWN != conn->status)
1160
1275
conn->status = oldstatus;
1161
1276
self->status = STMT_FINISHED;
1162
LEAVE_CONN_CS(conn);
1277
LEAVE_INNER_CONN_CS(func_cs_count, conn);
1164
1279
/* Check the status of the result */
1167
1282
was_ok = QR_command_successful(res);
1168
1283
was_nonfatal = QR_command_nonfatal(res);
1170
(strncmp(res->command, "UPDATE", 6) == 0 ||
1171
strncmp(res->command, "DELETE", 6) == 0) &&
1172
strtoul(res->command + 7, NULL, 0) == 0)
1174
was_rows_affected = 0;
1178
1286
SC_set_errornumber(self, STMT_OK);
1180
1288
SC_set_errornumber(self, was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND);
1290
if (QR_command_fatal(res) && PQstatus(conn->pgconn) == CONNECTION_BAD)
1291
SC_set_errornumber(self, STMT_BAD_ERROR);
1293
if (SC_get_errornumber(self) == STMT_ERROR_TAKEN_FROM_BACKEND)
1294
SC_set_sqlstate(self, CC_get_sqlstate(conn));
1182
1296
/* set cursor before the first tuple in the list */
1183
1297
self->currTuple = -1;
1184
self->current_col = -1;
1298
SC_set_current_col(self, -1);
1185
1299
self->rowset_start = -1;
1187
1301
/* issue "ABORT" when query aborted */
1188
1302
if (QR_get_aborted(res))
1190
if (!self->internal)
1304
if (!self->internal && CC_is_in_trans(conn) && CC_is_in_autocommit(conn) && !CC_is_in_manual_trans(conn))
1191
1305
CC_abort(conn);
1307
QR_set_aborted(res, FALSE);
1202
1318
/* now allocate the array to hold the binding info */
1203
1319
if (numcols > 0)
1205
ARDFields *opts = SC_get_ARD(self);
1321
ARDFields *opts = SC_get_ARDF(self);
1206
1322
extend_column_bindings(opts, numcols);
1207
1323
if (opts->bindings == NULL)
1209
1325
QR_Destructor(res);
1210
1326
SC_set_error(self, STMT_NO_MEMORY_ERROR,"Could not get enough free memory to store the binding information");
1211
SC_log_error(func, "", self);
1219
1334
/* Bad Error -- The error message will be in the Connection */
1221
SC_set_error(self, STMT_BAD_ERROR, CC_get_errormsg(conn));
1336
SC_set_error(self, STMT_BAD_ERROR, CC_get_errormsg(conn));
1222
1337
else if (self->statement_type == STMT_TYPE_CREATE)
1224
1339
SC_set_error(self, STMT_CREATE_TABLE_ERROR, "Error creating the table");
1248
1363
last->next = res;
1251
apdopts = SC_get_APD(self);
1366
ipdopts = SC_get_IPDF(self);
1252
1367
if (self->statement_type == STMT_TYPE_PROCCALL &&
1253
1368
(SC_get_errornumber(self) == STMT_OK ||
1254
1369
SC_get_errornumber(self) == STMT_INFO_ONLY) &&
1255
apdopts->parameters &&
1256
apdopts->parameters[0].buffer &&
1257
apdopts->parameters[0].paramType == SQL_PARAM_OUTPUT)
1370
ipdopts->parameters &&
1371
ipdopts->parameters[0].paramType == SQL_PARAM_OUTPUT)
1258
1372
{ /* get the return value of the procedure
1263
1377
ret = SC_fetch(hstmt);
1264
1378
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
1266
ret = PGAPI_GetData(hstmt, 1, apdopts->parameters[0].CType, apdopts->parameters[0].buffer, apdopts->parameters[0].buflen, apdopts->parameters[0].used);
1380
APDFields *apdopts = SC_get_APDF(self);
1382
ret = PGAPI_GetData(hstmt, 1,
1383
apdopts->parameters[0].CType,
1384
apdopts->parameters[0].buffer,
1385
apdopts->parameters[0].buflen,
1386
(SDWORD *) apdopts->parameters[0].used);
1267
1387
if (ret != SQL_SUCCESS)
1269
1389
SC_set_error(self, STMT_EXEC_ERROR, "GetData to Procedure return failed.");
1274
1394
SC_set_error(self, STMT_EXEC_ERROR, "SC_fetch to get a Procedure return failed.");
1399
CLEANUP_FUNC_CONN_CS(func_cs_count, conn);
1277
1400
if (SC_get_errornumber(self) == STMT_OK)
1278
if (was_rows_affected)
1281
return SQL_NO_DATA_FOUND;
1282
1402
else if (SC_get_errornumber(self) == STMT_INFO_ONLY)
1283
1403
return SQL_SUCCESS_WITH_INFO;
1413
#define CALLBACK_ALLOC_ONCE 4
1414
int enqueueNeedDataCallback(StatementClass *stmt, NeedDataCallfunc func, void *data)
1416
if (stmt->num_callbacks >= stmt->allocated_callbacks)
1418
SC_REALLOC_return_with_error(stmt->callbacks, NeedDataCallback,
1419
sizeof(NeedDataCallback) * (stmt->allocated_callbacks +
1420
CALLBACK_ALLOC_ONCE), stmt,
1421
"Couldn't alloc callbacks", -1)
1422
stmt->allocated_callbacks += CALLBACK_ALLOC_ONCE;
1424
stmt->callbacks[stmt->num_callbacks].func = func;
1425
stmt->callbacks[stmt->num_callbacks].data = data;
1426
stmt->num_callbacks++;
1428
inolog("enqueueNeedDataCallack stmt=%x, func=%x, count=%d\n", stmt, func, stmt->num_callbacks);
1429
return stmt->num_callbacks;
1432
RETCODE dequeueNeedDataCallback(RETCODE retcode, StatementClass *stmt)
1435
NeedDataCallfunc func;
1439
mylog("dequeueNeedDataCallback ret=%d count=%d\n", retcode, stmt->num_callbacks);
1440
if (SQL_NEED_DATA == retcode)
1442
if (stmt->num_callbacks <= 0)
1444
func = stmt->callbacks[0].func;
1445
data = stmt->callbacks[0].data;
1446
for (i = 1; i < stmt->num_callbacks; i++)
1447
stmt->callbacks[i - 1] = stmt->callbacks[i];
1448
cnt = --stmt->num_callbacks;
1449
ret = (*func)(retcode, data);
1451
if (SQL_NEED_DATA != ret && cnt > 0)
1452
ret = dequeueNeedDataCallback(ret, stmt);
1456
void cancelNeedDataState(StatementClass *stmt)
1458
int cnt = stmt->num_callbacks, i;
1460
stmt->num_callbacks = 0;
1461
for (i = 0; i < cnt; i++)
1463
if (stmt->callbacks[i].data)
1464
free(stmt->callbacks[i].data);
1466
stmt->execute_delegate = NULL;
1295
1470
SC_log_error(const char *func, const char *desc, const StatementClass *self)
1302
1477
QResultClass *res = SC_get_Result(self);
1303
const ARDFields *opts = SC_get_ARD(self);
1304
const APDFields *apdopts = SC_get_APD(self);
1478
const ARDFields *opts = SC_get_ARDF(self);
1479
const APDFields *apdopts = SC_get_APDF(self);
1305
1480
int rowsetSize;
1307
#if (ODBCVER >= 0x0300)
1308
1482
rowsetSize = (7 == self->transition_status ? opts->size_of_rowset_odbc2 : opts->size_of_rowset);
1310
rowsetSize = opts->size_of_rowset_odbc2;
1311
#endif /* ODBCVER */
1312
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message));
1313
mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message));
1484
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, sqlstate=%s, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__sqlstate), nullcheck(self->__error_message));
1485
mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, sqlstate=%s, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__sqlstate), nullcheck(self->__error_message));
1314
1486
qlog(" ------------------------------------------------------------\n");
1315
1487
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, res);
1316
1488
qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal);