List:Commits« Previous MessageNext Message »
From:jwinstead Date:May 29 2007 7:52pm
Subject:Connector/ODBC 3.51 commit: r447 - in trunk: . driver test
View as plain text  
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 testjwinstead29 May