From 5835593dfc18b68b5cab9fca2d51f7877e11217f Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Fri, 18 Dec 2015 13:04:34 +0900 Subject: [PATCH] Improve FR #31021 implementation (pg_last_notice() is needed to get all notice messages). Now pg_last_notice() can clear stored notices. --- UPGRADING | 14 ++++++-- ext/pgsql/pgsql.c | 65 ++++++++++++++++++++++------------- ext/pgsql/tests/09notice.phpt | 19 ++++++++-- 3 files changed, 70 insertions(+), 28 deletions(-) diff --git a/UPGRADING b/UPGRADING index e7a6856744..b77d8aa7ba 100644 --- a/UPGRADING +++ b/UPGRADING @@ -46,9 +46,12 @@ PHP 7.1 UPGRADE NOTES current environment variables will be returned as an associative array when omitted. - long2ip() accepts integer as parameter now -- pg_last_notice() accepts optional 2nd bool parameter to get all notices and - returns empty string or array on successful calls. It returned FALSE for - empty notice previously. +- pg_last_notice() accepts optional long parameter to specify operation. + PGSQL_NOTICE_LAST - Get last notice (Default) + PGSQL_NOTICE_ALL - Get all stored notices + PGSQL_NOTICE_CLEAR - Remove all stored notices + It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls. + It returned FALSE for empty notice previously. - pg_fetch_all() accepts optional 2nd bool parameter to get numerically indexed rows. - pg_select() accepts PGSQL_FETCH_NUM option to get numerically indexed rows. @@ -73,6 +76,11 @@ PHP 7.1 UPGRADE NOTES 10. New Global Constants ======================================== +- Pgsql: + PGSQL_NOTICE_LAST + PGSQL_NOTICE_ALL + PGSQL_NOTICE_CLEAR + ======================================== 11. Changes to INI File Handling ======================================== diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 812a2d5fc0..173998c57f 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -56,9 +56,13 @@ #define InvalidOid ((Oid) 0) #endif -#define PGSQL_ASSOC 1<<0 -#define PGSQL_NUM 1<<1 -#define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM) +#define PGSQL_ASSOC 1<<0 +#define PGSQL_NUM 1<<1 +#define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM) + +#define PGSQL_NOTICE_LAST 1 /* Get the last notice */ +#define PGSQL_NOTICE_ALL 2 /* Get all notices */ +#define PGSQL_NOTICE_CLEAR 3 /* Remove notices */ #define PGSQL_STATUS_LONG 1 #define PGSQL_STATUS_STRING 2 @@ -208,7 +212,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1) ZEND_ARG_INFO(0, connection) - ZEND_ARG_INFO(0, all_notices) + ZEND_ARG_INFO(0, option) ZEND_END_ARG_INFO() #ifdef HAVE_PQFTABLE @@ -1120,6 +1124,10 @@ PHP_MINIT_FUNCTION(pgsql) REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT); + /* For pg_last_notice() */ + REGISTER_LONG_CONSTANT("PGSQL_NOTICE_LAST", PGSQL_NOTICE_LAST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_NOTICE_ALL", PGSQL_NOTICE_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PGSQL_NOTICE_CLEAR", PGSQL_NOTICE_CLEAR, CONST_CS | CONST_PERSISTENT); /* For pg_connection_status() */ REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT); @@ -2304,16 +2312,16 @@ PHP_FUNCTION(pg_affected_rows) /* }}} */ #endif -/* {{{ proto mixed pg_last_notice(resource connection [, bool all_notices]) +/* {{{ proto mixed pg_last_notice(resource connection [, long option]) Returns the last notice set by the backend */ PHP_FUNCTION(pg_last_notice) { zval *pgsql_link = NULL; zval *notice, *notices; PGconn *pg_link; - zend_bool all_notices = 0; + long option = PGSQL_NOTICE_LAST; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &pgsql_link, &all_notices) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_link, &option) == FAILURE) { return; } @@ -2322,26 +2330,37 @@ PHP_FUNCTION(pg_last_notice) RETURN_FALSE; } - /* PHP 7.0 and earlier returns FALSE for empty notice. - PHP 7.1> returns empty array or string */ notices = zend_hash_index_find(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link)); - if (all_notices) { - if (notices) { - RETURN_ZVAL(notices, 1, 0); - } else { - array_init(return_value); - } - } else { - if (notices) { - zend_hash_internal_pointer_end(Z_ARRVAL_P(notices)); - if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) { + switch (option) { + case PGSQL_NOTICE_LAST: + if (notices) { + zend_hash_internal_pointer_end(Z_ARRVAL_P(notices)); + if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) { + RETURN_EMPTY_STRING(); + } + RETURN_ZVAL(notice, 1, 0); + } else { RETURN_EMPTY_STRING(); } - RETURN_ZVAL(notice, 1, 0); - } else { - RETURN_EMPTY_STRING(); - } + break; + case PGSQL_NOTICE_ALL: + if (notices) { + RETURN_ZVAL(notices, 1, 0); + } else { + array_init(return_value); + return; + } + break; + case PGSQL_NOTICE_CLEAR: + if (notices) { + zend_hash_clean(&PGG(notices)); + } + RETURN_TRUE; + break; + default: + php_error_docref(NULL, E_WARNING, "Invalid option specified (%d)", option); } + RETURN_FALSE; } /* }}} */ diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt index c5f9b1df9e..fb5dc8325c 100644 --- a/ext/pgsql/tests/09notice.phpt +++ b/ext/pgsql/tests/09notice.phpt @@ -26,7 +26,7 @@ var_dump($res); // Get empty notice var_dump(pg_last_notice($db)); -var_dump(pg_last_notice($db, TRUE)); +var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL)); pg_query($db, "BEGIN;"); pg_query($db, "BEGIN;"); @@ -35,7 +35,15 @@ pg_query($db, "BEGIN;"); // Get notices var_dump(pg_last_notice($db)); -var_dump(pg_last_notice($db, TRUE)); +var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL)); + +// Clear and get notices +var_dump(pg_last_notice($db, PGSQL_NOTICE_CLEAR)); +var_dump(pg_last_notice($db, PGSQL_NOTICE_LAST)); +var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL)); + +// Invalid option +var_dump(pg_last_notice($db, 99)); ?> --EXPECTF-- resource(%d) of type (pgsql result) @@ -57,3 +65,10 @@ array(3) { [2]=> string(52) "WARNING: there is already a transaction in progress" } +bool(true) +string(0) "" +array(0) { +} + +Warning: pg_last_notice(): Invalid option specified (99) in %s/09notice.php on line %d +bool(false) -- 2.40.0