mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
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 GH-14584
This commit is contained in:
parent
291eef285c
commit
1da352c367
7 changed files with 98 additions and 1 deletions
4
NEWS
4
NEWS
|
@ -8,6 +8,10 @@ PHP NEWS
|
|||
Pdo\Pgsql::prepare(…, [ PDO::ATTR_PREFETCH => 0 ]) make fetch() lazy
|
||||
instead of storing the whole result set in memory (Guillaume Outters)
|
||||
|
||||
- PGSQL:
|
||||
. Added pg_close_stmt to close a prepared statement while allowing
|
||||
its name to be reused. (David Carlier)
|
||||
|
||||
- Random:
|
||||
. Moves from /dev/urandom usage to arc4random_buf on Haiku. (David Carlier)
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@ PHP 8.5 UPGRADE NOTES
|
|||
6. New Functions
|
||||
========================================
|
||||
|
||||
- PGSQL@
|
||||
. pg_close_stmt offers an alternative way to close a prepared
|
||||
statement from the DEALLOCATE sql command in that we can reuse
|
||||
its name afterwards.
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
========================================
|
||||
|
|
|
@ -33,6 +33,9 @@ if test "$PHP_PGSQL" != "no"; then
|
|||
[Define to 1 if libpq has the 'PQsetChunkedRowsMode' function (PostgreSQL
|
||||
17 or later).])],,
|
||||
[$PGSQL_LIBS])
|
||||
PHP_CHECK_LIBRARY([pq], [PQclosePrepared],
|
||||
[AC_DEFINE([HAVE_PG_CLOSE_STMT], [1], [PostgreSQL 17 or later])],,
|
||||
[$PGSQL_LIBS])
|
||||
|
||||
old_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $PGSQL_CFLAGS"
|
||||
|
|
|
@ -6256,3 +6256,39 @@ PHP_FUNCTION(pg_set_chunked_rows_size)
|
|||
RETURN_BOOL(PQsetChunkedRowsMode(link->conn, (int)size) == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PG_CLOSE_STMT)
|
||||
PHP_FUNCTION(pg_close_stmt)
|
||||
{
|
||||
zval *pgsql_link;
|
||||
pgsql_link_handle *link;
|
||||
PGresult *pgsql_result;
|
||||
zend_string *stmt;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(2, 2)
|
||||
Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce)
|
||||
Z_PARAM_STR(stmt)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (ZSTR_LEN(stmt) == 0) {
|
||||
zend_argument_value_error(2, "cannot be empty");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
link = Z_PGSQL_LINK_P(pgsql_link);
|
||||
CHECK_PGSQL_LINK(link);
|
||||
|
||||
pgsql_result = PQclosePrepared(link->conn, ZSTR_VAL(stmt));
|
||||
|
||||
if (PQresultStatus(pgsql_result) != PGRES_COMMAND_OK) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
pgsql_result_handle *pg_handle;
|
||||
object_init_ex(return_value, pgsql_result_ce);
|
||||
pg_handle = Z_PGSQL_RESULT_P(return_value);
|
||||
pg_handle->conn = link->conn;
|
||||
pg_handle->result = pgsql_result;
|
||||
pg_handle->row = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -970,6 +970,9 @@ namespace {
|
|||
#ifdef HAVE_PG_SET_CHUNKED_ROWS_SIZE
|
||||
function pg_set_chunked_rows_size(Pgsql\Connection $connection, int $size): bool {}
|
||||
#endif
|
||||
#ifdef HAVE_PG_CLOSE_STMT
|
||||
function pg_close_stmt(Pgsql\Connection $connection, string $statement_name): Pgsql\Result|false {}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace PgSql {
|
||||
|
|
15
ext/pgsql/pgsql_arginfo.h
generated
15
ext/pgsql/pgsql_arginfo.h
generated
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 0b89a48c27c6682542312391f10a3ab8fb719ef8 */
|
||||
* Stub hash: 1f0141abe7cf476c305b074e31ce69a48b6eee21 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql\\Connection, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0)
|
||||
|
@ -495,6 +495,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_set_chunked_rows_size, 0, 2,
|
|||
ZEND_END_ARG_INFO()
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PG_CLOSE_STMT)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_close_stmt, 0, 2, Pgsql\\Result, MAY_BE_FALSE)
|
||||
ZEND_ARG_OBJ_INFO(0, connection, Pgsql\\Connection, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, statement_name, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
#endif
|
||||
|
||||
ZEND_FUNCTION(pg_connect);
|
||||
ZEND_FUNCTION(pg_pconnect);
|
||||
ZEND_FUNCTION(pg_connect_poll);
|
||||
|
@ -598,6 +605,9 @@ ZEND_FUNCTION(pg_socket_poll);
|
|||
#if defined(HAVE_PG_SET_CHUNKED_ROWS_SIZE)
|
||||
ZEND_FUNCTION(pg_set_chunked_rows_size);
|
||||
#endif
|
||||
#if defined(HAVE_PG_CLOSE_STMT)
|
||||
ZEND_FUNCTION(pg_close_stmt);
|
||||
#endif
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(pg_connect, arginfo_pg_connect)
|
||||
|
@ -725,6 +735,9 @@ static const zend_function_entry ext_functions[] = {
|
|||
ZEND_FE(pg_socket_poll, arginfo_pg_socket_poll)
|
||||
#if defined(HAVE_PG_SET_CHUNKED_ROWS_SIZE)
|
||||
ZEND_FE(pg_set_chunked_rows_size, arginfo_pg_set_chunked_rows_size)
|
||||
#endif
|
||||
#if defined(HAVE_PG_CLOSE_STMT)
|
||||
ZEND_FE(pg_close_stmt, arginfo_pg_close_stmt)
|
||||
#endif
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
|
33
ext/pgsql/tests/pg_close_stmt.phpt
Normal file
33
ext/pgsql/tests/pg_close_stmt.phpt
Normal file
|
@ -0,0 +1,33 @@
|
|||
--TEST--
|
||||
PostgreSQL pg_close_stmt
|
||||
--EXTENSIONS--
|
||||
pgsql
|
||||
--SKIPIF--
|
||||
<?php include("inc/skipif.inc");
|
||||
if (!function_exists("pg_close_stmt")) die("skip pg_close_stmt unsupported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
include('inc/config.inc');
|
||||
|
||||
|
||||
$query = 'SELECT $1::text IS NULL;';
|
||||
$params_null = [null];
|
||||
|
||||
$db = pg_connect($conn_str);
|
||||
$res = pg_prepare($db, 'test', $query);
|
||||
|
||||
$res = pg_execute($db, 'test', $params_null);
|
||||
$res = pg_close_stmt($db, 'test');
|
||||
var_dump($res !== false);
|
||||
var_dump(pg_result_status($res) === PGSQL_COMMAND_OK);
|
||||
pg_prepare($db, 'test', $query);
|
||||
$res = pg_execute($db, 'test', $params_null);
|
||||
pg_free_result($res);
|
||||
|
||||
pg_close($db);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
Loading…
Add table
Add a link
Reference in a new issue