Re: Nearing final release?

Lists: pgsql-hackerspgsql-patches
From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: PostgreSQL-development <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Nearing final release?
Date: 2004-10-16 03:38:35
Message-ID: 200410160338.i9G3cZH28948@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches


I think we are getting closer to a final release. I haven't seen many
_major_ failures in a few weeks, and the open items list is shrinking. I
would like us to make a concentrated effort to address or fix all the
open items by November 1 and consider a final 8.0 release during November.

---------------------------------------------------------------------------

PostgreSQL 8.0 Open Items
=========================

Current version at http://candle.pha.pa.us/cgi-bin/pgopenitems.

Changes
-------
* Win32
o fix query cancel in psql (?)
o fix shared memory on Win2k terminal server
o fix MSVC build to export SSL symbols
o SIG_DFL handling
o Handle "lost signals" on backend startup (eg. shutdown,
config file changes, etc)
* Tablespace
o fix ambiguity for objects using default tablespaces
o fix case where template db already uses target tablespace
o fix error message when creating objects in schema that has a
dropped tablespace as its default
o remove non-portable TABLESPACE clause from CREATE TABLE using
a SET or ALTER command
* allow libpq to check parameterized data types
* adjust bgwriter defaults, allow disabling
* synchonize supported encodings and docs

Completed Since Previoius Beta
------------------------------
* cleanup FRONTEND use in /port, malloc, elog
* update encoding list to include win1250
* make pgxs install by default
* Win32
o disable readline-required psql options
o fix SSL compiles
o add binary version stamps
o fix signal-safe socket handler for SSL
o start pg_autovacuum easily
o remove log timezone string from log_line_prefix '%t'
o fix MinGW libpq to export only required symbols

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Tatsuo Ishii <t-ishii(at)sra(dot)co(dot)jp>
To: pgman(at)candle(dot)pha(dot)pa(dot)us
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Nearing final release?
Date: 2004-10-16 05:30:44
Message-ID: 20041016.143044.41631374.t-ishii@sra.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

We see that the win32 version of PostgreSQL sometime does not respond
to pgbench -S running on Linux. Try something like:

pgbench -h windows_host -S -c 128 -t 1000 your_database

on Linux/FreeBSD/UNIX or whatever.
--
Tatsuo Ishii

> I think we are getting closer to a final release. I haven't seen many
> _major_ failures in a few weeks, and the open items list is shrinking. I
> would like us to make a concentrated effort to address or fix all the
> open items by November 1 and consider a final 8.0 release during November.
>
> ---------------------------------------------------------------------------
>
>
> PostgreSQL 8.0 Open Items
> =========================
>
> Current version at http://candle.pha.pa.us/cgi-bin/pgopenitems.
>
> Changes
> -------
> * Win32
> o fix query cancel in psql (?)
> o fix shared memory on Win2k terminal server
> o fix MSVC build to export SSL symbols
> o SIG_DFL handling
> o Handle "lost signals" on backend startup (eg. shutdown,
> config file changes, etc)
> * Tablespace
> o fix ambiguity for objects using default tablespaces
> o fix case where template db already uses target tablespace
> o fix error message when creating objects in schema that has a
> dropped tablespace as its default
> o remove non-portable TABLESPACE clause from CREATE TABLE using
> a SET or ALTER command
> * allow libpq to check parameterized data types
> * adjust bgwriter defaults, allow disabling
> * synchonize supported encodings and docs

> Completed Since Previoius Beta
> ------------------------------
> * cleanup FRONTEND use in /port, malloc, elog
> * update encoding list to include win1250
> * make pgxs install by default
> * Win32
> o disable readline-required psql options
> o fix SSL compiles
> o add binary version stamps
> o fix signal-safe socket handler for SSL
> o start pg_autovacuum easily
> o remove log timezone string from log_line_prefix '%t'
> o fix MinGW libpq to export only required symbols
>
>
>
> --
> Bruce Momjian | http://candle.pha.pa.us
> pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
> + If your life is a hard drive, | 13 Roberts Road
> + Christ can be your backup. | Newtown Square, Pennsylvania 19073
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo(at)postgresql(dot)org so that your
> message can get through to the mailing list cleanly
>


