Modified:
trunk/ChangeLog
trunk/configure.in
trunk/driver/catalog.c
trunk/driver/handle.c
trunk/driver/info.c
trunk/driver/myodbc3.h
trunk/driver/results.c
trunk/test/my_catalog.c
Log:
The wrong function was used for freeing the artificial result sets that
are created by some catalog functions. (Bug #22797)
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/ChangeLog 2007-05-29 19:52:41 UTC (rev 447)
@@ -5,6 +5,8 @@
but must be enabled through configuration files or the DSN. (Bug #12918)
Bugs fixed:
+ * The wrong function was used for freeing the artificial result sets that
+ are created by some catalog functions. (Bug #22797)
* Accessing the results of catalog functions could cause a crash when the
"Don't cache results" option was set and a forward-only cursor was
being used. (Bug #4657)
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/configure.in 2007-05-29 19:52:41 UTC (rev 447)
@@ -472,12 +472,9 @@
echo "END OF MYSQL CONFIGURATION"
echo ""
echo "ODBC DRIVER MANAGER CONFIGURATION - LIBRARIES AND HEADERS"
-###################################################################
-# #
-# iODBC #
-# #
-###################################################################
+# iODBC
+
use_iODBC=no
AC_ARG_WITH(iODBC,
[ --with-iODBC[=DIR] Use iODBC located in DIR],
@@ -494,103 +491,100 @@
if test "x$use_iODBC" = "xyes"
then
+ AC_DEFINE([USE_IODBC], [1], [use iODBC])
-AC_DEFINE([USE_IODBC], [1], [use iODBC])
+ AC_ARG_WITH(iodbc-includes,
+ [ --with-iodbc-includes=DIR Find iODBC headers in DIR],
+ iodbc_includes="$withval", iodbc_includes="$iodbc/include")
-myodbc_link_dmlib="-liodbc"
+ AC_ARG_WITH(iodbc-libs,
+ [ --with-iodbc-libs=DIR Find iODBC libraries in DIR],
+ iodbc_libs="$withval", iodbc_libs="$iodbc/lib")
-AC_ARG_WITH(iodbc-includes,
-[ --with-iodbc-includes=DIR Find iODBC headers in DIR],
-iodbc_includes="$withval",iodbc_includes="$iodbc/include")
+ AC_MSG_CHECKING([for iODBC version])
+ AC_PATH_PROG(iodbc_conf, iodbc-config, no)
+ if test "$iodbc_conf" != "no"
+ then
+ iodbc_version=`$iodbc_conf --version`
+ iodbc_cflags=`$iodbc_conf --cflags`
+ if test "x$iodbc_cflags" != "x"; then
+ CFLAGS="$CFLAGS $iodbc_cflags"
+ fi
+ ODBC_DM_LIB=`$iodbc_conf --libs`
+ else
+ iodbc_version="unknown"
+ ODBC_DM_LIB="-liodbc"
+ fi
+ AC_MSG_RESULT([$iodbc_version])
-AC_ARG_WITH(iodbc-libs,
-[ --with-iodbc-libs=DIR Find iODBC libraries in DIR],
-iodbc_libs="$withval",iodbc_libs="$iodbc/lib")
+ AC_SUBST(ODBC_DM_LIB)
-# add iodbc version
-AC_PATH_PROG(iodbc_conf,iodbc-config,no)
-if test "$iodbc_conf" != "no"
-then
- iodbc_version=`$iodbc_conf --version`
-else
- iodbc_version="unknown"
-fi
-AC_MSG_CHECKING([for iodbc version])
-AC_MSG_RESULT([$iodbc_version])
+ AC_CHECK_IODBC($iodbc_includes, $iodbc_libs)
-AC_CHECK_IODBC($iodbc_includes,$iodbc_libs)
+ AC_ARG_WITH(odbc-ini,
+ [ --with-odbc-ini=PATH Location of system ODBC.INI [IODBCDIR/etc/odbc.ini]],
+ odbc_ini="$withval", odbc_ini="$iodbc/etc/odbc.ini")
-AC_ARG_WITH(odbc-ini,
-[ --with-odbc-ini=PATH Location of system odbc.ini [IODBCDIR/etc/odbc.ini]],
-odbc_ini="$withval",odbc_ini="$iodbc/etc/odbc.ini")
+ if test "x$have_iodbcinst" != "xyes"
+ then
+ AC_DEFINE_UNQUOTED(SYSTEM_ODBC_INI,"$odbc_ini",
+ [Define path to system ODBC.INI file])
+ fi
-if test "x$have_iodbcinst" != "xyes"
-then
- AC_DEFINE_UNQUOTED(SYSTEM_ODBC_INI,"$odbc_ini",
- [Define path to system wide odbc.ini file])
-fi
-ODBC_DM_PATH="--with-iodbc=$iodbc"
-AC_SUBST(ODBC_DM_PATH)
-ODBC_DM_LIB="-liodbc"
-AC_SUBST(ODBC_DM_LIB)
+ ODBC_DM_PATH="--with-iodbc=$iodbc"
+ AC_SUBST(ODBC_DM_PATH)
else
-
-###################################################################
-#
# unixODBC
-#
-###################################################################
-AC_ARG_WITH(unixODBC,
-[ --with-unixODBC[=DIR] Use unixODBC located in DIR],
-[ unixODBC="$withval" ],
-[ unixODBC="" ])
+ AC_ARG_WITH(unixODBC,
+ [ --with-unixODBC[=DIR] Use unixODBC located in DIR],
+ [ unixODBC="$withval" ], [ unixODBC="" ])
-AC_DEFINE([USE_UNIXODBC], [1], [use unixODBC])
+ AC_DEFINE([USE_UNIXODBC], [1], [use unixODBC])
-# Default to /usr if not specified
-if test "x$unixODBC" = "x" -o "x$unixODBC" = "xyes"
-then
- unixODBC="/usr";
-fi
+ # Default to /usr if not specified
+ if test "x$unixODBC" = "x" -o "x$unixODBC" = "xyes"
+ then
+ unixODBC="/usr";
+ fi
-myodbc_link_dmlib="-lodbc"
-# add unixodbc version
-AC_PATH_PROG(isql,isql,no,["$unixODBC/bin:$PATH"])
-if test "$isql" != "no"
-then
- unixodbc_version=`$isql --version`
-else
- unixodbc_version="unknown"
-fi
-AC_MSG_CHECKING([for unixODBC version])
-AC_MSG_RESULT([$unixodbc_version])
+ AC_MSG_CHECKING([for unixODBC version])
+ AC_PATH_PROG(isql, isql, no, ["$unixODBC/bin:$PATH"])
+ if test "$isql" != "no"
+ then
+ unixodbc_version=`$isql --version`
+ else
+ unixodbc_version="unknown"
+ fi
+ AC_MSG_RESULT([$unixodbc_version])
-AC_ARG_WITH(unixODBC-includes,
-[ --with-unixODBC-includes=DIR Find unixODBC headers in DIR],
-unixODBC_includes="$withval",unixODBC_includes="$unixODBC/include")
+ AC_ARG_WITH(unixODBC-includes,
+ [ --with-unixODBC-includes=DIR Find unixODBC headers in DIR],
+ unixODBC_includes="$withval",
+ unixODBC_includes="$unixODBC/include")
-AC_ARG_WITH(unixODBC-libs,
-[ --with-unixODBC-libs=DIR Find unixODBC libraries in DIR],
-unixODBC_libs="$withval",unixODBC_libs="$unixODBC/lib")
+ AC_ARG_WITH(unixODBC-libs,
+ [ --with-unixODBC-libs=DIR Find unixODBC libraries in DIR],
+ unixODBC_libs="$withval", unixODBC_libs="$unixODBC/lib")
-AC_CHECK_UNIXODBC($unixODBC_includes,$unixODBC_libs)
+ AC_CHECK_UNIXODBC($unixODBC_includes, $unixODBC_libs)
-AC_ARG_WITH(odbc-ini,
-[ --with-odbc-ini=PATH Location of system odbc.ini [UnixODBCDIR/etc/odbc.ini]],
-odbc_ini="$withval",odbc_ini="$unixODBC/etc/odbc.ini")
+ AC_ARG_WITH(odbc-ini,
+ [ --with-odbc-ini=PATH Location of system ODBC.INI
[UnixODBCDIR/etc/odbc.ini]],
+ odbc_ini="$withval", odbc_ini="$unixODBC/etc/odbc.ini")
-if test "x$have_odbcinst" != "xyes"
-then
- AC_DEFINE_UNQUOTED(SYSTEM_ODBC_INI,"$odbc_ini",
- [Define path to system wide odbc.ini file])
-fi
-ODBC_DM_PATH="--with-unixODBC=$unixODBC"
-AC_SUBST(ODBC_DM_PATH)
-ODBC_DM_LIB="-lodbc"
-AC_SUBST(ODBC_DM_LIB)
+ if test "x$have_odbcinst" != "xyes"
+ then
+ AC_DEFINE_UNQUOTED(SYSTEM_ODBC_INI,"$odbc_ini",
+ [Define path to system ODBC.INI file])
+ fi
+ ODBC_DM_PATH="--with-unixODBC=$unixODBC"
+ AC_SUBST(ODBC_DM_PATH)
+
+ ODBC_DM_LIB="-lodbc"
+ AC_SUBST(ODBC_DM_LIB)
fi
###################################################################
@@ -837,7 +831,7 @@
AC_MSG_RESULT([$enable_dmlink])
if test "x$enable_dmlink" = "xyes" ; then
- myodbc_test_linklib="$myodbc_link_dmlib"
+ myodbc_test_linklib="$ODBC_DM_LIB"
elif test "x$gotthread" = "xno" ; then
myodbc_test_linklib="../driver/libmyodbc3.la"
else
Modified: trunk/driver/catalog.c
===================================================================
--- trunk/driver/catalog.c 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/driver/catalog.c 2007-05-29 19:52:41 UTC (rev 447)
@@ -334,6 +334,7 @@
/* Return set of allowed Table owners */
MYODBCDbgInfo( "%s", "Return set of table owners / Schema names" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLTABLES_owner_values,
sizeof(SQLTABLES_owner_values),
MYF(0));
@@ -351,6 +352,7 @@
/* Return set of TableType qualifiers */
MYODBCDbgInfo( "%s", "Return set of table types" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLTABLES_type_values,
sizeof(SQLTABLES_type_values),
MYF(0));
@@ -533,6 +535,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLTABLES_values,
sizeof(SQLTABLES_values),
@@ -861,6 +864,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLCOLUMNS_values,
sizeof(SQLCOLUMNS_values),
@@ -1039,6 +1043,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLSTAT_values,
sizeof(SQLSTAT_values),
@@ -1231,6 +1236,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLTABLES_priv_values,
sizeof(SQLTABLES_priv_values),
@@ -1405,6 +1411,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLCOLUMNS_priv_values,
sizeof(SQLCOLUMNS_priv_values),
@@ -1632,6 +1639,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLSPECIALCOLUMNS_values,
sizeof(SQLSPECIALCOLUMNS_values),
@@ -1753,6 +1761,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLPRIM_KEYS_values,
sizeof(SQLPRIM_KEYS_values),
@@ -2084,7 +2093,9 @@
}
else /* NO FOREIGN KEY support from SERVER */
{
+ /** @todo this should just goto empty_set */
stmt->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->eof=1;
}
stmt->result->row_count= row_count;
@@ -2095,6 +2106,7 @@
empty_set:
MYODBCDbgInfo( "%s", "Can't match anything; Returning empty set" );
stmt->result= (MYSQL_RES*) my_malloc(sizeof(MYSQL_RES),MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result->row_count= 0;
stmt->result_array= (MYSQL_ROW) my_memdup((gptr) SQLFORE_KEYS_values,
sizeof(SQLFORE_KEYS_values),
Modified: trunk/driver/handle.c
===================================================================
--- trunk/driver/handle.c 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/driver/handle.c 2007-05-29 19:52:41 UTC (rev 447)
@@ -423,12 +423,16 @@
if (fOption == SQL_RESET_PARAMS)
MYODBCDbgReturnReturn( SQL_SUCCESS );
- mysql_free_result(stmt->result);
+ if (!stmt->fake_result)
+ mysql_free_result(stmt->result);
+ else
+ x_free((gptr)stmt->result);
x_free((gptr) stmt->fields);
x_free((gptr) stmt->array);
x_free((gptr) stmt->result_array);
x_free((gptr) stmt->odbc_types);
stmt->result= 0;
+ stmt->fake_result= 0;
stmt->result_lengths= 0;
stmt->fields= 0;
stmt->array= 0;
Modified: trunk/driver/info.c
===================================================================
--- trunk/driver/info.c 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/driver/info.c 2007-05-29 19:52:41 UTC (rev 447)
@@ -1067,6 +1067,7 @@
/* Set up result Data dictionary. */
stmt->result= (MYSQL_RES *)my_malloc(sizeof(MYSQL_RES), MYF(MY_ZEROFILL));
+ stmt->fake_result= 1;
stmt->result_array= (char **)my_malloc(sizeof(SQL_GET_TYPE_INFO_values),
MYF(MY_FAE | MY_ZEROFILL));
Modified: trunk/driver/myodbc3.h
===================================================================
--- trunk/driver/myodbc3.h 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/driver/myodbc3.h 2007-05-29 19:52:41 UTC (rev 447)
@@ -325,6 +325,7 @@
{
DBC FAR *dbc;
MYSQL_RES *result;
+ my_bool fake_result;
MYSQL_ROW array,result_array,current_values;
MYSQL_ROW (*fix_fields)(struct tagSTMT FAR* stmt,MYSQL_ROW row);
MYSQL_FIELD *fields;
Modified: trunk/driver/results.c
===================================================================
--- trunk/driver/results.c 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/driver/results.c 2007-05-29 19:52:41 UTC (rev 447)
@@ -747,8 +747,12 @@
pthread_mutex_lock(&stmt->dbc->lock);
x_free((gptr) stmt->odbc_types);
- mysql_free_result(stmt->result);
+ if (!stmt->fake_result)
+ mysql_free_result(stmt->result);
+ else
+ x_free((gptr)stmt->result);
stmt->result= 0;
+ stmt->fake_result= 0;
stmt->odbc_types= 0;
stmt->cursor_row= 0;
stmt->result= mysql_store_result(&stmt->dbc->mysql);
Modified: trunk/test/my_catalog.c
===================================================================
--- trunk/test/my_catalog.c 2007-05-29 16:22:49 UTC (rev 446)
+++ trunk/test/my_catalog.c 2007-05-29 19:52:41 UTC (rev 447)
@@ -1172,6 +1172,51 @@
}
+/**
+ Tests the non-error code paths in catalog.c that return an empty set to
+ make sure the resulting empty result sets at least indicate the right
+ number of columns.
+*/
+DECLARE_TEST(empty_set)
+{
+ SQLSMALLINT columns;
+
+ /* SQLTables(): no known table types. */
+ ok_stmt(hstmt, SQLTables(hstmt, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS,
+ (SQLCHAR *)"UNKNOWN", SQL_NTS));
+ ok_stmt(hstmt, SQLNumResultCols(hstmt, &columns));
+ is_num(columns, 5);
+ expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND);
+ ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
+
+ /* SQLTables(): no tables found. */
+ ok_stmt(hstmt, SQLTables(hstmt, NULL, SQL_NTS, NULL, SQL_NTS,
+ (SQLCHAR *)"no_such_table", SQL_NTS, NULL, SQL_NTS));
+ ok_stmt(hstmt, SQLNumResultCols(hstmt, &columns));
+ is_num(columns, 5);
+ expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND);
+ ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
+
+ /* SQLColumns(): no table specified. */
+ ok_stmt(hstmt, SQLColumns(hstmt, NULL, SQL_NTS, NULL, SQL_NTS,
+ NULL, SQL_NTS, NULL, SQL_NTS));
+ ok_stmt(hstmt, SQLNumResultCols(hstmt, &columns));
+ is_num(columns, 18);
+ expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND);
+ ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
+
+ /* SQLStatistics(): no table specified. */
+ ok_stmt(hstmt, SQLStatistics(hstmt, NULL, SQL_NTS, NULL, SQL_NTS,
+ NULL, SQL_NTS, 0, 0));
+ ok_stmt(hstmt, SQLNumResultCols(hstmt, &columns));
+ is_num(columns, 13);
+ expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND);
+ ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
+
+ return OK;
+}
+
+
BEGIN_TESTS
ADD_TEST(my_columns_null)
ADD_TEST(my_drop_table)
@@ -1189,6 +1234,7 @@
ADD_TEST(tmysql_showkeys)
ADD_TEST(t_sqltables)
ADD_TEST(t_bug4518)
+ ADD_TEST(empty_set)
END_TESTS
| Thread |
|---|
| • Connector/ODBC 3.51 commit: r447 - in trunk: . driver test | jwinstead | 29 May |