mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add PQprepare/PQsendPrepared functions to libpq to support preparing
statements without necessarily specifying the datatypes of their parameters. Abhijit Menon-Sen with some help from Tom Lane.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.165 2004/10/01 17:34:17 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.166 2004/10/18 22:00:41 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="libpq">
|
<chapter id="libpq">
|
||||||
@ -1055,8 +1055,9 @@ PGresult *PQexec(PGconn *conn, const char *command);
|
|||||||
out-of-memory conditions or serious errors such as inability
|
out-of-memory conditions or serious errors such as inability
|
||||||
to send the command to the server.
|
to send the command to the server.
|
||||||
If a null pointer is returned, it
|
If a null pointer is returned, it
|
||||||
should be treated like a <symbol>PGRES_FATAL_ERROR</symbol> result. Use
|
should be treated like a <symbol>PGRES_FATAL_ERROR</symbol> result.
|
||||||
<function>PQerrorMessage</function> to get more information about the error.
|
Use <function>PQerrorMessage</function> to get more information
|
||||||
|
about such errors.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -1144,6 +1145,81 @@ than one nonempty command.) This is a limitation of the underlying protocol,
|
|||||||
but has some usefulness as an extra defense against SQL-injection attacks.
|
but has some usefulness as an extra defense against SQL-injection attacks.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<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>
|
<para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1166,7 +1242,8 @@ PGresult *PQexecPrepared(PGconn *conn,
|
|||||||
<para>
|
<para>
|
||||||
<function>PQexecPrepared</> is like <function>PQexecParams</>, but the
|
<function>PQexecPrepared</> is like <function>PQexecParams</>, but the
|
||||||
command to be executed is specified by naming a previously-prepared
|
command to be executed is specified by naming a previously-prepared
|
||||||
statement, instead of giving a query string. This feature allows commands
|
statement, instead of giving a query string.
|
||||||
|
This feature allows commands
|
||||||
that will be used repeatedly to be parsed and planned just once, rather
|
that will be used repeatedly to be parsed and planned just once, rather
|
||||||
than each time they are executed.
|
than each time they are executed.
|
||||||
<function>PQexecPrepared</> is supported only in protocol 3.0 and later
|
<function>PQexecPrepared</> is supported only in protocol 3.0 and later
|
||||||
@ -1182,13 +1259,6 @@ the prepared statement's parameter types were determined when it was created).
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -2270,10 +2340,15 @@ discarded by <function>PQexec</function>.
|
|||||||
Applications that do not like these limitations can instead use the
|
Applications that do not like these limitations can instead use the
|
||||||
underlying functions that <function>PQexec</function> is built from:
|
underlying functions that <function>PQexec</function> is built from:
|
||||||
<function>PQsendQuery</function> and <function>PQgetResult</function>.
|
<function>PQsendQuery</function> and <function>PQgetResult</function>.
|
||||||
There are also <function>PQsendQueryParams</function> and
|
There are also
|
||||||
<function>PQsendQueryPrepared</function>, which can be used with
|
<function>PQsendQueryParams</function>,
|
||||||
<function>PQgetResult</function> to duplicate the functionality of
|
<function>PQsendPrepare</function>, and
|
||||||
<function>PQexecParams</function> and <function>PQexecPrepared</function>
|
<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.
|
respectively.
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@ -2325,6 +2400,33 @@ int PQsendQueryParams(PGconn *conn,
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><function>PQsendQueryPrepared</function><indexterm><primary>PQsendQueryPrepared</></></term>
|
<term><function>PQsendQueryPrepared</function><indexterm><primary>PQsendQueryPrepared</></></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -2358,7 +2460,8 @@ int PQsendQueryPrepared(PGconn *conn,
|
|||||||
<para>
|
<para>
|
||||||
Waits for the next result from a prior
|
Waits for the next result from a prior
|
||||||
<function>PQsendQuery</function>,
|
<function>PQsendQuery</function>,
|
||||||
<function>PQsendQueryParams</function>, or
|
<function>PQsendQueryParams</function>,
|
||||||
|
<function>PQsendPrepare</function>, or
|
||||||
<function>PQsendQueryPrepared</function> call,
|
<function>PQsendQueryPrepared</function> call,
|
||||||
and returns it. A null pointer is returned when the command is complete
|
and returns it. A null pointer is returned when the command is complete
|
||||||
and there will be no more results.
|
and there will be no more results.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.2 2004/10/18 22:00:42 tgl Exp $
|
||||||
# Functions to be exported by libpq DLLs
|
# Functions to be exported by libpq DLLs
|
||||||
PQconnectdb 1
|
PQconnectdb 1
|
||||||
PQsetdbLogin 2
|
PQsetdbLogin 2
|
||||||
@ -116,3 +117,5 @@ PQgetssl 114
|
|||||||
pg_char_to_encoding 115
|
pg_char_to_encoding 115
|
||||||
pg_valid_server_encoding 116
|
pg_valid_server_encoding 116
|
||||||
pqsignal 117
|
pqsignal 117
|
||||||
|
PQprepare 118
|
||||||
|
PQsendPrepare 119
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.163 2004/10/16 22:52:53 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.164 2004/10/18 22:00:42 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -664,7 +664,7 @@ PQsendQuery(PGconn *conn, const char *query)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* remember we are using simple query protocol */
|
/* remember we are using simple query protocol */
|
||||||
conn->ext_query = false;
|
conn->queryclass = PGQUERY_SIMPLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give the data a push. In nonblock mode, don't complain if we're
|
* Give the data a push. In nonblock mode, don't complain if we're
|
||||||
@ -717,6 +717,94 @@ PQsendQueryParams(PGconn *conn,
|
|||||||
resultFormat);
|
resultFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* PQsendQueryPrepared
|
||||||
* Like PQsendQuery, but execute a previously prepared statement,
|
* Like PQsendQuery, but execute a previously prepared statement,
|
||||||
@ -921,7 +1009,7 @@ PQsendQueryGuts(PGconn *conn,
|
|||||||
goto sendFailed;
|
goto sendFailed;
|
||||||
|
|
||||||
/* remember we are using extended query protocol */
|
/* remember we are using extended query protocol */
|
||||||
conn->ext_query = true;
|
conn->queryclass = PGQUERY_EXTENDED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give the data a push. In nonblock mode, don't complain if we're
|
* Give the data a push. In nonblock mode, don't complain if we're
|
||||||
@ -1134,7 +1222,6 @@ PQgetResult(PGconn *conn)
|
|||||||
* The user is responsible for freeing the PGresult via PQclear()
|
* The user is responsible for freeing the PGresult via PQclear()
|
||||||
* when done with it.
|
* when done with it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PGresult *
|
PGresult *
|
||||||
PQexec(PGconn *conn, const char *query)
|
PQexec(PGconn *conn, const char *query)
|
||||||
{
|
{
|
||||||
@ -1168,6 +1255,29 @@ PQexecParams(PGconn *conn,
|
|||||||
return PQexecFinish(conn);
|
return PQexecFinish(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* PQexecPrepared
|
||||||
* Like PQexec, but execute a previously prepared statement,
|
* Like PQexec, but execute a previously prepared statement,
|
||||||
@ -1451,7 +1561,7 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
|
|||||||
* If we sent the COPY command in extended-query mode, we must
|
* If we sent the COPY command in extended-query mode, we must
|
||||||
* issue a Sync as well.
|
* issue a Sync as well.
|
||||||
*/
|
*/
|
||||||
if (conn->ext_query)
|
if (conn->queryclass != PGQUERY_SIMPLE)
|
||||||
{
|
{
|
||||||
if (pqPutMsgStart('S', false, conn) < 0 ||
|
if (pqPutMsgStart('S', false, conn) < 0 ||
|
||||||
pqPutMsgEnd(conn) < 0)
|
pqPutMsgEnd(conn) < 0)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.18 2004/10/16 22:52:54 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.19 2004/10/18 22:00:42 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -220,6 +220,15 @@ pqParseInput3(PGconn *conn)
|
|||||||
conn->asyncStatus = PGASYNC_READY;
|
conn->asyncStatus = PGASYNC_READY;
|
||||||
break;
|
break;
|
||||||
case '1': /* Parse Complete */
|
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 '2': /* Bind Complete */
|
||||||
case '3': /* Close Complete */
|
case '3': /* Close Complete */
|
||||||
/* Nothing to do for these message types */
|
/* Nothing to do for these message types */
|
||||||
@ -1118,7 +1127,7 @@ pqEndcopy3(PGconn *conn)
|
|||||||
* If we sent the COPY command in extended-query mode, we must
|
* If we sent the COPY command in extended-query mode, we must
|
||||||
* issue a Sync as well.
|
* issue a Sync as well.
|
||||||
*/
|
*/
|
||||||
if (conn->ext_query)
|
if (conn->queryclass != PGQUERY_SIMPLE)
|
||||||
{
|
{
|
||||||
if (pqPutMsgStart('S', false, conn) < 0 ||
|
if (pqPutMsgStart('S', false, conn) < 0 ||
|
||||||
pqPutMsgEnd(conn) < 0)
|
pqPutMsgEnd(conn) < 0)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.111 2004/10/16 22:52:55 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.112 2004/10/18 22:00:42 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -304,6 +304,9 @@ extern PGresult *PQexecParams(PGconn *conn,
|
|||||||
const int *paramLengths,
|
const int *paramLengths,
|
||||||
const int *paramFormats,
|
const int *paramFormats,
|
||||||
int resultFormat);
|
int resultFormat);
|
||||||
|
extern PGresult *PQprepare(PGconn *conn, const char *stmtName,
|
||||||
|
const char *query, int nParams,
|
||||||
|
const Oid *paramTypes);
|
||||||
extern PGresult *PQexecPrepared(PGconn *conn,
|
extern PGresult *PQexecPrepared(PGconn *conn,
|
||||||
const char *stmtName,
|
const char *stmtName,
|
||||||
int nParams,
|
int nParams,
|
||||||
@ -322,6 +325,9 @@ extern int PQsendQueryParams(PGconn *conn,
|
|||||||
const int *paramLengths,
|
const int *paramLengths,
|
||||||
const int *paramFormats,
|
const int *paramFormats,
|
||||||
int resultFormat);
|
int resultFormat);
|
||||||
|
extern int PQsendPrepare(PGconn *conn, const char *stmtName,
|
||||||
|
const char *query, int nParams,
|
||||||
|
const Oid *paramTypes);
|
||||||
extern int PQsendQueryPrepared(PGconn *conn,
|
extern int PQsendQueryPrepared(PGconn *conn,
|
||||||
const char *stmtName,
|
const char *stmtName,
|
||||||
int nParams,
|
int nParams,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.94 2004/10/16 22:52:55 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.95 2004/10/18 22:00:42 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -185,6 +185,14 @@ typedef enum
|
|||||||
PGASYNC_COPY_OUT /* Copy Out data transfer in progress */
|
PGASYNC_COPY_OUT /* Copy Out data transfer in progress */
|
||||||
} PGAsyncStatusType;
|
} 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 */
|
/* PGSetenvStatusType defines the state of the PQSetenv state machine */
|
||||||
/* (this is used only for 2.0-protocol connections) */
|
/* (this is used only for 2.0-protocol connections) */
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -264,10 +272,9 @@ struct pg_conn
|
|||||||
PGAsyncStatusType asyncStatus;
|
PGAsyncStatusType asyncStatus;
|
||||||
PGTransactionStatusType xactStatus;
|
PGTransactionStatusType xactStatus;
|
||||||
/* note: xactStatus never changes to ACTIVE */
|
/* note: xactStatus never changes to ACTIVE */
|
||||||
|
PGQueryClass queryclass;
|
||||||
bool nonblocking; /* whether this connection is using
|
bool nonblocking; /* whether this connection is using
|
||||||
* nonblock sending semantics */
|
* 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 */
|
char copy_is_binary; /* 1 = copy binary, 0 = copy text */
|
||||||
int copy_already_done; /* # bytes already returned in
|
int copy_already_done; /* # bytes already returned in
|
||||||
* COPY OUT */
|
* COPY OUT */
|
||||||
|
Reference in New Issue
Block a user