From: Greg Stark <gsstark(at)mit(dot)edu>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Nearing final release?
Date: 2004-10-16 21:42:46
Message-ID: 87r7ny2vc9.fsf@stark.xeocode.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches


Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:

> I think we are getting closer to a final release.
>...
> * synchonize supported encodings and docs

Is this Abhijit's patch to add PQprepare() and PQsendPrepare()?

http://archives.postgresql.org/pgsql-hackers/2004-10/msg00142.php

I'm anxious to see this get in 8.0 so that the prepared query support can be
used by DBD::pg and other libpq-based applications and drivers.

I'm not sure whether the patch he sent is adequate, I looked at it myself and
was a bit skeptical. But he said my concerns were misplaced. If somebody more
authoritative could look at it I expect he would be happy to take any feedback
into account and keep working on it. But if nobody says anything then I'm sure
nothing's going to happen and the binary prepared queries will be useless for
DBD::Pg and other libpq-based drivers.

--
greg


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: pgsql-hackers(at)postgresql(dot)org, Abhijit Menon-Sen <ams(at)oryx(dot)com>
Subject: Re: Nearing final release?
Date: 2004-10-16 22:41:05
Message-ID: 2806.1097966465@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

Greg Stark <gsstark(at)mit(dot)edu> writes:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
>> * synchonize supported encodings and docs

> Is this Abhijit's patch to add PQprepare() and PQsendPrepare()?

No ... does it look like it?

> I'm not sure whether the patch he sent is adequate, I looked at it
> myself and was a bit skeptical. But he said my concerns were
> misplaced.

[ looks... ] The patch is definitely broken as-is, because it changes
the application-visible behavior of existing functions --- in particular
PQsendQueryParams() followed by PQgetResult() will now return a bogus
additional PGresult. I think the cleanest solution is probably to add a
state flag indicating whether ParseComplete should generate a PGresult
or not.

regards, tom lane


From: Greg Stark <gsstark(at)mit(dot)edu>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Greg Stark <gsstark(at)mit(dot)edu>, pgsql-hackers(at)postgresql(dot)org, Abhijit Menon-Sen <ams(at)oryx(dot)com>
Subject: Re: Nearing final release?
Date: 2004-10-17 05:10:14
Message-ID: 87fz4e2amh.fsf@stark.xeocode.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches


Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:

> Greg Stark <gsstark(at)mit(dot)edu> writes:
> > Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > > * synchonize supported encodings and docs
>
> > Is this Abhijit's patch to add PQprepare() and PQsendPrepare()?
>
> No ... does it look like it?

Er, oops. I quoted the wrong line. The line I meant to quote was:

> > > * allow libpq to check parameterized data types

Which is slightly more plausible.

> > I'm not sure whether the patch he sent is adequate, I looked at it
> > myself and was a bit skeptical. But he said my concerns were
> > misplaced.
>
> [ looks... ] The patch is definitely broken as-is, because it changes
> the application-visible behavior of existing functions --- in particular
> PQsendQueryParams() followed by PQgetResult() will now return a bogus
> additional PGresult. I think the cleanest solution is probably to add a
> state flag indicating whether ParseComplete should generate a PGresult
> or not.

[That sounds exactly like what my concerns were.]

Adding a flag is going to be enough for synchronous queries. But it seems like
it has no chance of working for asynchronous queries. It would have to keep
track of what all the pending requests are and the expected results.

I think DBD::Pg would be pretty happy to have even synchronous queries
working. Afaik that's all it uses currently.

--
greg


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: pgsql-hackers(at)postgresql(dot)org, Abhijit Menon-Sen <ams(at)oryx(dot)com>
Subject: Re: Nearing final release?
Date: 2004-10-17 17:19:16
Message-ID: 9103.1098033556@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

Greg Stark <gsstark(at)mit(dot)edu> writes:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:
>> I think the cleanest solution is probably to add a
>> state flag indicating whether ParseComplete should generate a PGresult
>> or not.

> Adding a flag is going to be enough for synchronous queries. But it
> seems like it has no chance of working for asynchronous queries. It
> would have to keep track of what all the pending requests are and the
> expected results.

Say what? Neither libpq nor the backend support multiple queries
in-flight at the same time.

regards, tom lane


