BUG #3002: PQexecParams only supports some commands; needs improved error reporting, documenting or fixing

Started by Phil Endecottabout 19 years ago4 messagesbugs
Jump to latest
#1Phil Endecott
spam_from_postgresql_bugs@chezphil.org

The following bug has been logged online:

Bug reference: 3002
Logged by: Phil Endecott
Email address: spam_from_postgresql_bugs@chezphil.org
PostgreSQL version: 8.1.0
Operating system: All?
Description: PQexecParams only supports some commands; needs improved
error reporting, documenting or fixing
Details:

I understand that PQexecParams may only be used for SELECT, INSERT, DELETE
and UPDATE commands, but not for other commands where parameter substitution
might be useful such as CREATE VIEW and CREATE TABLE AS SELECT. When I used
PQexecParams with CREATE VIEW with one $ parameter I got no error
immediately, but got a "no value found for parameter 1" error when I later
ran a query that used the view.

Three fixes occur to me:

1. An error could be reported immediately if an unsupported command is
passed to PQexecParams.

2. The documentation of PQexecParams could be fixed to list the four
commands to which it can be applied.

3. PQexecParams could be extended to support these commands. I have written
a simple wrapper for PQexecParams that expands and escapes parameters and
calls PQexec, for a small set of parameter types. (Please ask me if you'd
like to see the code; it is only 30 lines of obviousness.) Presumably this
would be even simpler if done in the backend.

Thanks, Phil.

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Phil Endecott (#1)
Re: BUG #3002: PQexecParams only supports some commands; needs improved error reporting, documenting or fixing

"Phil Endecott" <spam_from_postgresql_bugs@chezphil.org> writes:

I understand that PQexecParams may only be used for SELECT, INSERT, DELETE
and UPDATE commands, but not for other commands where parameter substitution
might be useful such as CREATE VIEW and CREATE TABLE AS SELECT. When I used
PQexecParams with CREATE VIEW with one $ parameter I got no error
immediately, but got a "no value found for parameter 1" error when I later
ran a query that used the view.

As near as I can tell, your issue is that you haven't thought carefully
about what "$1" in a CREATE VIEW *means*. Is it supposed to represent a
constant value bound into the view when it's created? Is it supposed to
represent a value supplied whenever the view is used (if so, how do you
disambiguate when the query calling the view uses $1 for its own
purposes?). Or something else?

Given defensible arguments for a particular answer to these definitional
questions, we might think about implementing something, but right now my
instinct is to not go there. I'm not seeing a use-case that would
justify work on this.

regards, tom lane

#3Phil Endecott
spam_from_postgresql_bugs@chezphil.org
In reply to: Tom Lane (#2)
Re: BUG #3002: PQexecParams only supports some commands; needs improved error reporting, documenting or fixing

Hi Tom,

Tom Lane wrote:

"Phil Endecott" <spam_from_postgresql_bugs@chezphil.org> writes:

I understand that PQexecParams may only be used for SELECT, INSERT, DELETE
and UPDATE commands, but not for other commands where parameter substitution
might be useful such as CREATE VIEW and CREATE TABLE AS SELECT. When I used
PQexecParams with CREATE VIEW with one $ parameter I got no error
immediately, but got a "no value found for parameter 1" error when I later
ran a query that used the view.

As near as I can tell, your issue is that you haven't thought carefully
about what "$1" in a CREATE VIEW *means*. Is it supposed to represent a
constant value bound into the view when it's created?

Yes.

I'm just relying on the documentation of PQexecParams, which says
things like: "the primary advantage of PQexecParams over PQexec is that
parameter values may be separated from the command string, thus
avoiding the need for tedious and error-prone quoting and escaping."
This is the benefit that I was hoping to get. I simply expected
PQexecParams to substitute the parameter values at the positions in the
command string where the $ placeholders were, or to behave as if that
is what it had done.

I'm not seeing a use-case that would justify work on this.

In my IMAP mail server, I run a series of "create temporary view"
commands when the IMAP LOGIN command is processed. These views filter
the message database down to just that user's messages, so that
subsequent queries are simplified:

1 LOGIN phil password
----> create temporary view u_messages as select * from messages where owner='phil'

2 SELECT Today
----> select msg_id from u_messages where age(msgdate)<'1 day'::interval

I have a C++ wrapper around libpq. This allows me to write things like:

typedef std::string username_t;
Query<username_t> create_u_messages
("create temporary view u_messages as select * from messages where owner=$1");
...
create_u_messages("phil");

As currently implemented, this uses PQexecParams. I will have to
change it to do parameter substitution itself and then call PQexec,
either unconditionally or after parsing enough of the command to
recognise whether it is supported by PQexecParams.

Regards,

Phil.

#4Phil Endecott
spam_from_psql_bugs@chezphil.org
In reply to: Phil Endecott (#3)
Fwd: Re: BUG #3002: PQexecParams only supports some commands; needs improved error reporting, documenting or fixing

I'm resending this as the first attempt didn't make it to the list.

Phil.

Phil Endecott wrote:

Show quoted text

Hi Tom,

Tom Lane wrote:

"Phil Endecott" <spam_from_postgresql_bugs@chezphil.org> writes:

I understand that PQexecParams may only be used for SELECT, INSERT, DELETE
and UPDATE commands, but not for other commands where parameter substitution
might be useful such as CREATE VIEW and CREATE TABLE AS SELECT. When I used
PQexecParams with CREATE VIEW with one $ parameter I got no error
immediately, but got a "no value found for parameter 1" error when I later
ran a query that used the view.

As near as I can tell, your issue is that you haven't thought carefully
about what "$1" in a CREATE VIEW *means*. Is it supposed to represent a
constant value bound into the view when it's created?

Yes.

I'm just relying on the documentation of PQexecParams, which says
things like: "the primary advantage of PQexecParams over PQexec is that
parameter values may be separated from the command string, thus
avoiding the need for tedious and error-prone quoting and escaping."
This is the benefit that I was hoping to get. I simply expected
PQexecParams to substitute the parameter values at the positions in the
command string where the $ placeholders were, or to behave as if that
is what it had done.

I'm not seeing a use-case that would justify work on this.

In my IMAP mail server, I run a series of "create temporary view"
commands when the IMAP LOGIN command is processed. These views filter
the message database down to just that user's messages, so that
subsequent queries are simplified:

1 LOGIN phil password
----> create temporary view u_messages as select * from messages where owner='phil'

2 SELECT Today
----> select msg_id from u_messages where age(msgdate)<'1 day'::interval

I have a C++ wrapper around libpq. This allows me to write things like:

typedef std::string username_t;
Query<username_t> create_u_messages
("create temporary view u_messages as select * from messages where owner=$1");
....
create_u_messages("phil");

As currently implemented, this uses PQexecParams. I will have to
change it to do parameter substitution itself and then call PQexec,
either unconditionally or after parsing enough of the command to
recognise whether it is supported by PQexecParams.

Regards,

Phil.