Hi,

Firstly, I've just come back from holidays, I'm distracted by other things right now and might not be back in the swing of things properly - so beware.

table_info maps to the ODBC API SQLTables in DBD::ODBC. DBI seems to have picked some functionality for table_info from ODBC in that if '%' is passed for one of catalog, schema and table and the other 2 are empty strings the result only contains a list of catalogs, schemas or tables.

Someone just reported to me that in DBD::ODBC if you call table_info('%','','') you get all catalogs, schemas and tables back but you should get only a list of catalogs. I tracked this down to the following code in DBD::ODBC (ANSI case here, unicode one is slightly more complex):

    if (SvOK(catalog)) acatalog = SvPV_nolen(catalog);
    if (SvOK(schema)) aschema = SvPV_nolen(schema);
    if (SvOK(table)) atable = SvPV_nolen(table);
    if (SvOK(table_type)) atype = SvPV_nolen(table_type);

       rc = SQLTables(imp_sth->hstmt,
                      (acatalog && *acatalog) ? acatalog : NULL,SQL_NTS,
                      (aschema && *aschema) ? aschema : NULL, SQL_NTS,
                      (atable && atable) ? atable : NULL, SQL_NTS,
                      (atype && *atype) ? atype : NULL,
                      SQL_NTS           /* type (view, table, etc) */
                      );

What is happening here is that whatever is passed to table_info, if it is defined and NOT the empty string we pass the string else NULL and for SQLTables NULL is very different from the empty string (see special cases above). However, if you call:

$dbh->table_info('%', '', '') to just get catalogs what is passed to SQLTables is '%', NULL, NULL and this causes all tables to be returned instead of only catalogs.

The fix seems obvious, remove the test for *acatalog etc which I did and it fixes the problem \o/

except, DBD::ODBC test code calls table_info() (and for all I know other people do too) and that ends up in DBI calling table_info with 4 empty strings. Empty strings are not the same as undef/NULL and it results in SQLTables returning no tables at all when before it would return all tables.

As far as I can see, at some point in the past, someone (maybe me) realised this and changed DBD::ODBC to workaround this issue instead of questioning what DBI passes.

Now, table_info() with no arguments is not mentioned in the DBI pod so you could say that is undefined behaviour but it is a little late for that now as DBD::ODBC uses it in test code and as far as I know, so do others. However, to fix the initial bug I cannot know when empty strings are supposed to be undef/NULL and when they are supposed to be empty strings. So I can fix the bug as shown but only if I change DBD::ODBC test code from table_info() to table_info('%', '%', '%', '%') and I cannot change anyone elses code.

Any suggestions?

Martin
--
Martin J. Evans
Wetherby, UK

Reply via email to