Re: Is it ever legal (should be supported) to issue a non select in selectall_arrayref?

"Martin J. Evans" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.sybase.devel
Message-ID <[email protected]>
On 11/06/11 22:49, David Nicol wrote:
> I'm not 100% sure about the assertion about calling fetch on an
> executed non-select statement handle being defined to reliably return
> false, as in no-more-data as part of the standard. If C<fetch*>  isn't
> really defined to behave the same with a non-SELECT as with a SELECT
> that simply doesn't return any rows, like I think it is but not with
> certainty, the following is my submission as a patch to DBI.pm.
>
> --- a/DBI.pm    Sat Jun 11 16:19:30 2011 -0500
> +++ b/DBI.pm    Sat Jun 11 16:38:01 2011 -0500
> @@ -4621,6 +4621,16 @@
>   You can specify a maximum number of rows to fetch by including a
>   'C<MaxRows>' attribute in \%attr.
>
> +=head3 On use of non-C<SELECT>  SQL in C<select*_*>  methods
> +
> +While some drivers support statements other than C<SELECT>  in the above-listed
> +convenience functions, others do not. Requirement of this facility is
> not defined
> +by the DBI interface standard. The C<do>  method is provided for non-C<SELECT>
> +statements. When you really don't know if the statement you have in a variable
> +is going to be a C<SELECT>  or not, unrolling the process into
> C<prepare>,C<execute>,
> +and some C<fetch>  variant will always work, as C<fetch>  is defined to return
> +no data when called on executed non-C<SELECT>  statement handles.
> +
>   =head3 C<prepare>
>
>     $sth = $dbh->prepare($statement)          or die $dbh->errstr;
>
> --
>

I'm not sure DBD::ODBC knows the difference between "fetch" being called on an executed non-select statement and selectall*. The person who originally rt'd this has read this thread and thinks the proposed DBI pod change now infers:

use DBI;
use Data::Dumper;
$dbh = DBI->connect("dbi:ODBC:DSN=DBGEARDEVNYC-es;APP=nortonp_$ARGV[0]", "guestuser", "deshaw",
             {
             HandleError=>sub {print "ODBCError: " . Dumper(\@_) . "\n"},
             });
my $ref = $dbh->prepare("create table #foo (fooint int)");
$ref->execute();
my $results = $ref->fetch();

would put false in $results but DBD::ODBC errors with:

'DBD::ODBC::st fetch failed: no select statement currently executing (SQL-HY000)'

The problem is that in moving from DBD::Sybase to DBD::ODBC his code doing the above worked and now doesn't. It accidentally worked in a previous DBD::ODBC because the above error was masked (due to a bug I introduced). Obviously I could make it work but then anyone calling fetch on a non-select by accident or as the result of a bug in their code would not know. Personally, if I was not sure if some SQL was a select or not I'd examine NUM_OF_FIELDS first before I called fetch. DBD::Sybase differs from DBD::ODBC in the fetch as DBD::Sybase does:

	/* Check that execute() was executed sucessfully. This also implies	*/
	/* that describe() executed sucessfuly so the memory buffers	*/
	/* are allocated and bound.						*/
	if (!DBIc_is(imp_sth, DBIcf_ACTIVE) || !imp_sth->exec_done) {
		return Nullav;
	}

and DBD::ODBC does:

     /* Check that execute() was executed sucessfully. This also implies	*/
     /* that dbd_describe() executed sucessfuly so the memory buffers	*/
     /* are allocated and bound.						*/
     if ( !DBIc_ACTIVE(imp_sth) ) {
         dbd_error(sth, DBDODBC_INTERNAL_ERROR, "no select statement currently executing");
         return Nullav;
     }

So the proposed change saying

"When you really don't know if the statement you have in a variable is going to be a C<SELECT>  or not, unrolling the process into C<prepare>,C<execute>, and some C<fetch>  variant will always work, as C<fetch>  is defined to return no data when called on executed non-C<SELECT>  statement handles."

I don't see how DBD::ODBC is supposed to implement that. fetch is just an alias for fetchrow_arrayref. There is fetch and nothing else. If you call selectall* it ends up in dbd_st_fetch, if you call fetch it ends up in dbd_st_fetch.

So the question becomes which is right DBD::Sybase behaviour or DBD::ODBC.

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.