mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
Fixed a severe design flaw in ODBC driver that prevented the driver from using multiple SELECTs at once and instead crashed the driver
This commit is contained in:
parent
f1bc697d6a
commit
0e508c82d8
@ -36,15 +36,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct _henv {
|
||||
MdbSQL *sql;
|
||||
GPtrArray *connections;
|
||||
};
|
||||
struct _hdbc {
|
||||
struct _henv *henv;
|
||||
MdbSQL *sqlconn;
|
||||
ConnectParams* params;
|
||||
GPtrArray *statements;
|
||||
};
|
||||
struct _hstmt {
|
||||
MdbSQL *sql;
|
||||
struct _hdbc *hdbc;
|
||||
/* reminder to self: the following is here for testing purposes.
|
||||
* please make dynamic before checking in
|
||||
|
@ -184,9 +184,8 @@ static SQLRETURN do_connect (
|
||||
char *database)
|
||||
{
|
||||
struct _hdbc *dbc = (struct _hdbc *) hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
|
||||
if (mdb_sql_open(env->sql, database))
|
||||
if (mdb_sql_open(dbc->sqlconn, database))
|
||||
return SQL_SUCCESS;
|
||||
else
|
||||
return SQL_ERROR;
|
||||
@ -325,8 +324,6 @@ SQLRETURN SQL_API SQLExtendedFetch(
|
||||
SQLUSMALLINT *rgfRowStatus)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
|
||||
TRACE("SQLExtendedFetch");
|
||||
if (fFetchType!=SQL_FETCH_NEXT) {
|
||||
@ -340,7 +337,7 @@ SQLRETURN SQL_API SQLExtendedFetch(
|
||||
|
||||
bind_columns(stmt);
|
||||
|
||||
if (mdb_fetch_row(env->sql->cur_table)) {
|
||||
if (mdb_fetch_row(stmt->sql->cur_table)) {
|
||||
stmt->rows_affected++;
|
||||
return SQL_SUCCESS;
|
||||
} else {
|
||||
@ -543,6 +540,7 @@ struct _hdbc* dbc;
|
||||
g_ptr_array_add(env->connections, dbc);
|
||||
dbc->params = NewConnectParams ();
|
||||
dbc->statements = g_ptr_array_new();
|
||||
dbc->sqlconn = mdb_sql_init();
|
||||
*phdbc=dbc;
|
||||
|
||||
return SQL_SUCCESS;
|
||||
@ -562,7 +560,6 @@ struct _henv *env;
|
||||
|
||||
TRACE("_SQLAllocEnv");
|
||||
env = (SQLHENV) g_malloc0(sizeof(struct _henv));
|
||||
env->sql = mdb_sql_init();
|
||||
env->connections = g_ptr_array_new();
|
||||
*phenv=env;
|
||||
return SQL_SUCCESS;
|
||||
@ -588,6 +585,8 @@ static SQLRETURN SQL_API _SQLAllocStmt(
|
||||
stmt = (SQLHSTMT) g_malloc0(sizeof(struct _hstmt));
|
||||
stmt->hdbc=dbc;
|
||||
g_ptr_array_add(dbc->statements, stmt);
|
||||
stmt->sql = mdb_sql_init();
|
||||
stmt->sql->mdb = mdb_clone_handle(dbc->sqlconn->mdb);
|
||||
|
||||
*phstmt = stmt;
|
||||
return SQL_SUCCESS;
|
||||
@ -748,9 +747,7 @@ static SQLRETURN SQL_API _SQLDescribeCol(
|
||||
{
|
||||
int namelen, i;
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
MdbSQL *sql = env->sql;
|
||||
MdbSQL *sql = stmt->sql;
|
||||
MdbSQLColumn *sqlcol;
|
||||
MdbColumn *col;
|
||||
MdbTableDef *table;
|
||||
@ -866,8 +863,6 @@ static SQLRETURN SQL_API _SQLColAttributes(
|
||||
{
|
||||
int namelen, i;
|
||||
struct _hstmt *stmt;
|
||||
struct _hdbc *dbc;
|
||||
struct _henv *env;
|
||||
MdbSQL *sql;
|
||||
MdbSQLColumn *sqlcol;
|
||||
MdbColumn *col;
|
||||
@ -876,15 +871,13 @@ static SQLRETURN SQL_API _SQLColAttributes(
|
||||
|
||||
TRACE("_SQLColAttributes");
|
||||
stmt = (struct _hstmt *) hstmt;
|
||||
dbc = (struct _hdbc *) stmt->hdbc;
|
||||
env = (struct _henv *) dbc->henv;
|
||||
sql = env->sql;
|
||||
sql = stmt->sql;
|
||||
|
||||
/* dont check column index for these */
|
||||
switch(fDescType) {
|
||||
case SQL_COLUMN_COUNT:
|
||||
case SQL_DESC_COUNT:
|
||||
*pfDesc = env->sql->num_columns;
|
||||
*pfDesc = stmt->sql->num_columns;
|
||||
return SQL_SUCCESS;
|
||||
break;
|
||||
}
|
||||
@ -1004,16 +997,14 @@ SQLRETURN SQL_API SQLDisconnect(
|
||||
SQLHDBC hdbc)
|
||||
{
|
||||
struct _hdbc *dbc;
|
||||
struct _henv *env;
|
||||
|
||||
TRACE("SQLDisconnect");
|
||||
|
||||
dbc = (struct _hdbc *) hdbc;
|
||||
env = (struct _henv *) dbc->henv;
|
||||
// Automatically close all statements:
|
||||
while (dbc->statements->len)
|
||||
_SQLFreeStmt(g_ptr_array_index(dbc->statements, 0), SQL_DROP);
|
||||
mdb_sql_close(env->sql);
|
||||
mdb_sql_close(dbc->sqlconn);
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
@ -1097,20 +1088,18 @@ SQLRETURN SQL_API SQLErrorW(
|
||||
static SQLRETURN SQL_API _SQLExecute( SQLHSTMT hstmt)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
|
||||
TRACE("_SQLExecute");
|
||||
|
||||
/* fprintf(stderr,"query = %s\n",stmt->query); */
|
||||
_odbc_fix_literals(stmt);
|
||||
|
||||
mdb_sql_reset(env->sql);
|
||||
mdb_sql_reset(stmt->sql);
|
||||
|
||||
mdb_sql_run_query(env->sql, stmt->query);
|
||||
if (mdb_sql_has_error(env->sql)) {
|
||||
mdb_sql_run_query(stmt->sql, stmt->query);
|
||||
if (mdb_sql_has_error(stmt->sql)) {
|
||||
LogError("Couldn't parse SQL\n");
|
||||
mdb_sql_reset(env->sql);
|
||||
mdb_sql_reset(stmt->sql);
|
||||
return SQL_ERROR;
|
||||
} else {
|
||||
return SQL_SUCCESS;
|
||||
@ -1171,8 +1160,6 @@ SQLRETURN SQL_API SQLExecute(
|
||||
static void
|
||||
bind_columns(struct _hstmt *stmt)
|
||||
{
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
struct _sql_bind_info *cur;
|
||||
|
||||
TRACE("bind_columns");
|
||||
@ -1181,8 +1168,8 @@ bind_columns(struct _hstmt *stmt)
|
||||
cur = stmt->bind_head;
|
||||
while (cur) {
|
||||
if (cur->column_number>0 &&
|
||||
cur->column_number <= env->sql->num_columns) {
|
||||
mdb_sql_bind_column(env->sql, cur->column_number,
|
||||
cur->column_number <= stmt->sql->num_columns) {
|
||||
mdb_sql_bind_column(stmt->sql, cur->column_number,
|
||||
cur->varaddr, cur->column_lenbind);
|
||||
} else {
|
||||
/* log error ? */
|
||||
@ -1213,8 +1200,6 @@ SQLRETURN SQL_API SQLFetch(
|
||||
SQLHSTMT hstmt)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
|
||||
TRACE("SQLFetch");
|
||||
/* if we bound columns, transfer them to res_info now that we have one */
|
||||
@ -1222,13 +1207,13 @@ SQLRETURN SQL_API SQLFetch(
|
||||
//cur = stmt->bind_head;
|
||||
//while (cur) {
|
||||
//if (cur->column_number>0 &&
|
||||
//cur->column_number <= env->sql->num_columns) {
|
||||
//cur->column_number <= stmt->sql->num_columns) {
|
||||
// if (cur->column_lenbind) *(cur->column_lenbind) = 4;
|
||||
//}
|
||||
//cur = cur->next;
|
||||
//}
|
||||
|
||||
if (mdb_fetch_row(env->sql->cur_table)) {
|
||||
if (mdb_fetch_row(stmt->sql->cur_table)) {
|
||||
stmt->rows_affected++;
|
||||
stmt->pos=0;
|
||||
return SQL_SUCCESS;
|
||||
@ -1276,6 +1261,7 @@ static SQLRETURN SQL_API _SQLFreeConnect(
|
||||
|
||||
FreeConnectParams(dbc->params);
|
||||
g_ptr_array_free(dbc->statements, TRUE);
|
||||
mdb_sql_exit(dbc->sqlconn);
|
||||
g_free(dbc);
|
||||
|
||||
return SQL_SUCCESS;
|
||||
@ -1301,7 +1287,6 @@ static SQLRETURN SQL_API _SQLFreeEnv(
|
||||
return SQL_ERROR;
|
||||
}
|
||||
g_ptr_array_free(env->connections, TRUE);
|
||||
mdb_sql_exit(env->sql);
|
||||
g_free(env);
|
||||
|
||||
return SQL_SUCCESS;
|
||||
@ -1319,14 +1304,12 @@ static SQLRETURN SQL_API _SQLFreeStmt(
|
||||
{
|
||||
struct _hstmt *stmt=(struct _hstmt *)hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
MdbSQL *sql = env->sql;
|
||||
|
||||
TRACE("_SQLFreeStmt");
|
||||
if (fOption==SQL_DROP) {
|
||||
if (!g_ptr_array_remove(dbc->statements, stmt))
|
||||
return SQL_INVALID_HANDLE;
|
||||
mdb_sql_reset(sql);
|
||||
mdb_sql_exit(stmt->sql);
|
||||
unbind_columns(stmt);
|
||||
g_free(stmt);
|
||||
} else if (fOption==SQL_CLOSE) {
|
||||
@ -1373,11 +1356,9 @@ SQLRETURN SQL_API SQLNumResultCols(
|
||||
SQLSMALLINT *pccol)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
|
||||
TRACE("SQLNumResultCols");
|
||||
*pccol = env->sql->num_columns;
|
||||
*pccol = stmt->sql->num_columns;
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1453,9 +1434,7 @@ static SQLRETURN SQL_API _SQLColumns(
|
||||
SQLSMALLINT cbColumnName)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
MdbSQL *sql = env->sql;
|
||||
MdbSQL *sql = stmt->sql;
|
||||
MdbHandle *mdb = sql->mdb;
|
||||
MdbTableDef *ttable;
|
||||
MdbField fields[18];
|
||||
@ -1600,8 +1579,6 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
SQLLEN *pcbValue)
|
||||
{
|
||||
struct _hstmt *stmt;
|
||||
struct _hdbc *dbc;
|
||||
struct _henv *env;
|
||||
MdbSQL *sql;
|
||||
MdbHandle *mdb;
|
||||
MdbSQLColumn *sqlcol;
|
||||
@ -1611,9 +1588,7 @@ static SQLRETURN SQL_API _SQLGetData(
|
||||
|
||||
TRACE("_SQLGetData");
|
||||
stmt = (struct _hstmt *) hstmt;
|
||||
dbc = (struct _hdbc *) stmt->hdbc;
|
||||
env = (struct _henv *) dbc->henv;
|
||||
sql = env->sql;
|
||||
sql = stmt->sql;
|
||||
mdb = sql->mdb;
|
||||
|
||||
if (icol<1 || icol>sql->num_columns) {
|
||||
@ -2152,10 +2127,8 @@ SQLRETURN SQL_API SQLGetTypeInfo(
|
||||
SQLSMALLINT fSqlType)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
MdbTableDef *ttable;
|
||||
MdbSQL *sql = env->sql;
|
||||
MdbSQL *sql = stmt->sql;
|
||||
MdbHandle *mdb = sql->mdb;
|
||||
int row_size;
|
||||
unsigned char row_buffer[MDB_PGSIZE];
|
||||
@ -2310,9 +2283,7 @@ SQLRETURN SQL_API SQLTables( //sz* not used, so Unicode API not required.
|
||||
SQLSMALLINT cbTableType)
|
||||
{
|
||||
struct _hstmt *stmt = (struct _hstmt *) hstmt;
|
||||
struct _hdbc *dbc = (struct _hdbc *) stmt->hdbc;
|
||||
struct _henv *env = (struct _henv *) dbc->henv;
|
||||
MdbSQL *sql = env->sql;
|
||||
MdbSQL *sql = stmt->sql;
|
||||
MdbHandle *mdb = sql->mdb;
|
||||
MdbTableDef *ttable;
|
||||
MdbField fields[5];
|
||||
|
Loading…
Reference in New Issue
Block a user