Skip to content

Commit 1da352c

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. close phpGH-14584
1 parent 291eef2 commit 1da352c

File tree

7 files changed

+98
-1
lines changed

7 files changed

+98
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ PHP NEWS
88
Pdo\Pgsql::prepare(…, [ PDO::ATTR_PREFETCH => 0 ]) make fetch() lazy
99
instead of storing the whole result set in memory (Guillaume Outters)
1010

11+
- PGSQL:
12+
. Added pg_close_stmt to close a prepared statement while allowing
13+
its name to be reused. (David Carlier)
14+
1115
- Random:
1216
. Moves from /dev/urandom usage to arc4random_buf on Haiku. (David Carlier)
1317

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ PHP 8.5 UPGRADE NOTES
5959
6. New Functions
6060
========================================
6161

62+
- PGSQL@
63+
. pg_close_stmt offers an alternative way to close a prepared
64+
statement from the DEALLOCATE sql command in that we can reuse
65+
its name afterwards.
66+
6267
========================================
6368
7. New Classes and Interfaces
6469
========================================

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 (PQresultStatus(pgsql_result) != PGRES_COMMAND_OK) {
6284+
RETURN_FALSE;
6285+
} else {
6286+
pgsql_result_handle *pg_handle;
6287+
object_init_ex(return_value, pgsql_result_ce);
6288+
pg_handle = Z_PGSQL_RESULT_P(return_value);
6289+
pg_handle->conn = link->conn;
6290+
pg_handle->result = pgsql_result;
6291+
pg_handle->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 !== false);
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)