@@ -2415,40 +2415,66 @@ tables_no_i_s(SQLHSTMT hstmt,
2415
2415
STMT * stmt = (STMT * )hstmt ;
2416
2416
my_bool all_dbs = 1 , user_tables , views ;
2417
2417
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 ))))
2420
2432
{
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 );
2433
2445
2434
- if (!stmt -> result )
2435
- {
2436
- return handle_connection_error (stmt );
2437
- }
2446
+ if (!catalog_res )
2447
+ {
2448
+ return handle_connection_error (stmt );
2449
+ }
2438
2450
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 ;
2452
2478
}
2453
2479
2454
2480
if (!catalog_len && catalog && schema_len && !table_len && table )
@@ -2497,111 +2523,165 @@ tables_no_i_s(SQLHSTMT hstmt,
2497
2523
/* User Tables with type as 'TABLE' or 'VIEW' */
2498
2524
if (user_tables || views )
2499
2525
{
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 )
2506
2532
{
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 )
2510
2536
{
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 );
2518
2545
}
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
+ }
2522
2559
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
+ }
2525
2565
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 );
2531
2582
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 ; ///////////////////////
2538
2585
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 ;
2547
2591
2548
- data = stmt -> result_array ;
2592
+ if (!row_count )
2593
+ {
2594
+ mysql_free_result (stmt -> result );
2595
+ is_info_schema = 0 ;
2596
+ continue ;
2597
+ }
2549
2598
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 )) ))
2555
2604
{
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 );
2560
2607
}
2561
- else
2608
+
2609
+ data = stmt -> result_array ;
2610
+
2611
+ if (!stmt -> dbc -> ds -> no_catalog )
2562
2612
{
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 );
2565
2637
}
2566
- }
2567
- else
2568
- db = strmake_root (& stmt -> result -> field_alloc ,
2569
- (char * )catalog , catalog_len );
2570
- }
2571
2638
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
+ }
2587
2654
2588
- view = (myodbc_casecmp (row [type_index ], "VIEW" , 4 ) == 0 );
2655
+ view = (myodbc_casecmp (row [type_index ], "VIEW" , 4 ) == 0 );
2589
2656
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
+ }
2594
2672
}
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
+ }
2595
2681
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 ;
2605
2685
}
2606
2686
2607
2687
set_row_count (stmt , row_count );
0 commit comments