mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-19 02:27:55 +08:00
Store sqlState separtely on ODBC env / handle / stmts
Also fix the fact that "08001" was always returned by SQLError instead of the actual SQL state.
This commit is contained in:
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct _henv {
|
struct _henv {
|
||||||
GPtrArray *connections;
|
GPtrArray *connections;
|
||||||
|
char sqlState[6];
|
||||||
};
|
};
|
||||||
struct _hdbc {
|
struct _hdbc {
|
||||||
struct _henv *henv;
|
struct _henv *henv;
|
||||||
@@ -44,6 +45,7 @@ struct _hdbc {
|
|||||||
ConnectParams* params;
|
ConnectParams* params;
|
||||||
GPtrArray *statements;
|
GPtrArray *statements;
|
||||||
char lastError[256];
|
char lastError[256];
|
||||||
|
char sqlState[6];
|
||||||
#ifdef ENABLE_ODBC_W
|
#ifdef ENABLE_ODBC_W
|
||||||
iconv_t iconv_in;
|
iconv_t iconv_in;
|
||||||
iconv_t iconv_out;
|
iconv_t iconv_out;
|
||||||
@@ -57,6 +59,7 @@ struct _hstmt {
|
|||||||
*/
|
*/
|
||||||
char query[4096];
|
char query[4096];
|
||||||
char lastError[256];
|
char lastError[256];
|
||||||
|
char sqlState[6];
|
||||||
struct _sql_bind_info *bind_head;
|
struct _sql_bind_info *bind_head;
|
||||||
int rows_affected;
|
int rows_affected;
|
||||||
int icol; /* SQLGetData: last column */
|
int icol; /* SQLGetData: last column */
|
||||||
|
@@ -42,8 +42,6 @@ static void unbind_columns (struct _hstmt*);
|
|||||||
|
|
||||||
#define FILL_FIELD(f,v,s) mdb_fill_temp_field(f,v,s,0,0,0,0)
|
#define FILL_FIELD(f,v,s) mdb_fill_temp_field(f,v,s,0,0,0,0)
|
||||||
|
|
||||||
static __thread char sqlState[6];
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SQLCHAR *type_name;
|
SQLCHAR *type_name;
|
||||||
SQLSMALLINT data_type;
|
SQLSMALLINT data_type;
|
||||||
@@ -678,7 +676,7 @@ SQLRETURN SQL_API SQLDescribeCol(
|
|||||||
|
|
||||||
TRACE("SQLDescribeCol");
|
TRACE("SQLDescribeCol");
|
||||||
if (icol<1 || icol>sql->num_columns) {
|
if (icol<1 || icol>sql->num_columns) {
|
||||||
strcpy(sqlState, "07009"); // Invalid descriptor index
|
strcpy(stmt->sqlState, "07009"); // Invalid descriptor index
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
sqlcol = g_ptr_array_index(sql->columns,icol - 1);
|
sqlcol = g_ptr_array_index(sql->columns,icol - 1);
|
||||||
@@ -691,7 +689,7 @@ SQLRETURN SQL_API SQLDescribeCol(
|
|||||||
}
|
}
|
||||||
if (i==table->num_cols) {
|
if (i==table->num_cols) {
|
||||||
fprintf(stderr, "Column %s lost\n", (char*)sqlcol->name);
|
fprintf(stderr, "Column %s lost\n", (char*)sqlcol->name);
|
||||||
strcpy(sqlState, "07009"); // Invalid descriptor index
|
strcpy(stmt->sqlState, "07009"); // Invalid descriptor index
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,11 +698,11 @@ SQLRETURN SQL_API SQLDescribeCol(
|
|||||||
*pcbColName=strlen(sqlcol->name);
|
*pcbColName=strlen(sqlcol->name);
|
||||||
if (szColName) {
|
if (szColName) {
|
||||||
if (cbColNameMax < 0) {
|
if (cbColNameMax < 0) {
|
||||||
strcpy(sqlState, "HY090"); // Invalid string or buffer length
|
strcpy(stmt->sqlState, "HY090"); // Invalid string or buffer length
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
if (snprintf((char *)szColName, cbColNameMax, "%s", sqlcol->name) + 1 > cbColNameMax) {
|
if (snprintf((char *)szColName, cbColNameMax, "%s", sqlcol->name) + 1 > cbColNameMax) {
|
||||||
strcpy(sqlState, "01004"); // String data, right truncated
|
strcpy(stmt->sqlState, "01004"); // String data, right truncated
|
||||||
ret = SQL_SUCCESS_WITH_INFO;
|
ret = SQL_SUCCESS_WITH_INFO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -782,7 +780,7 @@ SQLRETURN SQL_API SQLColAttributes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (icol<1 || icol>sql->num_columns) {
|
if (icol<1 || icol>sql->num_columns) {
|
||||||
strcpy(sqlState, "07009"); // Invalid descriptor index
|
strcpy(stmt->sqlState, "07009"); // Invalid descriptor index
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,7 +794,7 @@ SQLRETURN SQL_API SQLColAttributes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i==table->num_cols) {
|
if (i==table->num_cols) {
|
||||||
strcpy(sqlState, "07009"); // Invalid descriptor index
|
strcpy(stmt->sqlState, "07009"); // Invalid descriptor index
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,11 +804,11 @@ SQLRETURN SQL_API SQLColAttributes(
|
|||||||
case SQL_COLUMN_NAME: case SQL_DESC_NAME:
|
case SQL_COLUMN_NAME: case SQL_DESC_NAME:
|
||||||
case SQL_COLUMN_LABEL: /* = SQL_DESC_LABEL */
|
case SQL_COLUMN_LABEL: /* = SQL_DESC_LABEL */
|
||||||
if (cbDescMax < 0) {
|
if (cbDescMax < 0) {
|
||||||
strcpy(sqlState, "HY090"); // Invalid string or buffer length
|
strcpy(stmt->sqlState, "HY090"); // Invalid string or buffer length
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
if (snprintf(rgbDesc, cbDescMax, "%s", sqlcol->name) + 1 > cbDescMax) {
|
if (snprintf(rgbDesc, cbDescMax, "%s", sqlcol->name) + 1 > cbDescMax) {
|
||||||
strcpy(sqlState, "01004"); // String data, right truncated
|
strcpy(stmt->sqlState, "01004"); // String data, right truncated
|
||||||
ret = SQL_SUCCESS_WITH_INFO;
|
ret = SQL_SUCCESS_WITH_INFO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -849,7 +847,7 @@ SQLRETURN SQL_API SQLColAttributes(
|
|||||||
*pfDesc = SQL_ATTR_READONLY;
|
*pfDesc = SQL_ATTR_READONLY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy(sqlState, "HYC00"); // Driver not capable
|
strcpy(stmt->sqlState, "HYC00"); // Driver not capable
|
||||||
ret = SQL_ERROR;
|
ret = SQL_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -912,13 +910,21 @@ SQLRETURN SQL_API SQLError(
|
|||||||
TRACE("SQLError");
|
TRACE("SQLError");
|
||||||
//if(pfNativeError)fprintf(stderr,"NativeError %05d\n", *pfNativeError);
|
//if(pfNativeError)fprintf(stderr,"NativeError %05d\n", *pfNativeError);
|
||||||
char *src = NULL;
|
char *src = NULL;
|
||||||
|
char *state = NULL;
|
||||||
if (hstmt) {
|
if (hstmt) {
|
||||||
src = ((struct _hstmt *)hstmt)->lastError;
|
src = ((struct _hstmt *)hstmt)->lastError;
|
||||||
|
state = ((struct _hstmt *)hstmt)->sqlState;
|
||||||
} else if (hdbc) {
|
} else if (hdbc) {
|
||||||
src = ((struct _hdbc *)hdbc)->lastError;
|
src = ((struct _hdbc *)hdbc)->lastError;
|
||||||
|
state = ((struct _hdbc *)hdbc)->sqlState;
|
||||||
|
} else if (henv) {
|
||||||
|
state = ((struct _henv *)henv)->sqlState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
strcpy((char*)szSqlState, state);
|
||||||
|
|
||||||
if (src && src[0]) {
|
if (src && src[0]) {
|
||||||
strcpy ((char*)szSqlState, "08001");
|
|
||||||
int l = snprintf((char*)szErrorMsg, cbErrorMsgMax, "%s", src);
|
int l = snprintf((char*)szErrorMsg, cbErrorMsgMax, "%s", src);
|
||||||
if (pcbErrorMsg)
|
if (pcbErrorMsg)
|
||||||
*pcbErrorMsg = l;
|
*pcbErrorMsg = l;
|
||||||
@@ -1095,7 +1101,7 @@ SQLRETURN SQL_API SQLFreeConnect(
|
|||||||
|
|
||||||
if (dbc->statements->len) {
|
if (dbc->statements->len) {
|
||||||
// Function sequence error
|
// Function sequence error
|
||||||
strcpy(sqlState, "HY010");
|
strcpy(dbc->sqlState, "HY010");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
if (!g_ptr_array_remove(env->connections, dbc))
|
if (!g_ptr_array_remove(env->connections, dbc))
|
||||||
@@ -1121,7 +1127,7 @@ SQLRETURN SQL_API SQLFreeEnv(
|
|||||||
|
|
||||||
if (env->connections->len) {
|
if (env->connections->len) {
|
||||||
// Function sequence error
|
// Function sequence error
|
||||||
strcpy(sqlState, "HY010");
|
strcpy(env->sqlState, "HY010");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
g_ptr_array_free(env->connections, TRUE);
|
g_ptr_array_free(env->connections, TRUE);
|
||||||
@@ -1427,7 +1433,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
mdb = sql->mdb;
|
mdb = sql->mdb;
|
||||||
|
|
||||||
if (icol<1 || icol>sql->num_columns) {
|
if (icol<1 || icol>sql->num_columns) {
|
||||||
strcpy(sqlState, "07009");
|
strcpy(stmt->sqlState, "07009");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1448,7 +1454,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!rgbValue) {
|
if (!rgbValue) {
|
||||||
strcpy(sqlState, "HY009");
|
strcpy(stmt->sqlState, "HY009");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1463,7 +1469,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
/* When NULL data is retrieved, non-null pcbValue is
|
/* When NULL data is retrieved, non-null pcbValue is
|
||||||
required */
|
required */
|
||||||
if (!pcbValue) {
|
if (!pcbValue) {
|
||||||
strcpy(sqlState, "22002");
|
strcpy(stmt->sqlState, "22002");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*pcbValue = SQL_NULL_DATA;
|
*pcbValue = SQL_NULL_DATA;
|
||||||
@@ -1479,7 +1485,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
goto found_bound_type;
|
goto found_bound_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strcpy(sqlState, "07009");
|
strcpy(stmt->sqlState, "07009");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
found_bound_type:
|
found_bound_type:
|
||||||
@@ -1501,7 +1507,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
switch (fCType) {
|
switch (fCType) {
|
||||||
case SQL_C_UTINYINT:
|
case SQL_C_UTINYINT:
|
||||||
if (intValue<0 || intValue>UCHAR_MAX) {
|
if (intValue<0 || intValue>UCHAR_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLCHAR*)rgbValue = (SQLCHAR)intValue;
|
*(SQLCHAR*)rgbValue = (SQLCHAR)intValue;
|
||||||
@@ -1511,7 +1517,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
case SQL_C_TINYINT:
|
case SQL_C_TINYINT:
|
||||||
case SQL_C_STINYINT:
|
case SQL_C_STINYINT:
|
||||||
if (intValue<SCHAR_MIN || intValue>SCHAR_MAX) {
|
if (intValue<SCHAR_MIN || intValue>SCHAR_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLSCHAR*)rgbValue = (SQLSCHAR)intValue;
|
*(SQLSCHAR*)rgbValue = (SQLSCHAR)intValue;
|
||||||
@@ -1521,7 +1527,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_SHORT:
|
case SQL_C_SHORT:
|
||||||
if (intValue<0 || intValue>USHRT_MAX) {
|
if (intValue<0 || intValue>USHRT_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
|
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
|
||||||
@@ -1530,7 +1536,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
break;
|
break;
|
||||||
case SQL_C_SSHORT:
|
case SQL_C_SSHORT:
|
||||||
if (intValue<SHRT_MIN || intValue>SHRT_MAX) {
|
if (intValue<SHRT_MIN || intValue>SHRT_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
|
*(SQLSMALLINT*)rgbValue = (SQLSMALLINT)intValue;
|
||||||
@@ -1539,7 +1545,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
break;
|
break;
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
if (intValue<0 || intValue>UINT_MAX) {
|
if (intValue<0 || intValue>UINT_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLUINTEGER*)rgbValue = (SQLINTEGER)intValue;
|
*(SQLUINTEGER*)rgbValue = (SQLINTEGER)intValue;
|
||||||
@@ -1549,7 +1555,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
case SQL_C_LONG:
|
case SQL_C_LONG:
|
||||||
case SQL_C_SLONG:
|
case SQL_C_SLONG:
|
||||||
if (intValue<INT_MIN || intValue>INT_MAX) {
|
if (intValue<INT_MIN || intValue>INT_MAX) {
|
||||||
strcpy(sqlState, "22003"); // Numeric value out of range
|
strcpy(stmt->sqlState, "22003"); // Numeric value out of range
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
*(SQLINTEGER*)rgbValue = intValue;
|
*(SQLINTEGER*)rgbValue = intValue;
|
||||||
@@ -1557,7 +1563,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
*pcbValue = sizeof(SQLINTEGER);
|
*pcbValue = sizeof(SQLINTEGER);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy(sqlState, "HYC00"); // Not implemented
|
strcpy(stmt->sqlState, "HYC00"); // Not implemented
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1627,7 +1633,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
return SQL_NO_DATA;
|
return SQL_NO_DATA;
|
||||||
}
|
}
|
||||||
if (cbValueMax < 0) {
|
if (cbValueMax < 0) {
|
||||||
strcpy(sqlState, "HY090"); // Invalid string or buffer length
|
strcpy(stmt->sqlState, "HY090"); // Invalid string or buffer length
|
||||||
free(str);
|
free(str);
|
||||||
str = NULL;
|
str = NULL;
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@@ -1662,7 +1668,7 @@ SQLRETURN SQL_API SQLGetData(
|
|||||||
if (partsRemain) {
|
if (partsRemain) {
|
||||||
stmt->pos += cbValueMax - ( needsTerminator ? 1 : 0 );
|
stmt->pos += cbValueMax - ( needsTerminator ? 1 : 0 );
|
||||||
if (col->col_type != MDB_OLE) { free(str); str = NULL; }
|
if (col->col_type != MDB_OLE) { free(str); str = NULL; }
|
||||||
strcpy(sqlState, "01004"); // truncated
|
strcpy(stmt->sqlState, "01004"); // truncated
|
||||||
return SQL_SUCCESS_WITH_INFO;
|
return SQL_SUCCESS_WITH_INFO;
|
||||||
}
|
}
|
||||||
stmt->pos = len;
|
stmt->pos = len;
|
||||||
@@ -1922,7 +1928,7 @@ SQLRETURN SQL_API SQLGetInfo(
|
|||||||
default:
|
default:
|
||||||
if (pcbInfoValue)
|
if (pcbInfoValue)
|
||||||
*pcbInfoValue = 0;
|
*pcbInfoValue = 0;
|
||||||
strcpy(sqlState, "HYC00");
|
strcpy(((struct _hdbc *)hdbc)->sqlState, "HYC00");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user