]> granicus.if.org Git - php/commitdiff
Implemented FR #31021 (pg_result_notice() is needed to get all notice messages).
authorYasuo Ohgaki <yohgaki@php.net>
Wed, 16 Dec 2015 22:27:34 +0000 (07:27 +0900)
committerYasuo Ohgaki <yohgaki@php.net>
Wed, 16 Dec 2015 22:31:19 +0000 (07:31 +0900)
NEWS
UPGRADING
ext/pgsql/pgsql.c
ext/pgsql/tests/09notice.phpt

diff --git a/NEWS b/NEWS
index 3c93334f67d45c8593354377df8e597c9e5dcb44..31bca55bb020bbcc1b9454693b21a709cff0de22 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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)
index 5c069f14f20dac9332d48ba1b83027ba571640c5..340859a0306636a242881289bca1fd660ef331f6 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -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
index e8e5a536f7407bfbd191364aca71f399a18056d7..1822867e42dfb10941265c0fafebc15a754ebb10 100644 (file)
@@ -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, &notice->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);
 }
 /* }}} */
 
index db671016e3b559341b50c6cc11a7a34fbae153e9..c5f9b1df9e0316ae7096eed832bc3a65fabfaccb 100644 (file)
@@ -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"
+}