aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/odbc/environ.c40
-rw-r--r--src/interfaces/odbc/statement.c10
-rw-r--r--src/interfaces/odbc/statement.h2
3 files changed, 48 insertions, 4 deletions
diff --git a/src/interfaces/odbc/environ.c b/src/interfaces/odbc/environ.c
index 5a6b6b11a3b..506ca5cf7ba 100644
--- a/src/interfaces/odbc/environ.c
+++ b/src/interfaces/odbc/environ.c
@@ -91,12 +91,16 @@ SQLError(
char *msg;
int status;
- mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt);
+ mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u <%d>\n", henv, hdbc, hstmt, cbErrorMsgMax);
+ if (cbErrorMsgMax < 0)
+ return SQL_ERROR;
if (SQL_NULL_HSTMT != hstmt)
{
/* CC: return an error of a hstmt */
StatementClass *stmt = (StatementClass *) hstmt;
+ SWORD msglen;
+ BOOL once_again = FALSE;
if (SC_get_error(stmt, &status, &msg))
{
@@ -112,8 +116,18 @@ SQLError(
return SQL_NO_DATA_FOUND;
}
+ msglen = (SWORD) strlen(msg);
if (NULL != pcbErrorMsg)
- *pcbErrorMsg = (SWORD) strlen(msg);
+ {
+ *pcbErrorMsg = msglen;
+ if (cbErrorMsgMax == 0)
+ once_again = TRUE;
+ else if (msglen >= cbErrorMsgMax)
+ {
+ once_again = TRUE;
+ *pcbErrorMsg = cbErrorMsgMax - 1;
+ }
+ }
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
@@ -238,7 +252,27 @@ SQLError(
return SQL_NO_DATA_FOUND;
}
- return SQL_SUCCESS;
+ if (once_again)
+ {
+ int outlen;
+ stmt->errornumber = status;
+ if (cbErrorMsgMax > 0)
+ outlen = *pcbErrorMsg;
+ else
+ outlen = 0;
+ if (!stmt->errormsg_malloced || !stmt->errormsg)
+ {
+ stmt->errormsg = malloc(msglen - outlen + 1);
+ stmt->errormsg_malloced = TRUE;
+ }
+ memmove(stmt->errormsg, msg + outlen, msglen - outlen + 1);
+ }
+ else if (stmt->errormsg_malloced)
+ SC_clear_error(stmt);
+ if (cbErrorMsgMax == 0)
+ return SQL_SUCCESS_WITH_INFO;
+ else
+ return SQL_SUCCESS;
}
else if (SQL_NULL_HDBC != hdbc)
{
diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c
index ba6ca3efbd4..fd77eee6d6c 100644
--- a/src/interfaces/odbc/statement.c
+++ b/src/interfaces/odbc/statement.c
@@ -248,6 +248,7 @@ SC_Constructor(void)
rv->errormsg = NULL;
rv->errornumber = 0;
rv->errormsg_created = FALSE;
+ rv->errormsg_malloced = FALSE;
rv->statement = NULL;
rv->stmt_with_params = NULL;
@@ -530,9 +531,12 @@ SC_recycle_statement(StatementClass *self)
self->bind_row = 0;
self->last_fetch_count = 0;
+ if (self->errormsg_malloced && self->errormsg)
+ free(self->errormsg);
self->errormsg = NULL;
self->errornumber = 0;
self->errormsg_created = FALSE;
+ self->errormsg_malloced = FALSE;
self->lobj_fd = -1;
@@ -610,9 +614,12 @@ SC_unbind_cols(StatementClass *self)
void
SC_clear_error(StatementClass *self)
{
+ if (self->errormsg_malloced && self->errormsg)
+ free(self->errormsg);
self->errornumber = 0;
self->errormsg = NULL;
self->errormsg_created = FALSE;
+ self->errormsg_malloced = FALSE;
}
@@ -675,7 +682,8 @@ SC_get_error(StatementClass *self, int *number, char **message)
{
*number = self->errornumber;
*message = self->errormsg;
- self->errormsg = NULL;
+ if (!self->errormsg_malloced)
+ self->errormsg = NULL;
}
rv = (self->errornumber != 0);
diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h
index fe0b4a0b720..3f2fef5db7d 100644
--- a/src/interfaces/odbc/statement.h
+++ b/src/interfaces/odbc/statement.h
@@ -218,6 +218,8 @@ struct StatementClass_
char pre_executing; /* This statement is prematurely executing */
char inaccurate_result; /* Current status is PREMATURE but
* result is inaccurate */
+ char errormsg_malloced; /* Current status is PREMATURE but
+ * result is inaccurate */
};
#define SC_get_conn(a) (a->hdbc)