diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | UPGRADING | 5 | ||||
-rw-r--r-- | ext/pgsql/pgsql.c | 64 | ||||
-rw-r--r-- | ext/pgsql/tests/09notice.phpt | 42 |
4 files changed, 74 insertions, 40 deletions
@@ -18,6 +18,9 @@ Hash: PDO_Firebird: . Fixed bug #60052 (Integer returned as a 64bit integer on X64_86). (Mariuz) +Pgsql: + . Implemented FR #31021 (pg_result_notice() is needed to get all notice messages). + Standard: . Fixed bug #71100 (long2ip() doesn't accept integers in strict mode). (Laruence) @@ -45,7 +45,10 @@ PHP 7.1 UPGRADE NOTES - The first $varname argument for getenv() is no longer mandatory, the current environment variables will be returned as an associative array when omitted. -- long2ip accepts integer as parameter now +- 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. ======================================== 6. New Functions diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index e8e5a536f7..1822867e42 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -961,29 +961,24 @@ static void _close_pgsql_plink(zend_resource *rsrc) */ static void _php_pgsql_notice_handler(void *resource_id, const char *message) { - php_pgsql_notice *notice; + zval *notices; + zval tmp; + char *trimed_message; + size_t trimed_message_len; if (! PGG(ignore_notices)) { - notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice)); - notice->message = _php_pgsql_trim_message(message, ¬ice->len); + notices = zend_hash_index_find(&PGG(notices), (zend_ulong)resource_id); + if (!notices) { + array_init(&tmp); + notices = &tmp; + zend_hash_index_update(&PGG(notices), (zend_ulong)resource_id, notices); + } + trimed_message = _php_pgsql_trim_message(message, &trimed_message_len); if (PGG(log_notices)) { - php_error_docref(NULL, E_NOTICE, "%s", notice->message); + php_error_docref(NULL, E_NOTICE, "%s", trimed_message); } - zend_hash_index_update_ptr(&PGG(notices), (zend_ulong)resource_id, notice); - } -} -/* }}} */ - -#define PHP_PGSQL_NOTICE_PTR_DTOR _php_pgsql_notice_ptr_dtor - -/* {{{ _php_pgsql_notice_dtor - */ -static void _php_pgsql_notice_ptr_dtor(zval *el) -{ - php_pgsql_notice *notice = (php_pgsql_notice *)Z_PTR_P(el); - if (notice) { - efree(notice->message); - efree(notice); + add_next_index_stringl(notices, trimed_message, trimed_message_len); + efree(trimed_message); } } /* }}} */ @@ -1096,7 +1091,7 @@ static PHP_GINIT_FUNCTION(pgsql) #endif memset(pgsql_globals, 0, sizeof(zend_pgsql_globals)); /* Initilize notice message hash at MINIT only */ - zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0); + zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1, 0); } /* }}} */ @@ -2306,15 +2301,16 @@ PHP_FUNCTION(pg_affected_rows) /* }}} */ #endif -/* {{{ proto string pg_last_notice(resource connection) +/* {{{ proto string pg_last_notice(resource connection [, bool all_notices]) Returns the last notice set by the backend */ PHP_FUNCTION(pg_last_notice) { zval *pgsql_link = NULL; + zval *notice, *notices; PGconn *pg_link; - php_pgsql_notice *notice; + zend_bool all_notices = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &pgsql_link, &all_notices) == FAILURE) { return; } @@ -2323,10 +2319,26 @@ PHP_FUNCTION(pg_last_notice) RETURN_FALSE; } - if ((notice = zend_hash_index_find_ptr(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link))) == NULL) { - 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) { + RETURN_EMPTY_STRING(); + } + RETURN_ZVAL(notice, 1, 0); + } else { + RETURN_EMPTY_STRING(); + } } - RETURN_STRINGL(notice->message, notice->len); } /* }}} */ diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt index db671016e3..c5f9b1df9e 100644 --- a/ext/pgsql/tests/09notice.phpt +++ b/ext/pgsql/tests/09notice.phpt @@ -9,35 +9,51 @@ _skip_lc_messages(); ?> --INI-- -pgsql.log_notice=1 -pgsql.ignore_notice=0 --FILE-- <?php include 'config.inc'; include 'lcmess.inc'; +ini_set('pgsql.log_notice', TRUE); +ini_set('pgsql.ignore_notice', FALSE); + $db = pg_connect($conn_str); _set_lc_messages(); -$res = pg_query($db, 'SET client_min_messages TO NOTICE;'); +$res = pg_query($db, 'SET client_min_messages TO NOTICE;'); var_dump($res); +// Get empty notice +var_dump(pg_last_notice($db)); +var_dump(pg_last_notice($db, TRUE)); + +pg_query($db, "BEGIN;"); +pg_query($db, "BEGIN;"); pg_query($db, "BEGIN;"); pg_query($db, "BEGIN;"); -$msg = pg_last_notice($db); -if ($msg === FALSE) { - echo "Cannot find notice message in hash\n"; - var_dump($msg); -} -echo $msg."\n"; -echo "pg_last_notice() is Ok\n"; - +// Get notices +var_dump(pg_last_notice($db)); +var_dump(pg_last_notice($db, TRUE)); ?> --EXPECTF-- resource(%d) of type (pgsql result) +string(0) "" +array(0) { +} + +Notice: pg_query(): %s already a transaction in progress in %s on line %d Notice: pg_query(): %s already a transaction in progress in %s on line %d -%s already a transaction in progress -pg_last_notice() is Ok + +Notice: pg_query(): %s already a transaction in progress in %s on line %d +string(52) "WARNING: there is already a transaction in progress" +array(3) { + [0]=> + string(52) "WARNING: there is already a transaction in progress" + [1]=> + string(52) "WARNING: there is already a transaction in progress" + [2]=> + string(52) "WARNING: there is already a transaction in progress" +} |