On Feb 15, 2010, at 2:42 PM, Tim Bunce wrote:

> I've not really looked the the DBD::Pg code much so this seemed like a
> good excuse... It looks like the default is to call PQprepare() with
> paramTypes Oid values of 0.

Yes, IIRC, 0 == unknown as far as the server is concerned. It just tells the 
server to resolve it when it can.

> http://developer.postgresql.org/pgdocs/postgres/libpq-exec.html says
> "If paramTypes is NULL, or any particular element in the array is zero,
> the server assigns a data type to the parameter symbol in the same way
> it would do for an untyped literal string."

Right, exactly.

> But I don't know if that means it has the same semantics as using
> 'unknown' as a type to PL/Perl's spi_prepare(). The docs for
> spi_prepare() don't mention if type parameters are optional or what
> happens if they're omitted.
> http://developer.postgresql.org/pgdocs/postgres/plperl-builtins.html#PLPERL-DATABASE

Same as in SQL PREPARE, I'm sure. Ultimately that's what's doing the work, IIUC.

> Looking at the code I see spi_prepare() maps the provided arg type names
> to oids then calls SPI_prepare().  The docs for SPI_prepare() also don't
> mention if the type parameters are optional or what happens if they're 
> omitted.
> The docs for the int nargs parameter say "number of input *parameters*"
> not "number of parameters that Oid *argtypes describes"
> http://developer.postgresql.org/pgdocs/postgres/spi-spi-prepare.html
> 
> Guess I need to go and check the current behaviour... see below.

And like maybe a doc patch might be useful.

> I'm currently using:
> 
>    my $placeholders = join ",", map { '$'.$_ } 1..$arity;
>    my $plan = spi_prepare("select * from $spname($placeholders)", 
> @$arg_types) };

Ah, yeah, that's better, but I do think you should use quote_ident() on the 
function name.

> and it turns out that spi_prepare is happy to prepare a statement with
> more placeholders than there are types provided.

Types or args?

> I'm a little nervous of relying on that undocumented behaviour.
> Hopefully someone can clarify if that's expected behaviour.

It's what I would expect, but I'm not an authority on this stuff.

> So, anyway, I've now extended the code so the parenthesis and types
> aren't needed. Thanks for prompting the investigation :)

Yay!

>> I don't think it's necessary. I mean, if you're passed an array, you
>> should of course pass it to PostgreSQL, but it can be anyarray.
> 
> Sure, you can pass an array in encoded string form, no problem.
> But specifying in the signature a type that includes [] enables
> you to use a perl array _reference_ and let call() look after
> encoding it for you.
> 
> I did it that way round, rather than checking all the args for refs on
> every call, as it felt safer, more efficient, and more extensible.

IIRC (again, sorry), that's what DBD::Pg does: It checks all the args and turns 
an array into an SQL array, without regard to specified types.

>> No, but the latter is more Perlish.
> 
> True. You can't specify a schema though, and the 'SP' is somewhat
> artificial. Still, I'm coming round to the idea :)

What about `SP->schema::function_name()`? Agreed that SP is artificial, but 
there needs to be some kind of handle for AUTOLOAD to wrap itself around. Maybe 
a singleton object instead? (I was kind of thinking of SP as that, anyway:

    use constant SP => 'PostgreSQL::PLPerl';

)

>> Yeah yeah. I could even put one on CPAN. ;-P
> 
> I think it only needs this (untested):
> 
>    package SP;
>    sub AUTOLOAD { our $AUTOLOAD =~ s/^SP:://; shift; call($AUTOLOAD, @_); }

Yep. Might be nice sugar to just throw in your module anyway.

> I could either add an extra module (PostgreSQL::PLPerl::Call::SP)
> or add a fancy import hook like:
> 
>    use PostgreSQL::PLPerl::Call qw(:AUTOLOAD => 'SP');

The latter is nice, as then the DBA can specify the name of package/global 
object.

Best,

David


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to