4 * Description: This module contains routines related to
5 * preparing and executing an SQL statement.
9 * API functions: SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact,
10 * SQLCancel, SQLNativeSql, SQLParamData, SQLPutData
12 * Comments: See "notice.txt" for copyright and license information.
21 #include "connection.h"
22 #include "statement.h"
28 #include "pgapifunc.h"
30 /*extern GLOBAL_VALUES globals;*/
33 /* Perform a Prepare on the SQL statement */
35 PGAPI_Prepare(HSTMT hstmt,
39 static char *func = "PGAPI_Prepare";
40 StatementClass *self = (StatementClass *) hstmt;
42 mylog("%s: entering...\n", func);
46 SC_log_error(func, "", NULL);
47 return SQL_INVALID_HANDLE;
51 * According to the ODBC specs it is valid to call SQLPrepare mulitple
52 * times. In that case, the bound SQL statement is replaced by the new
59 mylog("**** PGAPI_Prepare: STMT_PREMATURE, recycle\n");
60 SC_recycle_statement(self); /* recycle the statement, but do
61 * not remove parameter bindings */
65 mylog("**** PGAPI_Prepare: STMT_FINISHED, recycle\n");
66 SC_recycle_statement(self); /* recycle the statement, but do
67 * not remove parameter bindings */
71 mylog("**** PGAPI_Prepare: STMT_ALLOCATED, copy\n");
72 self->status = STMT_READY;
76 mylog("**** PGAPI_Prepare: STMT_READY, change SQL\n");
80 mylog("**** PGAPI_Prepare: STMT_EXECUTING, error!\n");
82 self->errornumber = STMT_SEQUENCE_ERROR;
83 self->errormsg = "PGAPI_Prepare(): The handle does not point to a statement that is ready to be executed";
84 SC_log_error(func, "", self);
89 self->errornumber = STMT_INTERNAL_ERROR;
90 self->errormsg = "An Internal Error has occured -- Unknown statement status.";
91 SC_log_error(func, "", self);
96 free(self->statement);
98 self->statement = make_string(szSqlStr, cbSqlStr, NULL);
101 self->errornumber = STMT_NO_MEMORY_ERROR;
102 self->errormsg = "No memory available to store statement";
103 SC_log_error(func, "", self);
107 self->prepare = TRUE;
108 self->statement_type = statement_type(self->statement);
110 /* Check if connection is onlyread (only selects are allowed) */
111 if (CC_is_onlyread(self->hdbc) && STMT_UPDATE(self))
113 self->errornumber = STMT_EXEC_ERROR;
114 self->errormsg = "Connection is readonly, only select statements are allowed.";
115 SC_log_error(func, "", self);
123 /* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
130 StatementClass *stmt = (StatementClass *) hstmt;
132 static char *func = "PGAPI_ExecDirect";
134 mylog("%s: entering...\n", func);
138 SC_log_error(func, "", NULL);
139 return SQL_INVALID_HANDLE;
143 free(stmt->statement);
146 * keep a copy of the un-parametrized statement, in case they try to
147 * execute this statement again
149 stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
150 if (!stmt->statement)
152 stmt->errornumber = STMT_NO_MEMORY_ERROR;
153 stmt->errormsg = "No memory available to store statement";
154 SC_log_error(func, "", stmt);
158 mylog("**** %s: hstmt=%u, statement='%s'\n", func, hstmt, stmt->statement);
160 stmt->prepare = FALSE;
163 * If an SQLPrepare was performed prior to this, but was left in the
164 * premature state because an error occurred prior to SQLExecute then
165 * set the statement to finished so it can be recycled.
167 if (stmt->status == STMT_PREMATURE)
168 stmt->status = STMT_FINISHED;
170 stmt->statement_type = statement_type(stmt->statement);
172 /* Check if connection is onlyread (only selects are allowed) */
173 if (CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt))
175 stmt->errornumber = STMT_EXEC_ERROR;
176 stmt->errormsg = "Connection is readonly, only select statements are allowed.";
177 SC_log_error(func, "", stmt);
181 mylog("%s: calling PGAPI_Execute...\n", func);
183 result = PGAPI_Execute(hstmt);
185 mylog("%s: returned %hd from PGAPI_Execute\n", func, result);
190 /* Execute a prepared SQL statement */
195 static char *func = "PGAPI_Execute";
196 StatementClass *stmt = (StatementClass *) hstmt;
197 ConnectionClass *conn;
201 mylog("%s: entering...\n", func);
205 SC_log_error(func, "", NULL);
206 mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func);
207 return SQL_INVALID_HANDLE;
211 * If the statement is premature, it means we already executed it from
212 * an SQLPrepare/SQLDescribeCol type of scenario. So just return
215 if (stmt->prepare && stmt->status == STMT_PREMATURE)
217 if (stmt->inaccurate_result)
218 SC_recycle_statement(stmt);
221 stmt->status = STMT_FINISHED;
222 if (stmt->errormsg == NULL)
224 mylog("%s: premature statement but return SQL_SUCCESS\n", func);
229 SC_log_error(func, "", stmt);
230 mylog("%s: premature statement so return SQL_ERROR\n", func);
236 mylog("%s: clear errors...\n", func);
238 SC_clear_error(stmt);
240 conn = SC_get_conn(stmt);
241 if (conn->status == CONN_EXECUTING)
243 stmt->errormsg = "Connection is already in use.";
244 stmt->errornumber = STMT_SEQUENCE_ERROR;
245 SC_log_error(func, "", stmt);
246 mylog("%s: problem with connection\n", func);
250 if (!stmt->statement)
252 stmt->errornumber = STMT_NO_STMTSTRING;
253 stmt->errormsg = "This handle does not have a SQL statement stored in it";
254 SC_log_error(func, "", stmt);
255 mylog("%s: problem with handle\n", func);
260 * If SQLExecute is being called again, recycle the statement. Note
261 * this should have been done by the application in a call to
262 * SQLFreeStmt(SQL_CLOSE) or SQLCancel.
264 if (stmt->status == STMT_FINISHED)
266 mylog("%s: recycling statement (should have been done by app)...\n", func);
267 SC_recycle_statement(stmt);
270 /* Check if the statement is in the correct state */
271 if ((stmt->prepare && stmt->status != STMT_READY) ||
272 (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY))
274 stmt->errornumber = STMT_STATUS_ERROR;
275 stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
276 SC_log_error(func, "", stmt);
277 mylog("%s: problem with statement\n", func);
282 * Check if statement has any data-at-execute parameters when it is
283 * not in SC_pre_execute.
285 if (!stmt->pre_executing)
289 * The bound parameters could have possibly changed since the last
290 * execute of this statement? Therefore check for params and
293 stmt->data_at_exec = -1;
294 for (i = 0; i < stmt->parameters_allocated; i++)
296 Int4 *pcVal = stmt->parameters[i].used;
298 if (pcVal && (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET))
299 stmt->parameters[i].data_at_exec = TRUE;
301 stmt->parameters[i].data_at_exec = FALSE;
302 /* Check for data at execution parameters */
303 if (stmt->parameters[i].data_at_exec == TRUE)
305 if (stmt->data_at_exec < 0)
306 stmt->data_at_exec = 1;
308 stmt->data_at_exec++;
313 * If there are some data at execution parameters, return need
318 * SQLParamData and SQLPutData will be used to send params and
319 * execute the statement.
321 if (stmt->data_at_exec > 0)
322 return SQL_NEED_DATA;
327 mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement);
329 /* Create the statement with parameters substituted. */
330 retval = copy_statement_with_parameters(stmt);
331 if (retval != SQL_SUCCESS)
332 /* error msg passed from above */
335 mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params);
337 * Get the field info for the prepared
338 * query using dummy backward fetch.
340 if (stmt->inaccurate_result && conn->connInfo.disallow_premature)
342 if (SC_is_pre_executable(stmt))
344 BOOL in_trans = CC_is_in_trans(conn);
345 BOOL issued_begin = FALSE, begin_included = FALSE;
348 if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0)
349 begin_included = TRUE;
352 res = CC_send_query(conn, "BEGIN", NULL);
353 if (res && !QR_aborted(res))
359 stmt->errornumber = STMT_EXEC_ERROR;
360 stmt->errormsg = "Handle prepare error";
364 /* we are now in a transaction */
365 CC_set_in_trans(conn);
366 stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL);
367 if (!res || QR_aborted(res))
370 stmt->errornumber = STMT_EXEC_ERROR;
371 stmt->errormsg = "Handle prepare error";
376 if (CC_is_in_autocommit(conn))
380 res = CC_send_query(conn, "COMMIT", NULL);
381 CC_set_no_trans(conn);
385 else if (!in_trans && begin_included)
386 CC_set_no_trans(conn);
388 stmt->status =STMT_FINISHED;
396 return SC_execute(stmt);
406 static char *func = "PGAPI_Transact";
407 extern ConnectionClass *conns[];
408 ConnectionClass *conn;
414 mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv);
416 if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV)
418 CC_log_error(func, "", NULL);
419 return SQL_INVALID_HANDLE;
423 * If hdbc is null and henv is valid, it means transact all
424 * connections on that henv.
426 if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV)
428 for (lf = 0; lf < MAX_CONNECTIONS; lf++)
432 if (conn && conn->henv == henv)
433 if (PGAPI_Transact(henv, (HDBC) conn, fType) != SQL_SUCCESS)
439 conn = (ConnectionClass *) hdbc;
441 if (fType == SQL_COMMIT)
442 stmt_string = "COMMIT";
443 else if (fType == SQL_ROLLBACK)
444 stmt_string = "ROLLBACK";
447 conn->errornumber = CONN_INVALID_ARGUMENT_NO;
448 conn->errormsg = "PGAPI_Transact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";
449 CC_log_error(func, "", conn);
453 /* If manual commit and in transaction, then proceed. */
454 if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
456 mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string);
458 res = CC_send_query(conn, stmt_string, NULL);
459 CC_set_no_trans(conn);
463 /* error msg will be in the connection */
464 CC_log_error(func, "", conn);
468 ok = QR_command_successful(res);
473 CC_log_error(func, "", conn);
483 HSTMT hstmt) /* Statement to cancel. */
485 static char *func = "PGAPI_Cancel";
486 StatementClass *stmt = (StatementClass *) hstmt;
496 mylog("%s: entering...\n", func);
498 /* Check if this can handle canceling in the middle of a SQLPutData? */
501 SC_log_error(func, "", NULL);
502 return SQL_INVALID_HANDLE;
504 ci = &(SC_get_conn(stmt)->connInfo);
507 * Not in the middle of SQLParamData/SQLPutData so cancel like a
510 if (stmt->data_at_exec < 0)
514 * MAJOR HACK for Windows to reset the driver manager's cursor
515 * state: Because of what seems like a bug in the Odbc driver
516 * manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as
517 * many applications depend on this behavior. So, this brute
518 * force method calls the driver manager's function on behalf of
523 if (ci->drivers.cancel_as_freestmt)
525 hmodule = GetModuleHandle("ODBC32");
526 addr = GetProcAddress(hmodule, "SQLFreeStmt");
527 result = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE);
530 result = PGAPI_FreeStmt(hstmt, SQL_CLOSE);
532 result = PGAPI_FreeStmt(hstmt, SQL_CLOSE);
535 mylog("PGAPI_Cancel: PGAPI_FreeStmt returned %d\n", result);
537 SC_clear_error(hstmt);
541 /* In the middle of SQLParamData/SQLPutData, so cancel that. */
544 * Note, any previous data-at-exec buffers will be freed in the
547 /* if they call SQLExecDirect or SQLExecute again. */
549 stmt->data_at_exec = -1;
550 stmt->current_exec_param = -1;
551 stmt->put_data = FALSE;
558 * Returns the SQL string as modified by the driver.
559 * Currently, just copy the input string without modification
560 * observing buffer limits and truncation.
565 UCHAR FAR *szSqlStrIn,
569 SDWORD FAR *pcbSqlStr)
571 static char *func = "PGAPI_NativeSql";
574 ConnectionClass *conn = (ConnectionClass *) hdbc;
577 mylog("%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn);
579 ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL);
582 conn->errornumber = CONN_NO_MEMORY_ERROR;
583 conn->errormsg = "No memory available to store native sql string";
584 CC_log_error(func, "", conn);
588 result = SQL_SUCCESS;
593 strncpy_null(szSqlStr, ptr, cbSqlStrMax);
595 if (len >= cbSqlStrMax)
597 result = SQL_SUCCESS_WITH_INFO;
598 conn->errornumber = STMT_TRUNCATED;
599 conn->errormsg = "The buffer was too small for the NativeSQL.";
614 * Supplies parameter data at execution time.
615 * Used in conjuction with SQLPutData.
622 static char *func = "PGAPI_ParamData";
623 StatementClass *stmt = (StatementClass *) hstmt;
628 mylog("%s: entering...\n", func);
632 SC_log_error(func, "", NULL);
633 return SQL_INVALID_HANDLE;
635 ci = &(SC_get_conn(stmt)->connInfo);
637 mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated);
639 if (stmt->data_at_exec < 0)
641 stmt->errornumber = STMT_SEQUENCE_ERROR;
642 stmt->errormsg = "No execution-time parameters for this statement";
643 SC_log_error(func, "", stmt);
647 if (stmt->data_at_exec > stmt->parameters_allocated)
649 stmt->errornumber = STMT_SEQUENCE_ERROR;
650 stmt->errormsg = "Too many execution-time parameters were present";
651 SC_log_error(func, "", stmt);
655 /* close the large object */
656 if (stmt->lobj_fd >= 0)
658 lo_close(stmt->hdbc, stmt->lobj_fd);
660 /* commit transaction if needed */
661 if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
666 res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
669 stmt->errormsg = "Could not commit (in-line) a transaction";
670 stmt->errornumber = STMT_EXEC_ERROR;
671 SC_log_error(func, "", stmt);
674 ok = QR_command_successful(res);
675 CC_set_no_trans(stmt->hdbc);
679 stmt->errormsg = "Could not commit (in-line) a transaction";
680 stmt->errornumber = STMT_EXEC_ERROR;
681 SC_log_error(func, "", stmt);
688 /* Done, now copy the params and then execute the statement */
689 if (stmt->data_at_exec == 0)
691 retval = copy_statement_with_parameters(stmt);
692 if (retval != SQL_SUCCESS)
695 stmt->current_exec_param = -1;
697 return SC_execute(stmt);
701 * Set beginning param; if first time SQLParamData is called , start
702 * at 0. Otherwise, start at the last parameter + 1.
704 i = stmt->current_exec_param >= 0 ? stmt->current_exec_param + 1 : 0;
706 /* At least 1 data at execution parameter, so Fill in the token value */
707 for (; i < stmt->parameters_allocated; i++)
709 if (stmt->parameters[i].data_at_exec == TRUE)
711 stmt->data_at_exec--;
712 stmt->current_exec_param = i;
713 stmt->put_data = FALSE;
714 *prgbValue = stmt->parameters[i].buffer; /* token */
719 return SQL_NEED_DATA;
724 * Supplies parameter data at execution time.
725 * Used in conjunction with SQLParamData.
733 static char *func = "PGAPI_PutData";
734 StatementClass *stmt = (StatementClass *) hstmt;
737 ParameterInfoClass *current_param;
740 mylog("%s: entering...\n", func);
744 SC_log_error(func, "", NULL);
745 return SQL_INVALID_HANDLE;
748 if (stmt->current_exec_param < 0)
750 stmt->errornumber = STMT_SEQUENCE_ERROR;
751 stmt->errormsg = "Previous call was not SQLPutData or SQLParamData";
752 SC_log_error(func, "", stmt);
756 current_param = &(stmt->parameters[stmt->current_exec_param]);
760 mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue);
762 stmt->put_data = TRUE;
764 current_param->EXEC_used = (SDWORD *) malloc(sizeof(SDWORD));
765 if (!current_param->EXEC_used)
767 stmt->errornumber = STMT_NO_MEMORY_ERROR;
768 stmt->errormsg = "Out of memory in PGAPI_PutData (1)";
769 SC_log_error(func, "", stmt);
773 *current_param->EXEC_used = cbValue;
775 if (cbValue == SQL_NULL_DATA)
778 /* Handle Long Var Binary with Large Objects */
779 if (current_param->SQLType == SQL_LONGVARBINARY)
781 /* begin transaction if needed */
782 if (!CC_is_in_trans(stmt->hdbc))
787 res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
790 stmt->errormsg = "Could not begin (in-line) a transaction";
791 stmt->errornumber = STMT_EXEC_ERROR;
792 SC_log_error(func, "", stmt);
795 ok = QR_command_successful(res);
799 stmt->errormsg = "Could not begin (in-line) a transaction";
800 stmt->errornumber = STMT_EXEC_ERROR;
801 SC_log_error(func, "", stmt);
805 CC_set_in_trans(stmt->hdbc);
809 current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
810 if (current_param->lobj_oid == 0)
812 stmt->errornumber = STMT_EXEC_ERROR;
813 stmt->errormsg = "Couldnt create large object.";
814 SC_log_error(func, "", stmt);
819 * major hack -- to allow convert to see somethings there have
820 * to modify convert to handle this better
822 current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;
825 stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE);
826 if (stmt->lobj_fd < 0)
828 stmt->errornumber = STMT_EXEC_ERROR;
829 stmt->errormsg = "Couldnt open large object for writing.";
830 SC_log_error(func, "", stmt);
834 retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
835 mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
839 /* for handling fields */
840 if (cbValue == SQL_NTS)
842 current_param->EXEC_buffer = strdup(rgbValue);
843 if (!current_param->EXEC_buffer)
845 stmt->errornumber = STMT_NO_MEMORY_ERROR;
846 stmt->errormsg = "Out of memory in PGAPI_PutData (2)";
847 SC_log_error(func, "", stmt);
853 Int2 ctype = current_param->CType;
855 if (ctype == SQL_C_DEFAULT)
856 ctype = sqltype_to_default_ctype(current_param->SQLType);
857 if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY)
859 current_param->EXEC_buffer = malloc(cbValue + 1);
860 if (!current_param->EXEC_buffer)
862 stmt->errornumber = STMT_NO_MEMORY_ERROR;
863 stmt->errormsg = "Out of memory in PGAPI_PutData (2)";
864 SC_log_error(func, "", stmt);
867 memcpy(current_param->EXEC_buffer, rgbValue, cbValue);
868 current_param->EXEC_buffer[cbValue] = '\0';
872 Int4 used = ctype_length(ctype);
874 current_param->EXEC_buffer = malloc(used);
875 if (!current_param->EXEC_buffer)
877 stmt->errornumber = STMT_NO_MEMORY_ERROR;
878 stmt->errormsg = "Out of memory in PGAPI_PutData (2)";
879 SC_log_error(func, "", stmt);
882 memcpy(current_param->EXEC_buffer, rgbValue, used);
889 /* calling SQLPutData more than once */
890 mylog("PGAPI_PutData: (>1) cbValue = %d\n", cbValue);
892 if (current_param->SQLType == SQL_LONGVARBINARY)
894 /* the large object fd is in EXEC_buffer */
895 retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
896 mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval);
898 *current_param->EXEC_used += cbValue;
902 buffer = current_param->EXEC_buffer;
904 if (cbValue == SQL_NTS)
906 buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1);
909 stmt->errornumber = STMT_NO_MEMORY_ERROR;
910 stmt->errormsg = "Out of memory in PGAPI_PutData (3)";
911 SC_log_error(func, "", stmt);
914 strcat(buffer, rgbValue);
916 mylog(" cbValue = SQL_NTS: strlen(buffer) = %d\n", strlen(buffer));
918 *current_param->EXEC_used = cbValue;
920 /* reassign buffer incase realloc moved it */
921 current_param->EXEC_buffer = buffer;
923 else if (cbValue > 0)
925 old_pos = *current_param->EXEC_used;
927 *current_param->EXEC_used += cbValue;
929 mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used);
931 /* dont lose the old pointer in case out of memory */
932 buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1);
935 stmt->errornumber = STMT_NO_MEMORY_ERROR;
936 stmt->errormsg = "Out of memory in PGAPI_PutData (3)";
937 SC_log_error(func, "", stmt);
941 memcpy(&buffer[old_pos], rgbValue, cbValue);
942 buffer[*current_param->EXEC_used] = '\0';
944 /* reassign buffer incase realloc moved it */
945 current_param->EXEC_buffer = buffer;
949 SC_log_error(func, "bad cbValue", stmt);