From: | jian he <jian(dot)universality(at)gmail(dot)com> |
---|---|
To: | Jelte Fennema <me(at)jeltef(dot)nl> |
Cc: | Craig Ringer <craig(at)2ndquadrant(dot)com>, Dmitry Igrishin <dmitigr(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>, Daniele Varrazzo <daniele(dot)varrazzo(at)gmail(dot)com> |
Subject: | Re: Deleting prepared statements from libpq. |
Date: | 2023-06-17 13:34:24 |
Message-ID: | CACJufxHRbW4nRa6RMttknzV7tz64L5nLFMp7tveOed3JgWFDhA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Fri, Jun 16, 2023 at 11:28 PM Jelte Fennema <me(at)jeltef(dot)nl> wrote:
>
> On Fri, 16 Jun 2023 at 16:26, Craig Ringer <craig(at)2ndquadrant(dot)com> wrote:
> > Nobody's implemented it.
> >
> > A patch to add PQclosePrepared and PQsendClosePrepared would be welcome. At least, I think so...
>
> This might have been a pretty old thread. But I just took it upon me
> to implement these functions (or well I mostly copied the
> PQsendDescribe related code and did s/describe/close). I haven't
> tested this code yet but I'm pretty sure it should just work (it
> compiles at least).
>
> The main reason I'm interested in this is because we're actively
> working on implementing named prepared statement support for PgBouncer
> in transaction pooling mode. It works with lots of client libraries
> already. But sadly it doesn't work with psycopg at the moment, or at
> least the closing part does not. And the reason is that psycopg closes
> statements using a DEALLOCATE query instead of the Close protocol
> message, because libpq does not support sending the Close protocol
> message.
>
> Afaict this is not just a problem for PgBouncer its implementation. As
> far as I can tell the same is true for the Odyssey connection pooler
> (which implemented named prepared statement support first).
I failed to link it. I don't know why.
if I comment out {assert(PQsendClosePrepared(conn,stmtName) == 1);}
then it works.
I use the following 4 commands, they all yield results, so it seems
PQsendClosePrepare is there.
nm /home/jian/postgres/pg16_test/lib/libpq.so.5.16 | grep PQsendClosePrepare
nm /home/jian/postgres/pg16_test/lib/libpq.so.5 | grep PQsendClosePrepare
nm /home/jian/postgres/pg16_test/lib/libpq.so | grep PQsendClosePrepare
nm /home/jian/postgres/pg16_test/lib/libpq.a | grep PQsendClosePrepare
------------------------------------------
/*
gcc -I/home/jian/postgres/pg16_test/include
/home/jian/misc/testlibpq.c -L/home/jian/postgres/pg16_test/lib -lpq
// nm /home/jian/postgres/pg16_test/lib/libpq.so | grep PQsendClosePrepared
000000000008df90 b __gcov0.PQsendClosePrepared
000000000007fda0 d __gcov_.PQsendClosePrepared
000000000002d060 t PQsendClosePrepared
*/
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
#include <assert.h>
void exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
};
int main()
{
char *conninfo = "dbname=test16beta port=5455 host=/tmp user=jian";
PGconn *conn;
PGresult *res;
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
exit_nicely(conn);
}
// PREPARE q3(text, int, float, boolean, smallint) AS
// SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR
// ten = $3::bigint OR true = $4 OR odd = $5::int)
// ORDER BY unique1;
// EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint);
// select 'text'::regtype::oid,'int'::regtype::oid,'float'::regtype::oid,'bool'::regtype::oid,'smallint'::regtype::oid;
const char *stmtName = "q3";
const char *query =
"SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR "
"ten = $3::bigint OR true = $4 OR odd = $5::int) "
"ORDER BY unique1 ";
int nParams = 5;
const Oid oidTypes[5] = {25, 23, 701,16, 21};
const char *const paramValues[] = {"AAAAxx","5","10.5","false","4"};
res = PQprepare(conn, stmtName, query,nParams, oidTypes);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
printf("here %d\n",__LINE__);
fprintf(stderr, "PQprepare failed: %s\n",PQresultErrorMessage(res));
PQclear(res);
}
else
{
PQclear(res);
res = PQexecPrepared(conn, stmtName, 5, paramValues,NULL, NULL,0);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
PQclear(res);
printf("PQexecPrepared failed\n");
exit_nicely(conn);
}
assert(PQsendClosePrepared(conn,stmtName) == 1);
res = PQexec(conn,"select from pg_prepared_statements where
name = 'q3'");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
PQclear(res);
printf("this command should return zero rows now it's not\n");
exit_nicely(conn);
}
}
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}
From | Date | Subject | |
---|---|---|---|
Next Message | Tomas Vondra | 2023-06-17 13:45:07 | Re: Incorrect estimation of HashJoin rows resulted from inaccurate small table statistics |
Previous Message | Tomas Vondra | 2023-06-17 11:48:39 | Re: Incorrect estimation of HashJoin rows resulted from inaccurate small table statistics |