aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/statement.c')
-rw-r--r--src/interfaces/odbc/statement.c131
1 files changed, 57 insertions, 74 deletions
diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c
index 497364ba84d..3463edf5337 100644
--- a/src/interfaces/odbc/statement.c
+++ b/src/interfaces/odbc/statement.c
@@ -1,4 +1,5 @@
-/* Module: statement.c
+/*-------
+ * Module: statement.c
*
* Description: This module contains functions related to creating
* and manipulating a statement.
@@ -8,7 +9,7 @@
* API functions: SQLAllocStmt, SQLFreeStmt
*
* Comments: See "notice.txt" for copyright and license information.
- *
+ *-------
*/
#ifdef HAVE_CONFIG_H
@@ -44,6 +45,7 @@ extern GLOBAL_VALUES globals;
#endif
#define PRN_NULLCHECK
+
/* Map sql commands to statement types */
static struct
{
@@ -126,12 +128,9 @@ SQLAllocStmt(HDBC hdbc,
*phstmt = (HSTMT) stmt;
- /*
- * Copy default statement options based from Connection options
- */
+ /* Copy default statement options based from Connection options */
stmt->options = conn->stmtOptions;
-
/* Save the handle for later */
stmt->phstmt = phstmt;
@@ -180,29 +179,27 @@ SQLFreeStmt(HSTMT hstmt,
/* Destroy the statement and free any results, cursors, etc. */
SC_Destructor(stmt);
-
}
else if (fOption == SQL_UNBIND)
{
SC_unbind_cols(stmt);
-
}
else if (fOption == SQL_CLOSE)
{
- /* this should discard all the results, but leave the statement */
- /* itself in place (it can be executed again) */
+ /*
+ * this should discard all the results, but leave the statement
+ * itself in place (it can be executed again)
+ */
if (!SC_recycle_statement(stmt))
{
/* errormsg passed in above */
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
-
}
else if (fOption == SQL_RESET_PARAMS)
{
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
-
}
else
{
@@ -216,8 +213,7 @@ SQLFreeStmt(HSTMT hstmt,
}
-
-/**********************************************************************
+/*
* StatementClass implementation
*/
void
@@ -234,6 +230,7 @@ InitializeStatementOptions(StatementOptions *opt)
opt->use_bookmarks = SQL_UB_OFF;
}
+
StatementClass *
SC_Constructor(void)
{
@@ -288,7 +285,6 @@ SC_Constructor(void)
rv->nfld = 0;
rv->parse_status = STMT_PARSE_NONE;
-
/* Clear Statement Options -- defaults will be set in AllocStmt */
memset(&rv->options, 0, sizeof(StatementOptions));
@@ -298,10 +294,10 @@ SC_Constructor(void)
return rv;
}
+
char
SC_Destructor(StatementClass *self)
{
-
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);
if (STMT_EXECUTING == self->status)
{
@@ -325,18 +321,13 @@ SC_Destructor(StatementClass *self)
/*
* the memory pointed to by the bindings is not deallocated by the
- * driver
- */
-
- /*
- * by by the application that uses that driver, so we don't have to
+ * driver but by the application that uses that driver, so we don't have to
* care
*/
/* about that here. */
if (self->bindings)
free(self->bindings);
-
/* Free the parsed table information */
if (self->ti)
{
@@ -358,7 +349,6 @@ SC_Destructor(StatementClass *self)
free(self->fi);
}
-
free(self);
mylog("SC_Destructor: EXIT\n");
@@ -366,9 +356,11 @@ SC_Destructor(StatementClass *self)
return TRUE;
}
-/* Free parameters and free the memory from the
- data-at-execution parameters that was allocated in SQLPutData.
-*/
+
+/*
+ * Free parameters and free the memory from the
+ * data-at-execution parameters that was allocated in SQLPutData.
+ */
void
SC_free_params(StatementClass *self, char option)
{
@@ -383,7 +375,6 @@ SC_free_params(StatementClass *self, char option)
{
if (self->parameters[i].data_at_exec == TRUE)
{
-
if (self->parameters[i].EXEC_used)
{
free(self->parameters[i].EXEC_used);
@@ -430,9 +421,10 @@ statement_type(char *statement)
}
-/* Called from SQLPrepare if STMT_PREMATURE, or
- from SQLExecute if STMT_FINISHED, or
- from SQLFreeStmt(SQL_CLOSE)
+/*
+ * Called from SQLPrepare if STMT_PREMATURE, or
+ * from SQLExecute if STMT_FINISHED, or
+ * from SQLFreeStmt(SQL_CLOSE)
*/
char
SC_recycle_statement(StatementClass *self)
@@ -472,7 +464,6 @@ SC_recycle_statement(StatementClass *self)
conn = SC_get_conn(self);
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
{
-
QResultClass *res = CC_send_query(conn, "ABORT", NULL);
QR_Destructor(res);
@@ -523,10 +514,9 @@ SC_recycle_statement(StatementClass *self)
}
self->inaccurate_result = FALSE;
- /****************************************************************/
- /* Reset only parameters that have anything to do with results */
- /****************************************************************/
-
+ /*
+ * Reset only parameters that have anything to do with results
+ */
self->status = STMT_READY;
self->manual_result = FALSE;/* very important */
@@ -542,14 +532,17 @@ SC_recycle_statement(StatementClass *self)
self->lobj_fd = -1;
- /* Free any data at exec params before the statement is executed */
- /* again. If not, then there will be a memory leak when */
- /* the next SQLParamData/SQLPutData is called. */
+ /*
+ * Free any data at exec params before the statement is executed
+ * again. If not, then there will be a memory leak when
+ * the next SQLParamData/SQLPutData is called.
+ */
SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);
return TRUE;
}
+
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
void
SC_pre_execute(StatementClass *self)
@@ -586,6 +579,7 @@ SC_pre_execute(StatementClass *self)
}
}
+
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
char
SC_unbind_cols(StatementClass *self)
@@ -607,6 +601,7 @@ SC_unbind_cols(StatementClass *self)
return 1;
}
+
void
SC_clear_error(StatementClass *self)
{
@@ -616,8 +611,10 @@ SC_clear_error(StatementClass *self)
}
-/* This function creates an error msg which is the concatenation */
-/* of the result, statement, connection, and socket messages. */
+/*
+ * This function creates an error msg which is the concatenation
+ * of the result, statement, connection, and socket messages.
+ */
char *
SC_create_errormsg(StatementClass *self)
{
@@ -654,12 +651,13 @@ SC_create_errormsg(StatementClass *self)
return msg;
}
+
char
SC_get_error(StatementClass *self, int *number, char **message)
{
char rv;
-/* Create a very informative errormsg if it hasn't been done yet. */
+ /* Create a very informative errormsg if it hasn't been done yet. */
if (!self->errormsg_created)
{
self->errormsg = SC_create_errormsg(self);
@@ -679,16 +677,19 @@ SC_get_error(StatementClass *self, int *number, char **message)
return rv;
}
-/* Currently, the driver offers very simple bookmark support -- it is
- just the current row number. But it could be more sophisticated
- someday, such as mapping a key to a 32 bit value
-*/
+
+/*
+ * Currently, the driver offers very simple bookmark support -- it is
+ * just the current row number. But it could be more sophisticated
+ * someday, such as mapping a key to a 32 bit value
+ */
unsigned long
SC_get_bookmark(StatementClass *self)
{
return (self->currTuple + 1);
}
+
RETCODE
SC_fetch(StatementClass *self)
{
@@ -702,7 +703,7 @@ SC_fetch(StatementClass *self)
char *value;
ColumnInfoClass *ci;
-/* TupleField *tupleField; */
+ /* TupleField *tupleField; */
self->last_fetch_count = 0;
ci = QR_get_fields(res); /* the column info */
@@ -711,11 +712,9 @@ SC_fetch(StatementClass *self)
if (self->manual_result || !globals.use_declarefetch)
{
-
if (self->currTuple >= QR_get_num_tuples(res) - 1 ||
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
{
-
/*
* if at the end of the tuples, return "no data found" and set
* the cursor past the end of the result set
@@ -729,7 +728,6 @@ SC_fetch(StatementClass *self)
}
else
{
-
/* read from the cache or the physical next tuple */
retval = QR_next_tuple(res);
if (retval < 0)
@@ -739,7 +737,6 @@ SC_fetch(StatementClass *self)
}
else if (retval > 0)
(self->currTuple)++;/* all is well */
-
else
{
mylog("SQLFetch: error\n");
@@ -772,7 +769,6 @@ SC_fetch(StatementClass *self)
for (lf = 0; lf < num_cols; lf++)
{
-
mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer);
/* reset for SQLGetData */
@@ -828,13 +824,13 @@ SC_fetch(StatementClass *self)
result = SQL_SUCCESS_WITH_INFO;
break;
- case COPY_GENERAL_ERROR: /* error msg already
- * filled in */
+ /* error msg already filled in */
+ case COPY_GENERAL_ERROR:
SC_log_error(func, "", self);
result = SQL_ERROR;
break;
- /* This would not be meaningful in SQLFetch. */
+ /* This would not be meaningful in SQLFetch. */
case COPY_NO_DATA_FOUND:
break;
@@ -908,13 +904,10 @@ SC_execute(StatementClass *self)
CC_set_in_trans(conn);
}
-
-
oldstatus = conn->status;
conn->status = CONN_EXECUTING;
self->status = STMT_EXECUTING;
-
/* If it's a SELECT statement, use a cursor. */
/*
@@ -924,19 +917,16 @@ SC_execute(StatementClass *self)
/* in copy_statement... */
if (self->statement_type == STMT_TYPE_SELECT)
{
-
char fetch[128];
mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name);
-
/* send the declare/select */
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
if (globals.use_declarefetch && self->result != NULL &&
QR_command_successful(self->result))
{
-
QR_Destructor(self->result);
/*
@@ -954,20 +944,15 @@ SC_execute(StatementClass *self)
* will correct for any discrepancies in sizes and adjust the
* cache accordingly.
*/
-
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
self->result = CC_send_query(conn, fetch, &qi);
}
-
mylog(" done sending the query:\n");
-
-
-
}
else
- { /* not a SELECT statement so don't use a
- * cursor */
+ {
+ /* not a SELECT statement so don't use a cursor */
mylog(" it's NOT a select statement: stmt=%u\n", self);
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
@@ -986,7 +971,6 @@ SC_execute(StatementClass *self)
QR_Destructor(res);
CC_set_no_trans(conn);
}
-
}
conn->status = oldstatus;
@@ -995,7 +979,6 @@ SC_execute(StatementClass *self)
/* Check the status of the result */
if (self->result)
{
-
was_ok = QR_command_successful(self->result);
was_nonfatal = QR_command_nonfatal(self->result);
@@ -1004,8 +987,8 @@ SC_execute(StatementClass *self)
else
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
- self->currTuple = -1; /* set cursor before the first tuple in
- * the list */
+ /* set cursor before the first tuple in the list */
+ self->currTuple = -1;
self->current_col = -1;
self->rowset_start = -1;
@@ -1029,9 +1012,8 @@ SC_execute(StatementClass *self)
CC_abort(conn);
}
else
- { /* Bad Error -- The error message will be
- * in the Connection */
-
+ {
+ /* Bad Error -- The error message will be in the Connection */
if (self->statement_type == STMT_TYPE_CREATE)
{
self->errornumber = STMT_CREATE_TABLE_ERROR;
@@ -1069,6 +1051,7 @@ SC_execute(StatementClass *self)
}
}
+
void
SC_log_error(char *func, char *desc, StatementClass *self)
{