Skip to content

Commit a83a757

Browse files
author
Bogdan Degtyariov
committed
SQLTABLES patch (Bug 13914518) has to be extended for NO_I_S case (Bug# 14005343)
1 parent c27343f commit a83a757

File tree

5 files changed

+323
-125
lines changed

5 files changed

+323
-125
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
Bugs fixed:
99
* SQL_ATTR_MAX_ROWS applies to all result sets on the statement,
1010
and not connection (Bug# 17259397/69554)
11+
* SQLTABLES patch (Bug 13914518) has to be extended for NO_I_S case
12+
(Bug# 14005343)
1113

1214
Built using MySQL 5.7.
1315

driver/catalog.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ static MYSQL_RES *table_status_i_s(STMT *stmt,
156156
char buff[255+4*NAME_CHAR_LEN], *to;
157157
my_bool clause_added= FALSE;
158158

159-
to= my_stpmov(buff, "SELECT TABLE_NAME, TABLE_COMMENT, TABLE_TYPE, TABLE_SCHEMA \
160-
FROM INFORMATION_SCHEMA.TABLES \
161-
WHERE ");
159+
to= my_stpmov(buff, "SELECT TABLE_NAME, TABLE_COMMENT, TABLE_TYPE, TABLE_SCHEMA " \
160+
"FROM ( SELECT * FROM INFORMATION_SCHEMA.TABLES " \
161+
"WHERE ");
162162

163163
if (catalog_name && *catalog_name)
164164
{
@@ -192,6 +192,7 @@ static MYSQL_RES *table_status_i_s(STMT *stmt,
192192
if (show_tables)
193193
to= my_stpmov(to, ") ");
194194
}
195+
to = my_stpmov(to, ") TABLES ");
195196

196197
/*
197198
As a pattern-value argument, an empty string needs to be treated
@@ -203,7 +204,7 @@ static MYSQL_RES *table_status_i_s(STMT *stmt,
203204

204205
if (table_name && *table_name)
205206
{
206-
to= my_stpmov(to, "AND TABLE_NAME LIKE '");
207+
to= my_stpmov(to, "WHERE TABLE_NAME LIKE '");
207208
if (wildcard)
208209
{
209210
to+= mysql_real_escape_string(mysql, to, (char *)table_name, table_len);

driver/catalog_no_i_s.c

Lines changed: 198 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,40 +2415,66 @@ tables_no_i_s(SQLHSTMT hstmt,
24152415
STMT *stmt= (STMT *)hstmt;
24162416
my_bool all_dbs= 1, user_tables, views;
24172417

2418-
/* empty (but non-NULL) schema and table returns catalog list */
2419-
if (catalog_len && !schema_len && schema && !table_len && table)
2418+
MYSQL_RES *catalog_res= NULL;
2419+
my_ulonglong row_count= 0;
2420+
MYSQL_ROW catalog_row;
2421+
unsigned long *lengths;
2422+
unsigned long count= 0;
2423+
my_bool is_info_schema= 0;
2424+
2425+
/*
2426+
empty (but non-NULL) schema and table returns catalog list
2427+
If no_i_s then call 'show database' to list all catalogs (database).
2428+
*/
2429+
if (catalog_len && ((!schema_len && schema && !table_len && table)
2430+
|| (catalog && (!server_has_i_s(stmt->dbc) ||
2431+
stmt->dbc->ds->no_information_schema))))
24202432
{
2421-
myodbc_mutex_lock(&stmt->dbc->lock);
2422-
{
2423-
char buff[32 + NAME_LEN], *to;
2424-
to= my_stpmov(buff, "SHOW DATABASES LIKE '");
2425-
to+= mysql_real_escape_string(&stmt->dbc->mysql, to,
2426-
(char *)catalog, catalog_len);
2427-
to= my_stpmov(to, "'");
2428-
MYLOG_QUERY(stmt, buff);
2429-
if (!exec_stmt_query(stmt, buff, strlen(buff), FALSE))
2430-
stmt->result= mysql_store_result(&stmt->dbc->mysql);
2431-
}
2432-
myodbc_mutex_unlock(&stmt->dbc->lock);
2433+
myodbc_mutex_lock(&stmt->dbc->lock);
2434+
{
2435+
char buff[32 + NAME_LEN], *to;
2436+
to= my_stpmov(buff, "SHOW DATABASES LIKE '");
2437+
to+= mysql_real_escape_string(&stmt->dbc->mysql, to,
2438+
(char *)catalog, catalog_len);
2439+
to= my_stpmov(to, "'");
2440+
MYLOG_QUERY(stmt, buff);
2441+
if (!mysql_query(&stmt->dbc->mysql, buff))
2442+
catalog_res= mysql_store_result(&stmt->dbc->mysql);
2443+
}
2444+
myodbc_mutex_unlock(&stmt->dbc->lock);
24332445

2434-
if (!stmt->result)
2435-
{
2436-
return handle_connection_error(stmt);
2437-
}
2446+
if (!catalog_res)
2447+
{
2448+
return handle_connection_error(stmt);
2449+
}
24382450

2439-
stmt->order = SQLTABLES_qualifier_order;
2440-
stmt->order_count = array_elements(SQLTABLES_qualifier_order);
2441-
stmt->fix_fields = fix_fields_copy;
2442-
stmt->array= (MYSQL_ROW) myodbc_memdup((char *)SQLTABLES_qualifier_values,
2443-
sizeof(SQLTABLES_qualifier_values),
2444-
MYF(0));
2445-
if (!stmt->array)
2446-
{
2447-
set_mem_error(&stmt->dbc->mysql);
2448-
return handle_connection_error(stmt);
2449-
}
2450-
myodbc_link_fields(stmt,SQLTABLES_fields,SQLTABLES_FIELDS);
2451-
return SQL_SUCCESS;
2451+
}
2452+
else
2453+
{
2454+
/*
2455+
Set is_info_schema for determining mysql_table_status
2456+
parameters later
2457+
*/
2458+
is_info_schema= 1;
2459+
}
2460+
2461+
/* empty (but non-NULL) schema and table returns catalog list */
2462+
if (catalog_len && !schema_len && schema && !table_len && table)
2463+
{
2464+
stmt->order = SQLTABLES_qualifier_order;
2465+
stmt->order_count = array_elements(SQLTABLES_qualifier_order);
2466+
stmt->fix_fields = fix_fields_copy;
2467+
stmt->array= (MYSQL_ROW) myodbc_memdup((char *)SQLTABLES_qualifier_values,
2468+
sizeof(SQLTABLES_qualifier_values),
2469+
MYF(0));
2470+
stmt->result= catalog_res;
2471+
if (!stmt->array)
2472+
{
2473+
set_mem_error(&stmt->dbc->mysql);
2474+
return handle_connection_error(stmt);
2475+
}
2476+
myodbc_link_fields(stmt, SQLTABLES_fields, SQLTABLES_FIELDS);
2477+
return SQL_SUCCESS;
24522478
}
24532479

24542480
if (!catalog_len && catalog && schema_len && !table_len && table)
@@ -2497,111 +2523,165 @@ tables_no_i_s(SQLHSTMT hstmt,
24972523
/* User Tables with type as 'TABLE' or 'VIEW' */
24982524
if (user_tables || views)
24992525
{
2500-
myodbc_mutex_lock(&stmt->dbc->lock);
2501-
stmt->result= table_status(stmt, catalog, catalog_len,
2502-
table, table_len, TRUE,
2503-
user_tables, views);
2504-
2505-
if (!stmt->result && mysql_errno(&stmt->dbc->mysql))
2526+
/*
2527+
If database result set (catalog_res) was produced loop
2528+
through all database to fetch table list inside database
2529+
*/
2530+
while (catalog_res && (catalog_row= mysql_fetch_row(catalog_res))
2531+
|| is_info_schema)
25062532
{
2507-
SQLRETURN rc;
2508-
/* unknown DB will return empty set from SQLTables */
2509-
switch (mysql_errno(&stmt->dbc->mysql))
2533+
myodbc_mutex_lock(&stmt->dbc->lock);
2534+
2535+
if (is_info_schema)
25102536
{
2511-
case ER_BAD_DB_ERROR:
2512-
myodbc_mutex_unlock(&stmt->dbc->lock);
2513-
goto empty_set;
2514-
default:
2515-
rc= handle_connection_error(stmt);
2516-
myodbc_mutex_unlock(&stmt->dbc->lock);
2517-
return rc;
2537+
/*
2538+
If i_s then all databases are fetched in single loop
2539+
for SQL_ALL_CATALOGS (%) and catalog selection is handled
2540+
inside mysql_table_status_i_s
2541+
*/
2542+
stmt->result= table_status(stmt, catalog, catalog_len,
2543+
table, table_len, TRUE,
2544+
user_tables, views);
25182545
}
2519-
}
2520-
myodbc_mutex_unlock(&stmt->dbc->lock);
2521-
}
2546+
else
2547+
{
2548+
/*
2549+
If no i_s then all databases, except information_schema as
2550+
it contains SYSTEM VIEW table types, are fetched are sent to
2551+
mysql_table_status_show to get result for SQL_ALL_CATALOGS
2552+
(%) and catalog selection is handled in this function
2553+
*/
2554+
if(myodbc_strcasecmp(catalog_row[0], "information_schema") == 0)
2555+
{
2556+
myodbc_mutex_unlock(&stmt->dbc->lock);
2557+
continue;
2558+
}
25222559

2523-
if (!stmt->result)
2524-
goto empty_set;
2560+
lengths= mysql_fetch_lengths(catalog_res);
2561+
stmt->result= table_status(stmt, catalog_row[0], lengths[0],
2562+
table, table_len, TRUE,
2563+
user_tables, views);
2564+
}
25252565

2526-
/* assemble final result set */
2527-
{
2528-
MYSQL_ROW data= 0, row;
2529-
char *db= "";
2530-
my_ulonglong row_count= stmt->result->row_count;
2566+
if (!stmt->result && mysql_errno(&stmt->dbc->mysql))
2567+
{
2568+
SQLRETURN rc;
2569+
/* unknown DB will return empty set from SQLTables */
2570+
switch (mysql_errno(&stmt->dbc->mysql))
2571+
{
2572+
case ER_BAD_DB_ERROR:
2573+
myodbc_mutex_unlock(&stmt->dbc->lock);
2574+
goto empty_set;
2575+
default:
2576+
rc= handle_connection_error(stmt);
2577+
myodbc_mutex_unlock(&stmt->dbc->lock);
2578+
return rc;
2579+
}
2580+
}
2581+
myodbc_mutex_unlock(&stmt->dbc->lock);
25312582

2532-
if (!row_count)
2533-
{
2534-
mysql_free_result(stmt->result);
2535-
stmt->result= NULL;
2536-
goto empty_set;
2537-
}
2583+
if (!stmt->result)
2584+
goto empty_set; ///////////////////////
25382585

2539-
if (!(stmt->result_array=
2540-
(char **)myodbc_malloc((uint)(sizeof(char *) * SQLTABLES_FIELDS *
2541-
row_count),
2542-
MYF(MY_ZEROFILL))))
2543-
{
2544-
set_mem_error(&stmt->dbc->mysql);
2545-
return handle_connection_error(stmt);
2546-
}
2586+
/* assemble final result set */
2587+
{
2588+
MYSQL_ROW data= 0, row;
2589+
char *db= "";
2590+
row_count += stmt->result->row_count;
25472591

2548-
data= stmt->result_array;
2592+
if (!row_count)
2593+
{
2594+
mysql_free_result(stmt->result);
2595+
is_info_schema= 0;
2596+
continue;
2597+
}
25492598

2550-
if (!stmt->dbc->ds->no_catalog)
2551-
{
2552-
if (!catalog)
2553-
{
2554-
if (!reget_current_catalog(stmt->dbc))
2599+
if (!(stmt->result_array=
2600+
(char **)myodbc_realloc((char *)stmt->result_array,
2601+
sizeof(char *) *
2602+
SQLTABLES_FIELDS * row_count,
2603+
MYF(MY_ZEROFILL))))
25552604
{
2556-
const char *dbname= stmt->dbc->database ? stmt->dbc->database
2557-
: "null";
2558-
db= strmake_root(&stmt->result->field_alloc,
2559-
dbname, strlen(dbname));
2605+
set_mem_error(&stmt->dbc->mysql);
2606+
return handle_connection_error(stmt);
25602607
}
2561-
else
2608+
2609+
data= stmt->result_array;
2610+
2611+
if (!stmt->dbc->ds->no_catalog)
25622612
{
2563-
/* error was set in reget_current_catalog */
2564-
return SQL_ERROR;
2613+
/* Set db to fetched database row from show database result set */
2614+
if (!is_info_schema && lengths[0])
2615+
{
2616+
db= strmake_root(&stmt->result->field_alloc,
2617+
catalog_row[0], lengths[0]);
2618+
}
2619+
else if (!catalog)
2620+
{
2621+
if (!reget_current_catalog(stmt->dbc))
2622+
{
2623+
const char *dbname= stmt->dbc->database ? stmt->dbc->database
2624+
: "null";
2625+
db= strmake_root(&stmt->result->field_alloc,
2626+
dbname, strlen(dbname));
2627+
}
2628+
else
2629+
{
2630+
/* error was set in reget_current_catalog */
2631+
return SQL_ERROR;
2632+
}
2633+
}
2634+
else
2635+
db= strmake_root(&stmt->result->field_alloc,
2636+
(char *)catalog, catalog_len);
25652637
}
2566-
}
2567-
else
2568-
db= strmake_root(&stmt->result->field_alloc,
2569-
(char *)catalog, catalog_len);
2570-
}
25712638

2572-
while ((row= mysql_fetch_row(stmt->result)))
2573-
{
2574-
int cat_index= 3;
2575-
int type_index= 2;
2576-
int comment_index= 1;
2577-
my_bool view;
2578-
2579-
/* If if did not use I_S */
2580-
if (stmt->dbc->ds->no_information_schema
2581-
|| !server_has_i_s(stmt->dbc))
2582-
{
2583-
type_index= comment_index= (stmt->result->field_count == 18) ? 17 : 15;
2584-
/* We do not have catalog in result */
2585-
cat_index= -1;
2586-
}
2639+
while ((row= mysql_fetch_row(stmt->result)))
2640+
{
2641+
int cat_index= 3;
2642+
int type_index= 2;
2643+
int comment_index= 1;
2644+
my_bool view;
2645+
2646+
/* If if did not use I_S */
2647+
if (stmt->dbc->ds->no_information_schema
2648+
|| !server_has_i_s(stmt->dbc))
2649+
{
2650+
type_index= comment_index= (stmt->result->field_count == 18) ? 17 : 15;
2651+
/* We do not have catalog in result */
2652+
cat_index= -1;
2653+
}
25872654

2588-
view= (myodbc_casecmp(row[type_index], "VIEW", 4) == 0);
2655+
view= (myodbc_casecmp(row[type_index], "VIEW", 4) == 0);
25892656

2590-
if ((view && !views) || (!view && !user_tables))
2591-
{
2592-
--row_count;
2593-
continue;
2657+
if ((view && !views) || (!view && !user_tables))
2658+
{
2659+
--row_count;
2660+
continue;
2661+
}
2662+
2663+
data[0+count]= (cat_index >= 0 ?
2664+
strdup_root(&stmt->result->field_alloc, row[cat_index]) :
2665+
db);
2666+
data[1+count]= "";
2667+
data[2+count]= strdup_root(&stmt->result->field_alloc, row[0]);
2668+
data[3+count]= view ? "VIEW" : "TABLE";
2669+
data[4+count]= strdup_root(&stmt->result->field_alloc, row[comment_index]);
2670+
count+= SQLTABLES_FIELDS;
2671+
}
25942672
}
2673+
/*
2674+
If i_s then loop only once to fetch database name,
2675+
as mysql_table_status_i_s handles SQL_ALL_CATALOGS (%)
2676+
functionality and all databases with tables are returned
2677+
in one result set and so no further loops are required.
2678+
*/
2679+
is_info_schema= 0;
2680+
}
25952681

2596-
/*TODO solve no_i_s case for SQL_ALL_CATALOGS */
2597-
data[0]= (cat_index >= 0 ?
2598-
strdup_root(&stmt->result->field_alloc, row[cat_index]) :
2599-
db);
2600-
data[1]= "";
2601-
data[2]= strdup_root(&stmt->result->field_alloc, row[0]);
2602-
data[3]= view ? "VIEW" : "TABLE";
2603-
data[4]= strdup_root(&stmt->result->field_alloc, row[comment_index]);
2604-
data+= SQLTABLES_FIELDS;
2682+
if (!row_count)
2683+
{
2684+
goto empty_set;
26052685
}
26062686

26072687
set_row_count(stmt, row_count);

0 commit comments

Comments
 (0)