From 57d9da879043a2f5fc5f29cb469de8bbbf23f26f Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 17 Dec 2015 07:27:34 +0900 Subject: Implemented FR #31021 (pg_result_notice() is needed to get all notice messages). --- ext/pgsql/pgsql.c | 64 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'ext/pgsql/pgsql.c') 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); } /* }}} */ -- cgit v1.2.1