Subject: | Error "Can't use string as an ARRAY ref" when wrong delimited format type specified |
This problem spans AnyData and DBD::AnyData but reporting it here.
If one specifies the wrong format type to 'ad_catalog' then later we will get confusing errors, or worse. In this case a tab-delimited file was used with the 'CSV' type.
One problem is the Perl error message "Can't use string as an ARRAY ref". If DBD:Storage::File routine get_col_names() is unable to discern column names from the first record of a file, it returns a string error message "CAN'T FIND COLUMN NAMES ON FIRST LINE " (concatenated with filename and text of first line). Note that the other expected return values are undef or an arrayref of column names array.
AnyData.pm routine prep_dbd_table may call get_col_names(). The return value is checked as part of a error test of whether the column names could be retrieved. The test conditions do not check whether the return value could be neither undef nor arrayref.
127c127,130
< if (!$col_names || !scalar @$col_names)
---
Show quoted text
> if ( ! defined $col_names
> || 'ARRAY' ne ref $col_names
> || ! scalar @$col_names
> )
The above patch fixes the Perl error message, but which then gets us into true confusion as to what is *supposed* to happen next, that is, how is the true error supposed to be reported.
There is code in DBD::AnyData routine open_table() that seems to look for an error string as opposed to undef or arrayref values. If a string is found it will print the string and *exit* (!!) the program. Terminating the program without a die has obvious nasty ramifications for error recovery.
What is strange is that the original check back in routine AnyData.pm prep_dbd_table() was trying to die with another error message. If I fiddle with the part of the test that fails there:
129c132
< && !$createMode eq 'o';
---
Show quoted text > && $createMode ne 'o';
I then get to see that error message in a DBI-ish manner when RaiseError is turned on:
"DBD::AnyData::st execute failed:"
"Execution ERROR: ERROR: No Column Names!:r
at C:/Perl/site/lib/AnyData.pm line 126, <GEN0> line 2." ."
"[for Statement "SELECT * FROM scid LIMIT 5"] at dbdanydata1.pl line 52."
Admittedly this isn't as enlightening an error message, but at least it is trappable.
If RaiseError is not turned on then we see a totally misleading message when the fetchrow_array() call fails, which is perhaps what the open_table() hack was trying to avoid?:
"Couldn't fetchrow(): Attempt to fetch row from a
Non-SELECT statement at dbdanydata1.pl line 57."
The first patch is needed. The second patch is questionable and would have to be reconciled against some real understanding of the code. And it would surely be nice to get an informative error message that can be trapped.