From: Abhijit Menon-Sen <ams(at)oryx(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Nearing final release?
Date: 2004-10-18 12:33:01
Message-ID: 20041018123301.GA11686@penne.toroid.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

At 2004-10-16 18:41:05 -0400, tgl(at)sss(dot)pgh(dot)pa(dot)us wrote:
>
> I think the cleanest solution is probably to add a state flag indicating
> whether ParseComplete should generate a PGresult or not.

Like the appended (incremental) patch?

(I didn't think this would work, because I thought libpq would allow you
to send multiple queries before trying to read results. But you said it
didn't support that, so...)

-- ams

--- libpq-int.h.1~ 2004-10-18 17:42:13.175759981 +0530
+++ libpq-int.h 2004-10-18 17:43:40.105986570 +0530
@@ -269,6 +269,8 @@
* nonblock sending semantics */
bool ext_query; /* was our last query sent with extended
* query protocol? */
+ bool sent_prepare; /* was our last Parse message sent with
+ * PQprepare? */
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
int copy_already_done; /* # bytes already returned in
* COPY OUT */

--- fe-exec.c.2~ 2004-10-18 17:47:55.540189274 +0530
+++ fe-exec.c 2004-10-18 17:48:30.119038902 +0530
@@ -686,6 +686,7 @@
goto sendFailed;

conn->ext_query = true;
+ conn->sent_prepare = true;
if (pqFlush(conn) < 0)
goto sendFailed;
conn->asyncStatus = PGASYNC_BUSY;

--- fe-protocol3.c.2~ 2004-10-18 17:44:06.616198123 +0530
+++ fe-protocol3.c 2004-10-18 17:46:34.431656569 +0530
@@ -220,10 +220,13 @@
conn->asyncStatus = PGASYNC_READY;
break;
case '1': /* Parse Complete */
- if (conn->result == NULL)
- conn->result = PQmakeEmptyPGresult(conn,
- PGRES_COMMAND_OK);
- conn->asyncStatus = PGASYNC_READY;
+ if (conn->sent_prepare) {
+ if (!conn->result)
+ conn->result = PQmakeEmptyPGresult(conn,
+ PGRES_COMMAND_OK);
+ conn->asyncStatus = PGASYNC_READY;
+ conn->sent_prepare = false;
+ }
break;
case '2': /* Bind Complete */
case '3': /* Close Complete */

--- libpq-fe.h.2~ 2004-10-18 17:55:40.632064120 +0530
+++ libpq-fe.h 2004-10-18 17:56:26.501634328 +0530
@@ -312,9 +312,9 @@
int resultFormat);

/* Interface for multiple-result or asynchronous queries */
-extern PGresult *PQsendPrepare(PGconn *conn, const char *stmtName,
- const char *query, int nParams,
- const Oid *paramTypes);
+extern int PQsendPrepare(PGconn *conn, const char *stmtName,
+ const char *query, int nParams,
+ const Oid *paramTypes);
extern int PQsendQuery(PGconn *conn, const char *query);
extern int PQsendQueryParams(PGconn *conn,
const char *command,


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Abhijit Menon-Sen <ams(at)oryx(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org, david(at)kineticode(dot)com
Subject: Final libpq patch?
Date: 2004-10-18 18:16:49
Message-ID: 200410181816.i9IIGnq16187@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches


Here is a mega-patch that merges in your four previous patches. Is this
ready to be applied? Making libpq changes during beta is risky so we
had better be careful.

I have also attached your pgtest.c file.

---------------------------------------------------------------------------

Abhijit Menon-Sen wrote:
> At 2004-10-16 18:41:05 -0400, tgl(at)sss(dot)pgh(dot)pa(dot)us wrote:
> >
> > I think the cleanest solution is probably to add a state flag indicating
> > whether ParseComplete should generate a PGresult or not.
>
> Like the appended (incremental) patch?
>
> (I didn't think this would work, because I thought libpq would allow you
> to send multiple queries before trying to read results. But you said it
> didn't support that, so...)
>
> -- ams
>
> --- libpq-int.h.1~ 2004-10-18 17:42:13.175759981 +0530
> +++ libpq-int.h 2004-10-18 17:43:40.105986570 +0530
> @@ -269,6 +269,8 @@
> * nonblock sending semantics */
> bool ext_query; /* was our last query sent with extended
> * query protocol? */
> + bool sent_prepare; /* was our last Parse message sent with
> + * PQprepare? */
> char copy_is_binary; /* 1 = copy binary, 0 = copy text */
> int copy_already_done; /* # bytes already returned in
> * COPY OUT */
>
> --- fe-exec.c.2~ 2004-10-18 17:47:55.540189274 +0530
> +++ fe-exec.c 2004-10-18 17:48:30.119038902 +0530
> @@ -686,6 +686,7 @@
> goto sendFailed;
>
> conn->ext_query = true;
> + conn->sent_prepare = true;
> if (pqFlush(conn) < 0)
> goto sendFailed;
> conn->asyncStatus = PGASYNC_BUSY;
>
> --- fe-protocol3.c.2~ 2004-10-18 17:44:06.616198123 +0530
> +++ fe-protocol3.c 2004-10-18 17:46:34.431656569 +0530
> @@ -220,10 +220,13 @@
> conn->asyncStatus = PGASYNC_READY;
> break;
> case '1': /* Parse Complete */
> - if (conn->result == NULL)
> - conn->result = PQmakeEmptyPGresult(conn,
> - PGRES_COMMAND_OK);
> - conn->asyncStatus = PGASYNC_READY;
> + if (conn->sent_prepare) {
> + if (!conn->result)
> + conn->result = PQmakeEmptyPGresult(conn,
> + PGRES_COMMAND_OK);
> + conn->asyncStatus = PGASYNC_READY;
> + conn->sent_prepare = false;
> + }
> break;
> case '2': /* Bind Complete */
> case '3': /* Close Complete */
>
> --- libpq-fe.h.2~ 2004-10-18 17:55:40.632064120 +0530
> +++ libpq-fe.h 2004-10-18 17:56:26.501634328 +0530
> @@ -312,9 +312,9 @@
> int resultFormat);
>
> /* Interface for multiple-result or asynchronous queries */
> -extern PGresult *PQsendPrepare(PGconn *conn, const char *stmtName,
> - const char *query, int nParams,
> - const Oid *paramTypes);
> +extern int PQsendPrepare(PGconn *conn, const char *stmtName,
> + const char *query, int nParams,
> + const Oid *paramTypes);
> extern int PQsendQuery(PGconn *conn, const char *query);
> extern int PQsendQueryParams(PGconn *conn,
> const char *command,
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/docs/faqs/FAQ.html
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

Attachment Content-Type Size
unknown_filename text/plain 9.0 KB
unknown_filename text/plain 1.7 KB

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: Abhijit Menon-Sen <ams(at)oryx(dot)com>, pgsql-hackers(at)postgresql(dot)org, david(at)kineticode(dot)com
Subject: Re: Final libpq patch?
Date: 2004-10-18 18:34:30
Message-ID: 27591.1098124470@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> Here is a mega-patch that merges in your four previous patches. Is this
> ready to be applied? Making libpq changes during beta is risky so we
> had better be careful.

I was planning to review the updated patch and apply if there was
nothing else major wrong with it. I will use this as the starting
point --- thanks for doing the merging ...

regards, tom lane


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Abhijit Menon-Sen <ams(at)oryx(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Nearing final release?
Date: 2004-10-18 19:40:36
Message-ID: 28883.1098128436@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

Abhijit Menon-Sen <ams(at)oryx(dot)com> writes:
> At 2004-10-16 18:41:05 -0400, tgl(at)sss(dot)pgh(dot)pa(dot)us wrote:
>> I think the cleanest solution is probably to add a state flag indicating
>> whether ParseComplete should generate a PGresult or not.

> Like the appended (incremental) patch?

Not exactly --- the way you've got this set up, a failed PQprepare will
leave a booby trap for the next operation. The flag has got to be reset
on command send, not on receipt of a success response. I'll find a
better place to do it.

regards, tom lane


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Abhijit Menon-Sen <ams(at)oryx(dot)com>
Cc: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, pgsql-patches(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Final libpq patch?
Date: 2004-10-18 22:03:50
Message-ID: 8745.1098137030@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers pgsql-patches

Here's the patch actually applied. I cleaned up the state problem,
fixed a couple minor omissions in the code, and did some work on the
documentation; also updated exports.txt which is now the source for
the *.def files.

regards, tom lane

*** doc/src/sgml/libpq.sgml.orig Fri Oct 1 13:34:17 2004
--- doc/src/sgml/libpq.sgml Mon Oct 18 17:50:04 2004
***************
*** 1055,1062 ****
out-of-memory conditions or serious errors such as inability
to send the command to the server.
If a null pointer is returned, it
! should be treated like a <symbol>PGRES_FATAL_ERROR</symbol> result. Use
! <function>PQerrorMessage</function> to get more information about the error.
</para>
</listitem>
</varlistentry>
--- 1055,1063 ----
out-of-memory conditions or serious errors such as inability
to send the command to the server.
If a null pointer is returned, it
! should be treated like a <symbol>PGRES_FATAL_ERROR</symbol> result.
! Use <function>PQerrorMessage</function> to get more information
! about such errors.
</para>
</listitem>
</varlistentry>
***************
*** 1147,1152 ****
--- 1148,1228 ----
<para>
<variablelist>
<varlistentry>
+ <term><function>PQprepare</function><indexterm><primary>PQprepare</></></term>
+ <listitem>
+ <para>
+ Submits a request to create a prepared statement with the
+ given parameters, and waits for completion.
+ <synopsis>
+ PGresult *PQprepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+ </synopsis>
+ </para>
+
+ <para>
+ <function>PQprepare</> creates a prepared statement for later execution with
+ <function>PQexecPrepared</>.
+ This feature allows commands
+ that will be used repeatedly to be parsed and planned just once, rather
+ than each time they are executed.
+ <function>PQprepare</> is supported only in protocol 3.0 and later
+ connections; it will fail when using protocol 2.0.
+ </para>
+
+ <para>
+ The function creates a prepared statement named <parameter>stmtName</>
+ from the <parameter>query</> string, which must contain a single SQL command.
+ <parameter>stmtName</> may be <literal>""</> to create an unnamed statement,
+ in which case any pre-existing unnamed statement is automatically replaced;
+ otherwise it is an error if the statement name is already defined in the
+ current session.
+ If any parameters are used, they are referred
+ to in the query as <literal>$1</>, <literal>$2</>, etc.
+ <parameter>nParams</> is the number of parameters for which types are
+ pre-specified in the array <parameter>paramTypes[]</>. (The array pointer
+ may be <symbol>NULL</symbol> when <parameter>nParams</> is zero.)
+ <parameter>paramTypes[]</> specifies, by OID, the data types to be assigned to
+ the parameter symbols. If <parameter>paramTypes</> is <symbol>NULL</symbol>,
+ 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. Also, the query may use parameter symbols with numbers higher than
+ <parameter>nParams</>; data types will be inferred for these symbols as
+ well.
+ </para>
+
+ <para>
+ As with <function>PQexec</>, the result is normally a
+ <structname>PGresult</structname> object whose contents indicate server-side
+ success or failure. A null result indicates out-of-memory or inability to
+ send the command at all.
+ Use <function>PQerrorMessage</function> to get more information
+ about such errors.
+ </para>
+
+ <para>
+ At present, there is no way to determine the actual datatype inferred for
+ any parameters whose types are not specified in <parameter>paramTypes[]</>.
+ This is a <application>libpq</> omission that will probably be rectified
+ in a future release.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Prepared statements for use with <function>PQexecPrepared</> can also be
+ created by executing SQL <command>PREPARE</> statements. (But
+ <function>PQprepare</> is more flexible since it does not require
+ parameter types to be pre-specified.) Also, although there is no
+ <application>libpq</> function for deleting a prepared statement,
+ the SQL <command>DEALLOCATE</> statement can be used for that purpose.
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
<term><function>PQexecPrepared</function><indexterm><primary>PQexecPrepared</></></term>
<listitem>
<para>
***************
*** 1166,1172 ****
<para>
<function>PQexecPrepared</> is like <function>PQexecParams</>, but the
command to be executed is specified by naming a previously-prepared
! statement, instead of giving a query string. This feature allows commands
that will be used repeatedly to be parsed and planned just once, rather
than each time they are executed.
<function>PQexecPrepared</> is supported only in protocol 3.0 and later
--- 1242,1249 ----
<para>
<function>PQexecPrepared</> is like <function>PQexecParams</>, but the
command to be executed is specified by naming a previously-prepared
! statement, instead of giving a query string.
! This feature allows commands
that will be used repeatedly to be parsed and planned just once, rather
than each time they are executed.
<function>PQexecPrepared</> is supported only in protocol 3.0 and later
***************
*** 1182,1194 ****
</listitem>
</varlistentry>
</variablelist>
-
- Presently, prepared statements for use with <function>PQexecPrepared</>
- must be set up by executing an SQL <command>PREPARE</> command,
- which is typically sent with <function>PQexec</> (though any of
- <application>libpq</>'s query-submission functions may be used).
- A lower-level interface for preparing statements may be offered in a
- future release.
</para>

<para>
--- 1259,1264 ----
***************
*** 2270,2279 ****
Applications that do not like these limitations can instead use the
underlying functions that <function>PQexec</function> is built from:
<function>PQsendQuery</function> and <function>PQgetResult</function>.
! There are also <function>PQsendQueryParams</function> and
! <function>PQsendQueryPrepared</function>, which can be used with
! <function>PQgetResult</function> to duplicate the functionality of
! <function>PQexecParams</function> and <function>PQexecPrepared</function>
respectively.

<variablelist>
--- 2340,2354 ----
Applications that do not like these limitations can instead use the
underlying functions that <function>PQexec</function> is built from:
<function>PQsendQuery</function> and <function>PQgetResult</function>.
! There are also
! <function>PQsendQueryParams</function>,
! <function>PQsendPrepare</function>, and
! <function>PQsendQueryPrepared</function>,
! which can be used with <function>PQgetResult</function> to duplicate the
! functionality of
! <function>PQexecParams</function>,
! <function>PQprepare</function>, and
! <function>PQexecPrepared</function>
respectively.

<variablelist>
***************
*** 2326,2331 ****
--- 2401,2433 ----
</varlistentry>

<varlistentry>
+ <term><function>PQsendPrepare</><indexterm><primary>PQsendPrepare</></></term>
+ <listitem>
+ <para>
+ Sends a request to create a prepared statement with the given
+ parameters, without waiting for completion.
+ <synopsis>
+ int PQsendPrepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+ </synopsis>
+
+ This is an asynchronous version of <function>PQprepare</>: it
+ returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <function>PQgetResult</function>
+ to determine whether the server successfully created the prepared
+ statement.
+ The function's parameters are handled identically to
+ <function>PQprepare</function>. Like
+ <function>PQprepare</function>, it will not work on 2.0-protocol
+ connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><function>PQsendQueryPrepared</function><indexterm><primary>PQsendQueryPrepared</></></term>
<listitem>
<para>
***************
*** 2358,2364 ****
<para>
Waits for the next result from a prior
<function>PQsendQuery</function>,
! <function>PQsendQueryParams</function>, or
<function>PQsendQueryPrepared</function> call,
and returns it. A null pointer is returned when the command is complete
and there will be no more results.
--- 2460,2467 ----
<para>
Waits for the next result from a prior
<function>PQsendQuery</function>,
! <function>PQsendQueryParams</function>,
! <function>PQsendPrepare</function>, or
<function>PQsendQueryPrepared</function> call,
and returns it. A null pointer is returned when the command is complete
and there will be no more results.
*** src/interfaces/libpq/exports.txt.orig Sat Oct 16 16:03:45 2004
--- src/interfaces/libpq/exports.txt Mon Oct 18 17:36:43 2004
***************
*** 1,3 ****
--- 1,4 ----
+ # $PostgreSQL$
# Functions to be exported by libpq DLLs
PQconnectdb 1
PQsetdbLogin 2
***************
*** 116,118 ****
--- 117,121 ----
pg_char_to_encoding 115
pg_valid_server_encoding 116
pqsignal 117
+ PQprepare 118
+ PQsendPrepare 119
*** src/interfaces/libpq/fe-exec.c.orig Sat Oct 16 18:52:53 2004
--- src/interfaces/libpq/fe-exec.c Mon Oct 18 17:35:24 2004
***************
*** 664,670 ****
}

/* remember we are using simple query protocol */
! conn->ext_query = false;

/*
* Give the data a push. In nonblock mode, don't complain if we're
--- 664,670 ----
}

/* remember we are using simple query protocol */
! conn->queryclass = PGQUERY_SIMPLE;

/*
* Give the data a push. In nonblock mode, don't complain if we're
***************
*** 718,723 ****
--- 718,811 ----
}

/*
+ * PQsendPrepare
+ * Submit a Parse message, but don't wait for it to finish
+ *
+ * Returns: 1 if successfully submitted
+ * 0 if error (conn->errorMessage is set)
+ */
+ int
+ PQsendPrepare(PGconn *conn,
+ const char *stmtName, const char *query,
+ int nParams, const Oid *paramTypes)
+ {
+ if (!PQsendQueryStart(conn))
+ return 0;
+
+ if (!stmtName)
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("statement name is a null pointer\n"));
+ return 0;
+ }
+
+ if (!query)
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("command string is a null pointer\n"));
+ return 0;
+ }
+
+ /* This isn't gonna work on a 2.0 server */
+ if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("function requires at least protocol version 3.0\n"));
+ return 0;
+ }
+
+ /* construct the Parse message */
+ if (pqPutMsgStart('P', false, conn) < 0 ||
+ pqPuts(stmtName, conn) < 0 ||
+ pqPuts(query, conn) < 0)
+ goto sendFailed;
+
+ if (nParams > 0 && paramTypes)
+ {
+ int i;
+
+ if (pqPutInt(nParams, 2, conn) < 0)
+ goto sendFailed;
+ for (i = 0; i < nParams; i++)
+ {
+ if (pqPutInt(paramTypes[i], 4, conn) < 0)
+ goto sendFailed;
+ }
+ }
+ else
+ {
+ if (pqPutInt(0, 2, conn) < 0)
+ goto sendFailed;
+ }
+ if (pqPutMsgEnd(conn) < 0)
+ goto sendFailed;
+
+ /* construct the Sync message */
+ if (pqPutMsgStart('S', false, conn) < 0 ||
+ pqPutMsgEnd(conn) < 0)
+ goto sendFailed;
+
+ /* remember we are doing just a Parse */
+ conn->queryclass = PGQUERY_PREPARE;
+
+ /*
+ * Give the data a push. In nonblock mode, don't complain if we're
+ * unable to send it all; PQgetResult() will do any additional
+ * flushing needed.
+ */
+ if (pqFlush(conn) < 0)
+ goto sendFailed;
+
+ /* OK, it's launched! */
+ conn->asyncStatus = PGASYNC_BUSY;
+ return 1;
+
+ sendFailed:
+ pqHandleSendFailure(conn);
+ return 0;
+ }
+
+ /*
* PQsendQueryPrepared
* Like PQsendQuery, but execute a previously prepared statement,
* using protocol 3.0 so we can pass parameters
***************
*** 921,927 ****
goto sendFailed;

/* remember we are using extended query protocol */
! conn->ext_query = true;

