Skip to content

Commit 018a15d

Browse files
committed
ext/pgsql: adding pg_close_stmt.
up to postgresql 17, when done with a prepared statement, we could release it with DEALLOCATE sql command which is fine ; until we want to implement a cache solution based on statement ids. Since PostgreSQL 17, PQclosePrepared uses internally the `close` protocol allowing to reuse the statement name while still freeing it. Since the close protocol implementation had been added on libpq within this release, no way to reimplement it.
1 parent fec2055 commit 018a15d

File tree

5 files changed

+89
-1
lines changed

5 files changed

+89
-1
lines changed

ext/pgsql/config.m4

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ if test "$PHP_PGSQL" != "no"; then
3333
[Define to 1 if libpq has the 'PQsetChunkedRowsMode' function (PostgreSQL
3434
17 or later).])],,
3535
[$PGSQL_LIBS])
36+
PHP_CHECK_LIBRARY([pq], [PQclosePrepared],
37+
[AC_DEFINE([HAVE_PG_CLOSE_STMT], [1], [PostgreSQL 17 or later])],,
38+
[$PGSQL_LIBS])
3639

3740
old_CFLAGS=$CFLAGS
3841
CFLAGS="$CFLAGS $PGSQL_CFLAGS"

ext/pgsql/pgsql.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6256,3 +6256,39 @@ PHP_FUNCTION(pg_set_chunked_rows_size)
62566256
RETURN_BOOL(PQsetChunkedRowsMode(link->conn, (int)size) == 1);
62576257
}
62586258
#endif
6259+
6260+
#if defined(HAVE_PG_CLOSE_STMT)
6261+
PHP_FUNCTION(pg_close_stmt)
6262+
{
6263+
zval *pgsql_link;
6264+
pgsql_link_handle *link;
6265+
PGresult *pgsql_result;
6266+
zend_string *stmt;
6267+
6268+
ZEND_PARSE_PARAMETERS_START(2, 2)
6269+
Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce)
6270+
Z_PARAM_STR(stmt)
6271+
ZEND_PARSE_PARAMETERS_END();
6272+
6273+
if (ZSTR_LEN(stmt) == 0) {
6274+
zend_argument_value_error(2, "cannot be empty");
6275+
RETURN_THROWS();
6276+
}
6277+
6278+
link = Z_PGSQL_LINK_P(pgsql_link);
6279+
CHECK_PGSQL_LINK(link);
6280+
6281+
pgsql_result = PQclosePrepared(link->conn, ZSTR_VAL(stmt));
6282+
6283+
if (!pgsql_result) {
6284+
RETURN_FALSE;
6285+
} else {
6286+
pgsql_result_handle *pg_result;
6287+
object_init_ex(return_value, pgsql_result_ce);
6288+
pg_result = Z_PGSQL_RESULT_P(return_value);
6289+
pg_result->conn = link->conn;
6290+
pg_result->result = pgsql_result;
6291+
pg_result->row = 0;
6292+
}
6293+
}
6294+
#endif

ext/pgsql/pgsql.stub.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,9 @@ function pg_socket_poll($socket, int $read, int $write, int $timeout = -1): int
970970
#ifdef HAVE_PG_SET_CHUNKED_ROWS_SIZE
971971
function pg_set_chunked_rows_size(Pgsql\Connection $connection, int $size): bool {}
972972
#endif
973+
#ifdef HAVE_PG_CLOSE_STMT
974+
function pg_close_stmt(Pgsql\Connection $connection, string $statement_name): Pgsql\Result|false {}
975+
#endif
973976
}
974977

975978
namespace PgSql {

ext/pgsql/pgsql_arginfo.h

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/pgsql/tests/pg_close_stmt.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
PostgreSQL pg_close_stmt
3+
--EXTENSIONS--
4+
pgsql
5+
--SKIPIF--
6+
<?php include("inc/skipif.inc");
7+
if (!function_exists("pg_close_stmt")) die("skip pg_close_stmt unsupported");
8+
?>
9+
--FILE--
10+
<?php
11+
include('inc/config.inc');
12+
13+
14+
$query = 'SELECT $1::text IS NULL;';
15+
$params_null = [null];
16+
17+
$db = pg_connect($conn_str);
18+
$res = pg_prepare($db, 'test', $query);
19+
20+
$res = pg_execute($db, 'test', $params_null);
21+
$res = pg_close_stmt($db, 'test');
22+
var_dump($res !== null);
23+
var_dump(pg_result_status($res) === PGSQL_COMMAND_OK);
24+
pg_prepare($db, 'test', $query);
25+
$res = pg_execute($db, 'test', $params_null);
26+
pg_free_result($res);
27+
28+
pg_close($db);
29+
30+
?>
31+
--EXPECT--
32+
bool(true)
33+
bool(true)

0 commit comments

Comments
 (0)