Skip to content

Commit edb0556

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 4f450b6 commit edb0556

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
@@ -24,6 +24,9 @@ if test "$PHP_PGSQL" != "no"; then
2424
PHP_CHECK_LIBRARY([pq], [PQsetChunkedRowsMode],
2525
[AC_DEFINE([HAVE_PG_SET_CHUNKED_ROWS_SIZE], [1], [PostgreSQL 17 or later])],,
2626
[$PGSQL_LIBS])
27+
PHP_CHECK_LIBRARY([pq], [PQclosePrepared],
28+
[AC_DEFINE([HAVE_PG_CLOSE_STMT], [1], [PostgreSQL 17 or later])],,
29+
[$PGSQL_LIBS])
2730

2831
old_CFLAGS=$CFLAGS
2932
CFLAGS="$CFLAGS $PGSQL_CFLAGS"

ext/pgsql/pgsql.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6267,3 +6267,39 @@ PHP_FUNCTION(pg_set_chunked_rows_size)
62676267
RETURN_BOOL(PQsetChunkedRowsMode(link->conn, (int)size) == 1);
62686268
}
62696269
#endif
6270+
6271+
#if defined(HAVE_PG_CLOSE_STMT)
6272+
PHP_FUNCTION(pg_close_stmt)
6273+
{
6274+
zval *pgsql_link;
6275+
pgsql_link_handle *link;
6276+
PGresult *pgsql_result;
6277+
zend_string *stmt;
6278+
6279+
ZEND_PARSE_PARAMETERS_START(2, 2)
6280+
Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce)
6281+
Z_PARAM_STR(stmt)
6282+
ZEND_PARSE_PARAMETERS_END();
6283+
6284+
if (ZSTR_LEN(stmt) == 0) {
6285+
zend_argument_value_error(2, "cannot be empty");
6286+
RETURN_THROWS();
6287+
}
6288+
6289+
link = Z_PGSQL_LINK_P(pgsql_link);
6290+
CHECK_PGSQL_LINK(link);
6291+
6292+
pgsql_result = PQclosePrepared(link->conn, ZSTR_VAL(stmt));
6293+
6294+
if (!pgsql_result) {
6295+
RETURN_FALSE;
6296+
} else {
6297+
pgsql_result_handle *pg_result;
6298+
object_init_ex(return_value, pgsql_result_ce);
6299+
pg_result = Z_PGSQL_RESULT_P(return_value);
6300+
pg_result->conn = link->conn;
6301+
pg_result->result = pgsql_result;
6302+
pg_result->row = 0;
6303+
}
6304+
}
6305+
#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 $stmt_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)