--- libpq-fe.h.1~ 2004-10-05 18:14:07.885948042 +0530 +++ libpq-fe.h 2004-10-05 22:19:07.544034341 +0530 @@ -292,6 +292,9 @@ extern void PQinitSSL(int do_init); /* Simple synchronous query */ extern PGresult *PQexec(PGconn *conn, const char *query); +extern PGresult *PQprepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); extern PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, @@ -309,6 +312,9 @@ extern PGresult *PQexecPrepared(PGconn * 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 PQsendQuery(PGconn *conn, const char *query); extern int PQsendQueryParams(PGconn *conn, const char *command, --- fe-exec.c.1~ 2004-10-02 06:15:44.000000000 +0530 +++ fe-exec.c 2004-10-05 22:02:03.459149212 +0530 @@ -635,6 +635,69 @@ pqSaveParameterStatus(PGconn *conn, cons /* + * 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 (PG_PROTOCOL_MAJOR(conn->pversion) < 3) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("function requires at least protocol version 3.0\n")); + return 0; + } + + if (!PQsendQueryStart(conn)) + return 0; + + 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; + + if (pqPutMsgStart('S', false, conn) < 0 || + pqPutMsgEnd(conn) < 0) + goto sendFailed; + + conn->ext_query = true; + if (pqFlush(conn) < 0) + goto sendFailed; + conn->asyncStatus = PGASYNC_BUSY; + return 1; + +sendFailed: + pqHandleSendFailure(conn); + return 0; +} + + +/* * PQsendQuery * Submit a query, but don't wait for it to finish * @@ -1145,6 +1208,28 @@ PQexec(PGconn *conn, const char *query) return PQexecFinish(conn); } + +/* + * PQprepare + * Creates a prepared statement by issuing a v3.0 parse message. + * + * Returns NULL if the query failed, and a new PGresult otherwise. The + * user is responsible for calling PQclient() on the result. + */ + +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); +} + + /* * PQexecParams * Like PQexec, but use protocol 3.0 so we can pass parameters --- fe-protocol3.c.1~ 2004-10-05 18:59:55.293092244 +0530 +++ fe-protocol3.c 2004-10-05 19:17:48.154807848 +0530 @@ -220,6 +220,11 @@ pqParseInput3(PGconn *conn) conn->asyncStatus = PGASYNC_READY; break; case '1': /* Parse Complete */ + 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 */