4
* Description: This module contains functions related to creating
5
* and manipulating a statement.
7
* Classes: StatementClass (Functions prefix: "SC_")
9
* API functions: SQLAllocStmt, SQLFreeStmt
11
* Comments: See "notice.txt" for copyright and license information.
15
#include "statement.h"
18
#include "connection.h"
27
#include "pgapifunc.h"
33
/* Map sql commands to statement types */
42
STMT_TYPE_SELECT, "SELECT"
45
STMT_TYPE_INSERT, "INSERT"
48
STMT_TYPE_UPDATE, "UPDATE"
51
STMT_TYPE_DELETE, "DELETE"
54
STMT_TYPE_CREATE, "CREATE"
57
STMT_TYPE_ALTER, "ALTER"
60
STMT_TYPE_DROP, "DROP"
63
STMT_TYPE_GRANT, "GRANT"
66
STMT_TYPE_REVOKE, "REVOKE"
69
STMT_TYPE_PROCCALL, "{"
72
STMT_TYPE_LOCK, "LOCK"
81
PGAPI_AllocStmt(HDBC hdbc,
84
CSTR func = "PGAPI_AllocStmt";
85
ConnectionClass *conn = (ConnectionClass *) hdbc;
88
mylog("%s: entering...\n", func);
92
CC_log_error(func, "", NULL);
93
return SQL_INVALID_HANDLE;
96
stmt = SC_Constructor();
98
mylog("**** PGAPI_AllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt);
102
CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "No more memory to allocate a further SQL-statement");
103
*phstmt = SQL_NULL_HSTMT;
104
CC_log_error(func, "", conn);
108
if (!CC_add_statement(conn, stmt))
110
CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "Maximum number of connections exceeded.");
111
CC_log_error(func, "", conn);
113
*phstmt = SQL_NULL_HSTMT;
117
*phstmt = (HSTMT) stmt;
119
/* Copy default statement options based from Connection options */
120
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;
126
stmt->stmt_size_limit = CC_get_max_query_len(conn);
127
/* Save the handle for later */
128
stmt->phstmt = phstmt;
135
PGAPI_FreeStmt(HSTMT hstmt,
138
CSTR func = "PGAPI_FreeStmt";
139
StatementClass *stmt = (StatementClass *) hstmt;
141
mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption);
145
SC_log_error(func, "", NULL);
146
return SQL_INVALID_HANDLE;
148
SC_clear_error(stmt);
150
if (fOption == SQL_DROP)
152
ConnectionClass *conn = stmt->hdbc;
154
/* Remove the statement from the connection's statement list */
159
if (!CC_remove_statement(conn, stmt))
161
SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.");
162
SC_log_error(func, "", stmt);
163
return SQL_ERROR; /* stmt may be executing a
167
/* Free any cursors and discard any result info */
168
if (res = SC_get_Result(stmt), res)
171
SC_set_Result(stmt, NULL);
175
/* Destroy the statement and free any results, cursors, etc. */
178
else if (fOption == SQL_UNBIND)
179
SC_unbind_cols(stmt);
180
else if (fOption == SQL_CLOSE)
183
* this should discard all the results, but leave the statement
184
* itself in place (it can be executed again)
186
stmt->transition_status = 0;
187
if (!SC_recycle_statement(stmt))
189
/* errormsg passed in above */
190
SC_log_error(func, "", stmt);
194
else if (fOption == SQL_RESET_PARAMS)
195
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
198
SC_set_error(stmt, STMT_OPTION_OUT_OF_RANGE_ERROR, "Invalid option passed to PGAPI_FreeStmt.");
199
SC_log_error(func, "", stmt);
208
* StatementClass implementation
211
InitializeStatementOptions(StatementOptions *opt)
213
memset(opt, 0, sizeof(StatementOptions));
214
opt->maxRows = 0; /* driver returns all rows */
215
opt->maxLength = 0; /* driver returns all data for char/binary */
216
opt->keyset_size = 0; /* fully keyset driven is the default */
217
opt->scroll_concurrency = SQL_CONCUR_READ_ONLY;
218
opt->cursor_type = SQL_CURSOR_FORWARD_ONLY;
219
opt->retrieve_data = SQL_RD_ON;
220
opt->use_bookmarks = SQL_UB_OFF;
221
#if (ODBCVER >= 0x0300)
222
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 */
257
rv = (StatementClass *) malloc(sizeof(StatementClass));
260
rv->hdbc = NULL; /* no connection associated yet */
264
rv->manual_result = FALSE;
266
rv->prepared = FALSE;
267
rv->status = STMT_ALLOCATED;
268
rv->internal = FALSE;
269
rv->transition_status = 0;
271
rv->__error_message = NULL;
272
rv->__error_number = 0;
273
rv->errormsg_created = FALSE;
275
rv->statement = NULL;
276
rv->stmt_with_params = NULL;
277
rv->load_statement = NULL;
278
rv->execute_statement = NULL;
279
rv->stmt_size_limit = -1;
280
rv->statement_type = STMT_TYPE_UNKNOWN;
283
rv->rowset_start = -1;
284
rv->current_col = -1;
286
rv->last_fetch_count = rv->last_fetch_count_include_ommitted = 0;
287
rv->save_rowset_size = -1;
289
rv->data_at_exec = -1;
290
rv->current_exec_param = -1;
291
rv->exec_start_row = -1;
292
rv->exec_end_row = -1;
293
rv->exec_current_row = -1;
294
rv->put_data = FALSE;
297
rv->cursor_name[0] = '\0';
302
rv->parse_status = STMT_PARSE_NONE;
304
/* Clear Statement Options -- defaults will be set in AllocStmt */
305
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));
311
rv->pre_executing = FALSE;
312
rv->inaccurate_result = FALSE;
314
rv->updatable = FALSE;
315
rv->error_recsize = -1;
316
rv->diag_row_count = 0;
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
SC_Destructor(StatementClass *self)
375
QResultClass *res = SC_get_Result(self);
377
if (!self) return FALSE;
378
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, res, self->hdbc);
379
SC_clear_error(self);
380
if (STMT_EXECUTING == self->status)
382
SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.");
389
res->conn = NULL; /* prevent any dbase activity */
394
SC_initialize_stmts(self, TRUE);
396
/* Free the parsed table information */
401
for (i = 0; i < self->ntab; i++)
409
/* 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));
415
if (self->__error_message)
416
free(self->__error_message);
417
DELETE_STMT_CS(self);
420
mylog("SC_Destructor: EXIT\n");
427
* Free parameters and free the memory from the
428
* data-at-execution parameters that was allocated in SQLPutData.
431
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);
435
self->data_at_exec = -1;
436
self->current_exec_param = -1;
437
self->put_data = FALSE;
438
if (option == STMT_FREE_PARAMS_ALL)
440
self->exec_start_row = -1;
441
self->exec_end_row = -1;
442
self->exec_current_row = -1;
448
statement_type(const char *statement)
452
/* ignore leading whitespace in query string */
453
while (*statement && (isspace((unsigned char) *statement) || *statement == '('))
456
for (i = 0; Statement_Type[i].s; i++)
457
if (!strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))
458
return Statement_Type[i].type;
460
return STMT_TYPE_OTHER;
464
SC_set_prepared(StatementClass *stmt, BOOL prepared)
466
if (prepared == stmt->prepared)
470
ConnectionClass *conn = SC_get_conn(stmt);
471
if (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);
482
stmt->prepared = prepared;
486
* Initialize stmt_with_params, load_statement and execute_statement
487
* member pointer deallocating corresponding prepared plan.
488
* Also initialize statement member pointer if specified.
491
SC_initialize_stmts(StatementClass *self, BOOL initializeOriginal)
493
if (initializeOriginal)
497
free(self->statement);
498
self->statement = NULL;
500
if (self->execute_statement)
502
free(self->execute_statement);
503
self->execute_statement = NULL;
505
SC_set_prepared(self,FALSE);
507
if (self->stmt_with_params)
509
free(self->stmt_with_params);
510
self->stmt_with_params = NULL;
512
if (self->load_statement)
514
free(self->load_statement);
515
self->load_statement = NULL;
522
* Called from SQLPrepare if STMT_PREMATURE, or
523
* from SQLExecute if STMT_FINISHED, or
524
* from SQLFreeStmt(SQL_CLOSE)
527
SC_recycle_statement(StatementClass *self)
529
ConnectionClass *conn;
532
mylog("recycle statement: self= %u\n", self);
534
SC_clear_error(self);
535
/* This would not happen */
536
if (self->status == STMT_EXECUTING)
538
SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.");
542
switch (self->status)
545
/* this statement does not need to be recycled */
554
* Premature execution of the statement might have caused the
555
* start of a transaction. If so, we have to rollback that
558
conn = SC_get_conn(self);
559
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
561
if (SC_is_pre_executable(self) && !conn->connInfo.disallow_premature)
570
SC_set_error(self, STMT_INTERNAL_ERROR, "An internal error occured while recycling statements");
574
/* Free the parsed table information */
579
for (i = 0; i < self->ntab; i++)
585
/* Free the parsed field information */
586
IRDFields_free(SC_get_IRD(self));
588
self->parse_status = STMT_PARSE_NONE;
589
self->updatable = FALSE;
591
/* Free any cursors */
592
if (res = SC_get_Result(self), res)
595
SC_set_Result(self, NULL);
597
self->inaccurate_result = FALSE;
600
* Reset only parameters that have anything to do with results
602
self->status = STMT_READY;
603
self->manual_result = FALSE; /* very important */
605
self->currTuple = -1;
606
self->rowset_start = -1;
607
self->current_col = -1;
609
self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;
611
self->__error_message = NULL;
612
self->__error_number = 0;
613
self->errormsg_created = FALSE;
618
* Free any data at exec params before the statement is executed
619
* again. If not, then there will be a memory leak when the next
620
* SQLParamData/SQLPutData is called.
622
SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);
623
SC_initialize_stmts(self, FALSE);
625
* reset the current attr setting to the original one.
627
self->options.scroll_concurrency = self->options_orig.scroll_concurrency;
628
self->options.cursor_type = self->options_orig.cursor_type;
629
self->options.keyset_size = self->options_orig.keyset_size;
630
self->options.maxLength = self->options_orig.maxLength;
631
self->options.maxRows = self->options_orig.maxRows;
637
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
639
SC_pre_execute(StatementClass *self)
641
mylog("SC_pre_execute: status = %d\n", self->status);
643
if (self->status == STMT_READY)
645
mylog(" preprocess: status = READY\n");
648
if (self->statement_type == STMT_TYPE_SELECT)
650
char old_pre_executing = self->pre_executing;
652
self->pre_executing = TRUE;
653
self->inaccurate_result = FALSE;
657
self->pre_executing = old_pre_executing;
659
if (self->status == STMT_FINISHED)
661
mylog(" preprocess: after status = FINISHED, so set PREMATURE\n");
662
self->status = STMT_PREMATURE;
665
if (!SC_is_pre_executable(self))
667
SC_set_Result(self, QR_Constructor());
668
QR_set_status(SC_get_Result(self), PGRES_TUPLES_OK);
669
self->inaccurate_result = TRUE;
670
self->status = STMT_PREMATURE;
676
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
678
SC_unbind_cols(StatementClass *self)
680
ARDFields *opts = SC_get_ARD(self);
682
ARD_unbind_cols(opts, FALSE);
683
opts->bookmark->buffer = NULL;
684
opts->bookmark->used = NULL;
691
SC_clear_error(StatementClass *self)
693
self->__error_number = 0;
694
if (self->__error_message)
695
free(self->__error_message);
696
self->__error_message = NULL;
697
self->errormsg_created = FALSE;
699
self->error_recsize = -1;
700
self->diag_row_count = 0;
705
* This function creates an error msg which is the concatenation
706
* of the result, statement, connection, and socket messages.
709
SC_create_errormsg(const StatementClass *self)
711
QResultClass *res = SC_get_Curres(self);
712
ConnectionClass *conn = self->hdbc;
714
BOOL detailmsg = FALSE;
719
if (res && res->message)
721
strncpy(msg, res->message, sizeof(msg));
724
else if (SC_get_errormsg(self))
725
strncpy(msg, SC_get_errormsg(self), sizeof(msg));
727
if (!msg[0] && res && QR_get_notice(res))
729
char *notice = QR_get_notice(res);
730
int len = strlen(notice);
731
if (len < sizeof(msg))
733
memcpy(msg, notice, len);
737
return strdup(notice);
741
SocketClass *sock = conn->sock;
743
if (!detailmsg && CC_get_errormsg(conn) && (CC_get_errormsg(conn))[0] != '\0')
746
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
return msg[0] ? strdup(msg) : NULL;
760
SC_set_error(StatementClass *self, int number, const char *message)
762
if (self->__error_message)
763
free(self->__error_message);
764
self->__error_number = number;
765
self->__error_message = message ? strdup(message) : NULL;
770
SC_set_errormsg(StatementClass *self, const char *message)
772
if (self->__error_message)
773
free(self->__error_message);
774
self->__error_message = message ? strdup(message) : NULL;
779
SC_error_copy(StatementClass *self, const StatementClass *from)
781
if (self->__error_message)
782
free(self->__error_message);
783
self->__error_number = from->__error_number;
784
self->__error_message = from->__error_message ? strdup(from->__error_message) : NULL;
789
SC_full_error_copy(StatementClass *self, const StatementClass *from)
791
if (self->__error_message)
792
free(self->__error_message);
793
self->__error_number = from->__error_number;
794
self->__error_message = SC_create_errormsg(from);
795
self->errormsg_created = TRUE;
799
SC_get_error(StatementClass *self, int *number, char **message)
803
/* Create a very informative errormsg if it hasn't been done yet. */
804
if (!self->errormsg_created)
806
msgcrt = SC_create_errormsg(self);
807
if (self->__error_message)
808
free(self->__error_message);
809
self->__error_message = msgcrt;
810
self->errormsg_created = TRUE;
812
self->error_recsize = -1;
815
if (SC_get_errornumber(self))
817
*number = SC_get_errornumber(self);
818
*message = self->__error_message;
821
rv = (SC_get_errornumber(self) != 0);
828
SC_get_time(StatementClass *stmt)
832
if (!stmt->stmt_time)
833
stmt->stmt_time = time(NULL);
834
return stmt->stmt_time;
837
* Currently, the driver offers very simple bookmark support -- it is
838
* just the current row number. But it could be more sophisticated
839
* someday, such as mapping a key to a 32 bit value
842
SC_get_bookmark(StatementClass *self)
844
return (self->currTuple + 1);
849
SC_fetch(StatementClass *self)
851
CSTR func = "SC_fetch";
852
QResultClass *res = SC_get_Curres(self);
861
ColumnInfoClass *coli;
863
/* TupleField *tupleField; */
864
ConnInfo *ci = &(SC_get_conn(self)->connInfo);
866
self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;
867
coli = QR_get_fields(res); /* the column info */
869
mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch);
871
if (self->manual_result || !SC_is_fetchcursor(self))
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;
884
mylog("**** SC_fetch: manual_result\n");
889
/* read from the cache or the physical next tuple */
890
retval = QR_next_tuple(res);
893
mylog("**** SC_fetch: end_tuples\n");
894
return SQL_NO_DATA_FOUND;
897
(self->currTuple)++; /* all is well */
900
mylog("SC_fetch: error\n");
901
SC_set_error(self, STMT_EXEC_ERROR, "Error fetching next row");
902
SC_log_error(func, "", self);
906
#ifdef DRIVER_CURSOR_IMPLEMENT
909
UWORD pstatus = res->keyset[self->currTuple].status;
910
if (0 != (pstatus & (CURS_SELF_DELETING | CURS_SELF_DELETED)))
911
return SQL_SUCCESS_WITH_INFO;
912
if (SQL_ROW_DELETED != (pstatus & KEYSET_INFO_PUBLIC) &&
913
0 != (pstatus & CURS_OTHER_DELETED))
914
return SQL_SUCCESS_WITH_INFO;
916
#endif /* DRIVER_CURSOR_IMPLEMENT */
918
num_cols = QR_NumPublicResultCols(res);
920
result = SQL_SUCCESS;
921
self->last_fetch_count++;
922
self->last_fetch_count_include_ommitted++;
924
opts = SC_get_ARD(self);
926
* If the bookmark column was bound then return a bookmark. Since this
927
* is used with SQLExtendedFetch, and the rowset size may be greater
928
* than 1, and an application can use row or column wise binding, use
929
* the code in copy_and_convert_field() to handle that.
931
if (opts->bookmark->buffer)
934
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);
942
if (self->options.retrieve_data == SQL_RD_OFF) /* data isn't required */
944
for (lf = 0; lf < num_cols; lf++)
946
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
/* reset for SQLGetData */
949
opts->bindings[lf].data_left = -1;
951
if (opts->bindings[lf].buffer != NULL)
953
/* this column has a binding */
955
/* type = QR_get_field_type(res, lf); */
956
type = CI_get_oid(coli, lf); /* speed things up */
958
mylog("type = %d\n", type);
960
if (self->manual_result)
962
value = QR_get_value_manual(res, self->currTuple, lf);
963
mylog("manual_result\n");
965
else if (SC_is_fetchcursor(self))
966
value = QR_get_value_backend(res, lf);
969
int curt = GIdx2ResultIdx(self->currTuple, self, res);
970
value = QR_get_value_backend_row(res, curt, lf);
973
mylog("value = '%s'\n", (value == NULL) ? "<NULL>" : value);
975
retval = copy_and_convert_field_bindinfo(self, type, value, lf);
977
mylog("copy_and_convert: retval = %d\n", retval);
982
break; /* OK, do next bound column */
984
case COPY_UNSUPPORTED_TYPE:
985
SC_set_error(self, STMT_RESTRICTED_DATA_TYPE_ERROR, "Received an unsupported type from Postgres.");
986
SC_log_error(func, "", self);
990
case COPY_UNSUPPORTED_CONVERSION:
991
SC_set_error(self, STMT_RESTRICTED_DATA_TYPE_ERROR, "Couldn't handle the necessary data type conversion.");
992
SC_log_error(func, "", self);
996
case COPY_RESULT_TRUNCATED:
997
SC_set_error(self, STMT_TRUNCATED, "Fetched item was truncated.");
998
qlog("The %dth item was truncated\n", lf + 1);
999
qlog("The buffer size = %d", opts->bindings[lf].buflen);
1000
qlog(" and the value is '%s'\n", value);
1001
result = SQL_SUCCESS_WITH_INFO;
1004
/* error msg already filled in */
1005
case COPY_GENERAL_ERROR:
1006
SC_log_error(func, "", self);
1010
/* This would not be meaningful in SQLFetch. */
1011
case COPY_NO_DATA_FOUND:
1015
SC_set_error(self, STMT_INTERNAL_ERROR, "Unrecognized return value from copy_and_convert_field.");
1016
SC_log_error(func, "", self);
1028
SC_execute(StatementClass *self)
1030
CSTR func = "SC_execute";
1031
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.
1039
QResultClass *res = NULL;
1045
BOOL auto_begin = FALSE, is_in_trans;
1048
conn = SC_get_conn(self);
1049
ci = &(conn->connInfo);
1051
/* Begin a transaction if one is not already in progress */
1054
* Basically we don't have to begin a transaction in autocommit mode
1055
* because Postgres backend runs in autocomit mode. We issue "BEGIN"
1056
* in the following cases. 1) we use declare/fetch and the statement
1057
* is SELECT (because declare/fetch must be called in a transaction).
1058
* 2) we are in autocommit off state and the statement isn't of type
1061
ENTER_CONN_CS(conn);
1062
if (CONN_EXECUTING == conn->status)
1064
LEAVE_CONN_CS(conn);
1065
SC_set_error(self, STMT_SEQUENCE_ERROR, "Connection is already in use.");
1066
SC_log_error(func, "", self);
1067
mylog("%s: problem with connection\n", func);
1070
is_in_trans = CC_is_in_trans(conn);
1071
if (!self->internal && !is_in_trans &&
1072
(SC_is_fetchcursor(self) ||
1073
(!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER)))
1075
mylog(" about to begin a transaction on statement = %u\n", self);
1077
if (PG_VERSION_GE(conn, 7.1))
1078
qflag |= GO_INTO_TRANSACTION;
1079
else if (!CC_begin(conn))
1081
LEAVE_CONN_CS(conn);
1082
SC_set_error(self, STMT_EXEC_ERROR, "Could not begin a transaction");
1083
SC_log_error(func, "", self);
1088
oldstatus = conn->status;
1089
conn->status = CONN_EXECUTING;
1090
self->status = STMT_EXECUTING;
1092
/* If it's a SELECT statement, use a cursor. */
1095
* Note that the declare cursor has already been prepended to the
1098
/* in copy_statement... */
1099
if (self->statement_type == STMT_TYPE_SELECT)
1102
qflag |= (SQL_CONCUR_READ_ONLY != self->options.scroll_concurrency ? CREATE_KEYSET : 0);
1104
mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name);
1106
/* send the declare/select */
1107
res = CC_send_query(conn, self->stmt_with_params, NULL, qflag);
1108
if (SC_is_fetchcursor(self) && res != NULL &&
1109
QR_command_maybe_successful(res))
1112
qflag &= (~ GO_INTO_TRANSACTION);
1115
* That worked, so now send the fetch to start getting data
1118
qi.result_in = NULL;
1119
qi.cursor = self->cursor_name;
1120
qi.row_size = ci->drivers.fetch_max;
1123
* Most likely the rowset size will not be set by the
1124
* application until after the statement is executed, so might
1125
* as well use the cache size. The qr_next_tuple() function
1126
* will correct for any discrepancies in sizes and adjust the
1127
* cache accordingly.
1129
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
1131
res = CC_send_query(conn, fetch, &qi, qflag);
1133
mylog(" done sending the query:\n");
1137
/* not a SELECT statement so don't use a cursor */
1138
mylog(" it's NOT a select statement: stmt=%u\n", self);
1139
res = CC_send_query(conn, self->stmt_with_params, NULL, qflag);
1142
* We shouldn't send COMMIT. Postgres backend does the autocommit
1143
* if neccessary. (Zoltan, 04/26/2000)
1147
* Above seems wrong. Even in case of autocommit, started
1148
* transactions must be committed. (Hiroshi, 02/11/2001)
1150
if (CC_is_in_trans(conn))
1153
CC_set_in_manual_trans(conn);
1154
if (!self->internal && CC_is_in_autocommit(conn) && !CC_is_in_manual_trans(conn))
1159
if (CONN_DOWN != conn->status)
1160
conn->status = oldstatus;
1161
self->status = STMT_FINISHED;
1162
LEAVE_CONN_CS(conn);
1164
/* Check the status of the result */
1167
was_ok = QR_command_successful(res);
1168
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
SC_set_errornumber(self, STMT_OK);
1180
SC_set_errornumber(self, was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND);
1182
/* set cursor before the first tuple in the list */
1183
self->currTuple = -1;
1184
self->current_col = -1;
1185
self->rowset_start = -1;
1187
/* issue "ABORT" when query aborted */
1188
if (QR_get_aborted(res))
1190
if (!self->internal)
1197
/* see if the query did return any result columns */
1198
for (tres = res, numcols = 0; !numcols && tres; tres = tres->next)
1200
numcols = QR_NumResultCols(tres);
1202
/* now allocate the array to hold the binding info */
1205
ARDFields *opts = SC_get_ARD(self);
1206
extend_column_bindings(opts, numcols);
1207
if (opts->bindings == NULL)
1210
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
/* Bad Error -- The error message will be in the Connection */
1221
SC_set_error(self, STMT_BAD_ERROR, CC_get_errormsg(conn));
1222
else if (self->statement_type == STMT_TYPE_CREATE)
1224
SC_set_error(self, STMT_CREATE_TABLE_ERROR, "Error creating the table");
1227
* This would allow the table to already exists, thus
1228
* appending rows to it. BUT, if the table didn't have the
1229
* same attributes, it would fail. return
1230
* SQL_SUCCESS_WITH_INFO;
1235
SC_set_error(self, STMT_EXEC_ERROR, CC_get_errormsg(conn));
1238
if (!self->internal)
1241
if (!SC_get_Result(self))
1242
SC_set_Result(self, res);
1246
for (last = SC_get_Result(self); last->next; last = last->next)
1251
apdopts = SC_get_APD(self);
1252
if (self->statement_type == STMT_TYPE_PROCCALL &&
1253
(SC_get_errornumber(self) == STMT_OK ||
1254
SC_get_errornumber(self) == STMT_INFO_ONLY) &&
1255
apdopts->parameters &&
1256
apdopts->parameters[0].buffer &&
1257
apdopts->parameters[0].paramType == SQL_PARAM_OUTPUT)
1258
{ /* get the return value of the procedure
1261
HSTMT hstmt = (HSTMT) self;
1263
ret = SC_fetch(hstmt);
1264
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);
1267
if (ret != SQL_SUCCESS)
1269
SC_set_error(self, STMT_EXEC_ERROR, "GetData to Procedure return failed.");
1274
SC_set_error(self, STMT_EXEC_ERROR, "SC_fetch to get a Procedure return failed.");
1277
if (SC_get_errornumber(self) == STMT_OK)
1278
if (was_rows_affected)
1281
return SQL_NO_DATA_FOUND;
1282
else if (SC_get_errornumber(self) == STMT_INFO_ONLY)
1283
return SQL_SUCCESS_WITH_INFO;
1286
if (!SC_get_errormsg(self) || !SC_get_errormsg(self)[0])
1287
SC_set_errormsg(self, "Error while executing the query");
1288
SC_log_error(func, "", self);
1295
SC_log_error(const char *func, const char *desc, const StatementClass *self)
1297
#ifdef PRN_NULLCHECK
1298
#define nullcheck(a) (a ? a : "(NULL)")
1302
QResultClass *res = SC_get_Result(self);
1303
const ARDFields *opts = SC_get_ARD(self);
1304
const APDFields *apdopts = SC_get_APD(self);
1307
#if (ODBCVER >= 0x0300)
1308
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));
1314
qlog(" ------------------------------------------------------------\n");
1315
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, res);
1316
qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal);
1317
qlog(" bindings=%u, bindings_allocated=%d\n", opts->bindings, opts->allocated);
1318
qlog(" parameters=%u, parameters_allocated=%d\n", apdopts->parameters, apdopts->allocated);
1319
qlog(" statement_type=%d, statement='%s'\n", self->statement_type, nullcheck(self->statement));
1320
qlog(" stmt_with_params='%s'\n", nullcheck(self->stmt_with_params));
1321
qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data);
1322
qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd);
1323
qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->options.maxRows, rowsetSize, self->options.keyset_size, self->options.cursor_type, self->options.scroll_concurrency);
1324
qlog(" cursor_name='%s'\n", nullcheck(self->cursor_name));
1326
qlog(" ----------------QResult Info -------------------------------\n");
1330
qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
1331
qlog(" fetch_count=%d, num_total_rows=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->num_total_rows, res->num_fields, nullcheck(res->cursor));
1332
qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
1333
qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples);
1336
/* Log the connection error if there is one */
1337
CC_log_error(func, desc, self->hdbc);
1341
qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
1342
mylog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
1344
#undef PRN_NULLCHECK