diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index 8718208e8506..b8952521c302 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -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" diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index af95c81d803a..09ed9d75623c 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -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 diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index f507de2e062a..10ce60df9cdc 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -970,6 +970,9 @@ function pg_socket_poll($socket, int $read, int $write, int $timeout = -1): int #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 { diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index 182dea8d221a..778698a28756 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -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 }; diff --git a/ext/pgsql/tests/pg_close_stmt.phpt b/ext/pgsql/tests/pg_close_stmt.phpt new file mode 100644 index 000000000000..e93108c1e7a2 --- /dev/null +++ b/ext/pgsql/tests/pg_close_stmt.phpt @@ -0,0 +1,33 @@ +--TEST-- +PostgreSQL pg_close_stmt +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true)