Re: thorny problem with table_info implementation

2013-09-03 Thread Tim Bunce
On Mon, Sep 02, 2013 at 08:53:18PM +0100, Martin J. Evans wrote:
 On 02/09/2013 20:27, Martin J. Evans wrote:
 
 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.
 
 Correction, in that last paragraph (I did warn you), I should have
 said table_info() to table_info('%', '%', '%') i.e.,
 
 table_info('%', '', '') returns catalogs only
 table_info('', '%', '') returns schemas only
 table_info('', '', '', '%') returns types only
 table_info('%', '%', '%') returns everything
 table_info() did return everything due to workaround in DBD::ODBC
 but fixing bug ends up in table_info() returning nothing.

How about changing your test code to table_info('%', '%', '%', '%')
and treat table_info() a special case that triggers a warning?

Tim.


Re: thorny problem with table_info implementation

2013-09-03 Thread Martin J. Evans

On 03/09/13 09:38, Tim Bunce wrote:

On Mon, Sep 02, 2013 at 08:53:18PM +0100, Martin J. Evans wrote:

On 02/09/2013 20:27, Martin J. Evans wrote:


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.


Correction, in that last paragraph (I did warn you), I should have
said table_info() to table_info('%', '%', '%') i.e.,

table_info('%', '', '') returns catalogs only
table_info('', '%', '') returns schemas only
table_info('', '', '', '%') returns types only
table_info('%', '%', '%') returns everything
table_info() did return everything due to workaround in DBD::ODBC
but fixing bug ends up in table_info() returning nothing.


How about changing your test code to table_info('%', '%', '%', '%')


because that does not work. It would need to be table_info('%','%','%') (or 
table_info(undef, undef, undef, undef) for it to work. In ODBC the table type 
needs to be null or all types to get everything. Obviously changing the test 
code is easy.


and treat table_info() a special case that triggers a warning?


hmm, I warned I might be having a bad day. As soon as I read that I thought how 
do I do that as I'd forgotten there is a table_info method in DBD::ODBC itself. 
It appears all the problems are DBD::ODBC specific as I missed the code that 
set the parameters to q{} if not defined.


Tim.



Thanks and sorry for noise.

Martin


Re: thorny problem with table_info implementation

2013-09-03 Thread Martin J. Evans

On 03/09/2013 11:43, Martin J. Evans wrote:

On 03/09/13 09:38, Tim Bunce wrote:

On Mon, Sep 02, 2013 at 08:53:18PM +0100, Martin J. Evans wrote:

On 02/09/2013 20:27, Martin J. Evans wrote:


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.


Correction, in that last paragraph (I did warn you), I should have
said table_info() to table_info('%', '%', '%') i.e.,

table_info('%', '', '') returns catalogs only
table_info('', '%', '') returns schemas only
table_info('', '', '', '%') returns types only
table_info('%', '%', '%') returns everything
table_info() did return everything due to workaround in DBD::ODBC
but fixing bug ends up in table_info() returning nothing.


How about changing your test code to table_info('%', '%', '%', '%')


because that does not work. It would need to be table_info('%','%','%')
(or table_info(undef, undef, undef, undef) for it to work. In ODBC the
table type needs to be null or all types to get everything. Obviously
changing the test code is easy.


and treat table_info() a special case that triggers a warning?


hmm, I warned I might be having a bad day. As soon as I read that I
thought how do I do that as I'd forgotten there is a table_info method
in DBD::ODBC itself. It appears all the problems are DBD::ODBC specific
as I missed the code that set the parameters to q{} if not defined.


Tim.



Thanks and sorry for noise.

Martin



Pushed changes to github and will try and find time to release updates 
tomorrow. This started from 
http://stackoverflow.com/questions/18450002/retrieving-available-table-types-schemas-and-catalogs-using-dbiodbc-table-i. 
This actually found a bug in the easysoft sql server odbc driver re: 
calling SQLTables with % as the table_type - ask easysoft support for an 
updated driver if you need this fix. If no complaints I will release a 
new DBD::ODBC with new test cases in the next week.


Martin
--
Martin J. Evans
Wetherby, UK


Re: thorny problem with table_info implementation

2013-09-02 Thread Martin J. Evans

On 02/09/2013 20:27, Martin J. Evans wrote:

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


Correction, in that last paragraph (I did warn you), I should have said 
table_info() to table_info('%', '%', '%') i.e.,


table_info('%', '', '') returns catalogs only
table_info('', '%', '') returns schemas only
table_info('', '', '', '%') returns types only
table_info('%', '%', '%') returns everything
table_info() did return everything due to workaround in DBD::ODBC but 
fixing bug ends up in table_info() returning nothing.


Martin
--
Martin J. Evans
Wetherby, UK