=== modified file 'cmake/FindMySQL.cmake' --- cmake/FindMySQL.cmake 2010-08-19 15:37:55 +0000 +++ cmake/FindMySQL.cmake 2011-07-22 19:39:08 +0000 @@ -61,6 +61,7 @@ $ENV{MYSQL_DIR}/client/${libsuffixBuild} $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild} $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist} + $ENV{ProgramFiles}/MySQL/*/lib $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist}) ELSE (WIN32) FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient_r === modified file 'driver/catalog_no_i_s.c' --- driver/catalog_no_i_s.c 2011-05-31 10:42:22 +0000 +++ driver/catalog_no_i_s.c 2011-07-25 09:33:00 +0000 @@ -167,7 +167,6 @@ const uint SQLCOLUMNS_FIELDS= array_elements(SQLCOLUMNS_values); - /** Get the list of columns in a table matching a wildcard. @@ -181,107 +180,50 @@ @return Result of SHOW COLUMNS FROM, or NULL if there is an error */ -static -MYSQL_RES *mysql_list_dbcolumns(STMT *stmt, - SQLCHAR *szCatalog, SQLSMALLINT cbCatalog, - SQLCHAR *szTable, SQLSMALLINT cbTable, - SQLCHAR *szColumn, SQLSMALLINT cbColumn) +static MYSQL_RES * +mysql_list_dbcolumns(STMT *stmt, + SQLCHAR *szCatalog, SQLSMALLINT cbCatalog, + SQLCHAR *szTable, SQLSMALLINT cbTable, + SQLCHAR *szColumn, SQLSMALLINT cbColumn) { DBC *dbc= stmt->dbc; MYSQL *mysql= &dbc->mysql; MYSQL_RES *result; - MYSQL_ROW row; /* If a catalog was specified, we have to do it the hard way. */ if (cbCatalog) { char buff[255]; - char *select, *to; - size_t select_len; - unsigned long *lengths; - - /* Get a list of column names that match our criteria. */ - to= strmov(buff, "SHOW COLUMNS FROM `"); - if (cbCatalog) - { - to+= myodbc_escape_string(mysql, to, (ulong)(sizeof(buff) - (to - buff)), - (char *)szCatalog, cbCatalog, 1); - to= strmov(to, "`.`"); - } - - to+= myodbc_escape_string(mysql, to, (ulong)(sizeof(buff) - (to - buff)), - (char *)szTable, cbTable, 1); - to= strmov(to, "`"); - - if (cbColumn) - { - to= strmov(to, " LIKE '"); - to+= mysql_real_escape_string(mysql, to, (char *)szColumn, cbColumn); - to= strmov(to, "'"); - } - - MYLOG_QUERY(stmt, buff); - - pthread_mutex_lock(&dbc->lock); - if (mysql_query(mysql,buff) || - !(result= mysql_store_result(mysql))) - { - pthread_mutex_unlock(&dbc->lock); - return NULL; - } - pthread_mutex_unlock(&dbc->lock); - - /* Build a SELECT ... LIMIT 0 to get the field metadata. */ - select_len = (ulong)result->row_count * (NAME_LEN + 1) + NAME_LEN * 2; - if (!(select= (char *)my_malloc(select_len, MYF(0)))) - { - set_mem_error(mysql); - return NULL; - } - - to= strxmov(select, "SELECT ", NullS); - while ((row= mysql_fetch_row(result))) - { - to= strmov(to, "`"); - lengths= mysql_fetch_lengths(result); - to+= myodbc_escape_string(mysql, to, (ulong)(select_len - (to - select)), - (char *)row[0], lengths[0], 1); - to= strmov(to, "`,"); - } - *(--to)= '\0'; - - to= strmov(to, " FROM `"); - if (cbCatalog) - { - to+= myodbc_escape_string(mysql, to, (ulong)(select_len - (to - select)), - (char *)szCatalog, cbCatalog, 1); - to= strmov(to, "`.`"); - } - - to+= myodbc_escape_string(mysql, to, (ulong)(select_len - (to - select)), - (char *)szTable, cbTable, 1); - to= strmov(to, "` LIMIT 0"); - - mysql_free_result(result); - - MYLOG_QUERY(stmt, select); - - pthread_mutex_lock(&dbc->lock); - if (mysql_query(mysql, select)) - { - x_free(select); - pthread_mutex_unlock(&dbc->lock); - return NULL; - } - result= mysql_store_result(&dbc->mysql); - pthread_mutex_unlock(&dbc->lock); - x_free(select); - - return result; + + if (reget_current_catalog(dbc)) + return NULL; + + /* reget_current_catalog locks mutex, so locking here */ + pthread_mutex_lock(&dbc->lock); + + strncpy(buff, szCatalog, cbCatalog); + buff[cbCatalog]= '\0'; + + if (mysql_select_db(mysql, buff)) + { + pthread_mutex_unlock(&dbc->lock); + return NULL; + } } + else + pthread_mutex_lock(&dbc->lock); - pthread_mutex_lock(&dbc->lock); result= mysql_list_fields(mysql, (char *)szTable, (char *)szColumn); + if (cbCatalog) + { + if (mysql_select_db( mysql, dbc->database)) + { + /* Well, probably have to return error here */ + mysql_free_result(result); + pthread_mutex_unlock(&dbc->lock); + return NULL; + } + } pthread_mutex_unlock(&dbc->lock); return result; @@ -302,23 +244,24 @@ @param[in] cbColumn Length of column pattern */ SQLRETURN -mysql_columns(SQLHSTMT hstmt, SQLCHAR *szCatalog, SQLSMALLINT cbCatalog, +mysql_columns(STMT * stmt, SQLCHAR *szCatalog, SQLSMALLINT cbCatalog, SQLCHAR *szSchema __attribute__((unused)), SQLSMALLINT cbSchema __attribute__((unused)), SQLCHAR *szTable, SQLSMALLINT cbTable, SQLCHAR *szColumn, SQLSMALLINT cbColumn) { - STMT *stmt= (STMT *)hstmt; MYSQL_RES *res; MEM_ROOT *alloc; MYSQL_ROW table_row; unsigned long rows= 0, next_row= 0, *lengths; char *db= NULL; + BOOL is_access= FALSE; /* Get the list of tables that match szCatalog and szTable */ pthread_mutex_lock(&stmt->dbc->lock); - res= mysql_table_status(stmt, szCatalog, cbCatalog, szTable, cbTable, TRUE, TRUE, TRUE); + res= mysql_table_status(stmt, szCatalog, cbCatalog, szTable, cbTable, TRUE, + TRUE, TRUE); if (!res && mysql_errno(&stmt->dbc->mysql)) { @@ -333,6 +276,11 @@ } pthread_mutex_unlock(&stmt->dbc->lock); +#ifdef _WIN32 + if (GetModuleHandle("msaccess.exe") != NULL) + is_access= TRUE; +#endif + stmt->result= res; alloc= &res->field_alloc; @@ -410,9 +358,13 @@ if (is_char_sql_type(type) || is_wchar_sql_type(type) || is_binary_sql_type(type)) + { row[15]= strdup_root(alloc, buff); /* CHAR_OCTET_LENGTH */ + } else + { row[15]= NULL; /* CHAR_OCTET_LENGTH */ + } { SQLSMALLINT digits= get_decimal_digits(stmt, field); @@ -438,9 +390,18 @@ if ((field->flags & NOT_NULL_FLAG) && !(field->flags & TIMESTAMP_FLAG) && !(field->flags & AUTO_INCREMENT_FLAG)) { - sprintf(buff, "%d", SQL_NO_NULLS); - row[10]= strdup_root(alloc, buff); /* NULLABLE */ - row[17]= strdup_root(alloc, "NO"); /* IS_NULLABLE */ + if (is_access) + { + sprintf(buff, "%d", SQL_NULLABLE_UNKNOWN); + row[10]= strdup_root(alloc, buff); /* NULLABLE */ + row[17]= strdup_root(alloc, "NO");/* IS_NULLABLE */ + } + else + { + sprintf(buff, "%d", SQL_NO_NULLS); + row[10]= strdup_root(alloc, buff); /* NULLABLE */ + row[17]= strdup_root(alloc, "NO"); /* IS_NULLABLE */ + } } else { @@ -452,17 +413,17 @@ row[11]= ""; /* REMARKS */ /* - The default value of the column. The value in this column should be - interpreted as a string if it is enclosed in quotation marks. - - if NULL was specified as the default value, then this column is the - word NULL, not enclosed in quotation marks. If the default value - cannot be represented without truncation, then this column contains - TRUNCATED, with no enclosing single quotation marks. If no default - value was specified, then this column is NULL. - - The value of COLUMN_DEF can be used in generating a new column - definition, except when it contains the value TRUNCATED + The default value of the column. The value in this column should be + interpreted as a string if it is enclosed in quotation marks. + + if NULL was specified as the default value, then this column is the + word NULL, not enclosed in quotation marks. If the default value + cannot be represented without truncation, then this column contains + TRUNCATED, with no enclosing single quotation marks. If no default + value was specified, then this column is NULL. + + The value of COLUMN_DEF can be used in generating a new column + definition, except when it contains the value TRUNCATED */ if (!field->def) row[12]= NullS; /* COLUMN_DEF */ @@ -470,14 +431,20 @@ { if (field->type == MYSQL_TYPE_TIMESTAMP && !strcmp(field->def,"0000-00-00 00:00:00")) + { row[12]= NullS; /* COLUMN_DEF */ + } else { char *def= alloc_root(alloc, strlen(field->def) + 3); if (is_numeric_mysql_type(field)) + { sprintf(def, "%s", field->def); + } else + { sprintf(def, "'%s'", field->def); + } row[12]= def; /* COLUMN_DEF */ } } === modified file 'driver/connect.c' --- driver/connect.c 2011-06-21 21:10:42 +0000 +++ driver/connect.c 2011-07-23 15:12:52 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/ODBC is licensed under the terms of the GPLv2 , like most @@ -123,8 +123,11 @@ We always set character_set_results to NULL so we can do our own conversion to the ANSI character set or Unicode. */ - if (odbc_stmt(dbc, "SET character_set_results = NULL") != SQL_SUCCESS) + if (is_minimum_version(dbc->mysql.server_version, "4.1.1", 5) + && odbc_stmt(dbc, "SET character_set_results = NULL") != SQL_SUCCESS) + { return SQL_ERROR; + } return SQL_SUCCESS; } === modified file 'test/my_catalog.c' --- test/my_catalog.c 2011-04-07 16:56:16 +0000 +++ test/my_catalog.c 2011-07-25 09:37:20 +0000 @@ -2309,6 +2309,35 @@ } +/** + Bug#31067 test. Testing only part of the patch, as the report itself + is about Access and can't be tested automatically. The test checks + if SQLColumns returns correct default value if table's catalog specified. +*/ +DECLARE_TEST(t_bug31067) +{ + SQLCHAR buff[512]; + + ok_sql(hstmt, "DROP DATABASE IF EXISTS bug31067"); + ok_sql(hstmt, "CREATE DATABASE bug31067"); + ok_sql(hstmt, "CREATE TABLE bug31067.a (a varchar(10) not null default 'bug31067')"); + + /* Get the info from just one table. */ + ok_stmt(hstmt, SQLColumns(hstmt, (SQLCHAR *)"bug31067", SQL_NTS, NULL, SQL_NTS, + (SQLCHAR *)"a", SQL_NTS, NULL, 0)); + + ok_stmt(hstmt, SQLFetch(hstmt)); + + is_str(my_fetch_str(hstmt, buff, 13), "'bug31067'", 11); + + expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND); + + ok_sql(hstmt, "DROP DATABASE bug31067"); + + return OK; +} + + BEGIN_TESTS ADD_TEST(my_columns_null) ADD_TEST(my_drop_table) @@ -2350,6 +2379,7 @@ ADD_TEST(t_sqlprocedurecolumns) ADD_TEST(t_bug57182) ADD_TEST(t_bug55870) + ADD_TEST(t_bug31067) END_TESTS === modified file 'test/odbctap.h' --- test/odbctap.h 2011-04-07 16:56:16 +0000 +++ test/odbctap.h 2011-07-25 09:44:57 +0000 @@ -885,7 +885,13 @@ SQLLEN nLen; SQLGetData(hstmt,icol,SQL_CHAR,szData,MAX_ROW_DATA_LEN+1,&nLen); - printMessage(" my_fetch_str: %s(%ld)",szData,nLen); + /* If Null value - putting down smth meaningful. also that allows caller to + better/(in more easy way) test the value */ + if (nLen < 0) + { + strcpy(szData, "(Null)"); + } + printMessage(" my_fetch_str: %s(%ld)", szData, nLen); return((const char *)szData); }