/*
* Give the data a push. In nonblock mode, don't complain if we're
--- 1009,1015 ----
goto sendFailed;

/* remember we are using extended query protocol */
! conn->queryclass = PGQUERY_EXTENDED;

/*
* Give the data a push. In nonblock mode, don't complain if we're
***************
*** 1134,1140 ****
* The user is responsible for freeing the PGresult via PQclear()
* when done with it.
*/
-
PGresult *
PQexec(PGconn *conn, const char *query)
{
--- 1222,1227 ----
***************
*** 1169,1174 ****
--- 1256,1284 ----
}

/*
+ * PQprepare
+ * Creates a prepared statement by issuing a v3.0 parse message.
+ *
+ * If the query was not even sent, return NULL; conn->errorMessage is set to
+ * a relevant message.
+ * If the query was sent, a new PGresult is returned (which could indicate
+ * either success or failure).
+ * The user is responsible for freeing the PGresult via PQclear()
+ * when done with it.
+ */
+ PGresult *
+ PQprepare(PGconn *conn,
+ const char *stmtName, const char *query,
+ int nParams, const Oid *paramTypes)
+ {
+ if (!PQexecStart(conn))
+ return NULL;
+ if (!PQsendPrepare(conn, stmtName, query, nParams, paramTypes))
+ return NULL;
+ return PQexecFinish(conn);
+ }
+
+ /*
* PQexecPrepared
* Like PQexec, but execute a previously prepared statement,
* using protocol 3.0 so we can pass parameters
***************
*** 1451,1457 ****
* If we sent the COPY command in extended-query mode, we must
* issue a Sync as well.
*/
! if (conn->ext_query)
{
if (pqPutMsgStart('S', false, conn) < 0 ||
pqPutMsgEnd(conn) < 0)
--- 1561,1567 ----
* If we sent the COPY command in extended-query mode, we must
* issue a Sync as well.
*/
! if (conn->queryclass != PGQUERY_SIMPLE)
{
if (pqPutMsgStart('S', false, conn) < 0 ||
pqPutMsgEnd(conn) < 0)
*** src/interfaces/libpq/fe-protocol3.c.orig Sat Oct 16 18:52:54 2004
--- src/interfaces/libpq/fe-protocol3.c Mon Oct 18 17:35:24 2004
***************
*** 220,225 ****
--- 220,234 ----
conn->asyncStatus = PGASYNC_READY;
break;
case '1': /* Parse Complete */
+ /* If we're doing PQprepare, we're done; else ignore */
+ if (conn->queryclass == PGQUERY_PREPARE)
+ {
+ if (conn->result == NULL)
+ conn->result = PQmakeEmptyPGresult(conn,
+ PGRES_COMMAND_OK);
+ conn->asyncStatus = PGASYNC_READY;
+ }
+ break;
case '2': /* Bind Complete */
case '3': /* Close Complete */
/* Nothing to do for these message types */
***************
*** 1118,1124 ****
* If we sent the COPY command in extended-query mode, we must
* issue a Sync as well.
*/
! if (conn->ext_query)
{
if (pqPutMsgStart('S', false, conn) < 0 ||
pqPutMsgEnd(conn) < 0)
--- 1127,1133 ----
* If we sent the COPY command in extended-query mode, we must
* issue a Sync as well.
*/
! if (conn->queryclass != PGQUERY_SIMPLE)
{
if (pqPutMsgStart('S', false, conn) < 0 ||
pqPutMsgEnd(conn) < 0)
*** src/interfaces/libpq/libpq-fe.h.orig Sat Oct 16 18:52:55 2004
--- src/interfaces/libpq/libpq-fe.h Mon Oct 18 17:35:24 2004
***************
*** 304,309 ****
--- 304,312 ----
const int *paramLengths,
const int *paramFormats,
int resultFormat);
+ extern PGresult *PQprepare(PGconn *conn, const char *stmtName,
+ const char *query, int nParams,
+ const Oid *paramTypes);
extern PGresult *PQexecPrepared(PGconn *conn,
const char *stmtName,
int nParams,
***************
*** 322,327 ****
--- 325,333 ----
const int *paramLengths,
const int *paramFormats,
int resultFormat);
+ extern int PQsendPrepare(PGconn *conn, const char *stmtName,
+ const char *query, int nParams,
+ const Oid *paramTypes);
extern int PQsendQueryPrepared(PGconn *conn,
const char *stmtName,
int nParams,
*** src/interfaces/libpq/libpq-int.h.orig Sat Oct 16 18:52:55 2004
--- src/interfaces/libpq/libpq-int.h Mon Oct 18 17:35:25 2004
***************
*** 185,190 ****
--- 185,198 ----
PGASYNC_COPY_OUT /* Copy Out data transfer in progress */
} PGAsyncStatusType;

+ /* PGQueryClass tracks which query protocol we are now executing */
+ typedef enum
+ {
+ PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
+ PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
+ PGQUERY_PREPARE /* Parse only (PQprepare) */
+ } PGQueryClass;
+
/* PGSetenvStatusType defines the state of the PQSetenv state machine */
/* (this is used only for 2.0-protocol connections) */
typedef enum
***************
*** 264,273 ****
PGAsyncStatusType asyncStatus;
PGTransactionStatusType xactStatus;
/* note: xactStatus never changes to ACTIVE */
bool nonblocking; /* whether this connection is using
* nonblock sending semantics */
- bool ext_query; /* was our last query sent with extended
- * query protocol? */
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
int copy_already_done; /* # bytes already returned in
* COPY OUT */
--- 272,280 ----
PGAsyncStatusType asyncStatus;
PGTransactionStatusType xactStatus;
/* note: xactStatus never changes to ACTIVE */
+ PGQueryClass queryclass;
bool nonblocking; /* whether this connection is using
* nonblock sending semantics */
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
int copy_already_done; /* # bytes already returned in
* COPY OUT */