summaryrefslogtreecommitdiff
path: root/ext/pgsql/pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pgsql/pgsql.c')
-rw-r--r--ext/pgsql/pgsql.c222
1 files changed, 135 insertions, 87 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index b215697ca9..904b9aa3bf 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2017 The PHP Group |
+ | Copyright (c) 1997-2018 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -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,6 +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, option)
ZEND_END_ARG_INFO()
#ifdef HAVE_PQFTABLE
@@ -276,6 +281,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
ZEND_ARG_INFO(0, result)
+ ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
@@ -582,6 +588,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_select, 0, 0, 3)
ZEND_ARG_INFO(0, table)
ZEND_ARG_INFO(0, ids)
ZEND_ARG_INFO(0, options)
+ ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO()
/* }}} */
@@ -961,29 +968,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 +1098,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);
}
/* }}} */
@@ -1123,6 +1125,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);
@@ -1337,12 +1343,12 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) {
php_error_docref(NULL, E_WARNING,
- "Cannot create new link. Too many open links (%pd)", PGG(num_links));
+ "Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links));
goto err;
}
if (PGG(max_persistent) != -1 && PGG(num_persistent) >= PGG(max_persistent)) {
php_error_docref(NULL, E_WARNING,
- "Cannot create new link. Too many open persistent links (%pd)", PGG(num_persistent));
+ "Cannot create new link. Too many open persistent links (" ZEND_LONG_FMT ")", PGG(num_persistent));
goto err;
}
@@ -1435,7 +1441,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
}
}
if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) {
- php_error_docref(NULL, E_WARNING, "Cannot create new link. Too many open links (%pd)", PGG(num_links));
+ php_error_docref(NULL, E_WARNING, "Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links));
goto err;
}
@@ -1653,26 +1659,21 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type
/* 8.0 or grater supports protorol version 3 */
char *tmp;
add_assoc_string(return_value, "server", (char*)PQparameterStatus(pgsql, "server_version"));
- tmp = (char*)PQparameterStatus(pgsql, "server_encoding");
- add_assoc_string(return_value, "server_encoding", tmp);
- tmp = (char*)PQparameterStatus(pgsql, "client_encoding");
- add_assoc_string(return_value, "client_encoding", tmp);
- tmp = (char*)PQparameterStatus(pgsql, "is_superuser");
- add_assoc_string(return_value, "is_superuser", tmp);
- tmp = (char*)PQparameterStatus(pgsql, "session_authorization");
- add_assoc_string(return_value, "session_authorization", tmp);
- tmp = (char*)PQparameterStatus(pgsql, "DateStyle");
- add_assoc_string(return_value, "DateStyle", tmp);
- tmp = (char*)PQparameterStatus(pgsql, "IntervalStyle");
- add_assoc_string(return_value, "IntervalStyle", tmp ? tmp : "");
- tmp = (char*)PQparameterStatus(pgsql, "TimeZone");
- add_assoc_string(return_value, "TimeZone", tmp ? tmp : "");
- tmp = (char*)PQparameterStatus(pgsql, "integer_datetimes");
- add_assoc_string(return_value, "integer_datetimes", tmp ? tmp : "");
- tmp = (char*)PQparameterStatus(pgsql, "standard_conforming_strings");
- add_assoc_string(return_value, "standard_conforming_strings", tmp ? tmp : "");
- tmp = (char*)PQparameterStatus(pgsql, "application_name");
- add_assoc_string(return_value, "application_name", tmp ? tmp : "");
+
+#define PHP_PQ_COPY_PARAM(_x) tmp = (char*)PQparameterStatus(pgsql, _x); \
+ if(tmp) add_assoc_string(return_value, _x, tmp); \
+ else add_assoc_null(return_value, _x);
+
+ PHP_PQ_COPY_PARAM("server_encoding");
+ PHP_PQ_COPY_PARAM("client_encoding");
+ PHP_PQ_COPY_PARAM("is_superuser");
+ PHP_PQ_COPY_PARAM("session_authorization");
+ PHP_PQ_COPY_PARAM("DateStyle");
+ PHP_PQ_COPY_PARAM("IntervalStyle");
+ PHP_PQ_COPY_PARAM("TimeZone");
+ PHP_PQ_COPY_PARAM("integer_datetimes");
+ PHP_PQ_COPY_PARAM("standard_conforming_strings");
+ PHP_PQ_COPY_PARAM("application_name");
}
#endif
#endif
@@ -2308,15 +2309,16 @@ PHP_FUNCTION(pg_affected_rows)
/* }}} */
#endif
-/* {{{ proto string pg_last_notice(resource connection)
+/* {{{ 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;
- php_pgsql_notice *notice;
+ zend_long option = PGSQL_NOTICE_LAST;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_link, &option) == FAILURE) {
return;
}
@@ -2325,10 +2327,38 @@ 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;
+ notices = zend_hash_index_find(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link));
+ 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();
+ }
+ 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 (" ZEND_LONG_FMT ")", option);
}
- RETURN_STRINGL(notice->message, notice->len);
+ RETURN_FALSE;
}
/* }}} */
@@ -2641,7 +2671,7 @@ PHP_FUNCTION(pg_fetch_result)
}
} else {
if (row < 0 || row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd",
+ php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT,
row, Z_LVAL_P(result));
RETURN_FALSE;
}
@@ -2732,7 +2762,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
if (use_row) {
if (row < 0 || row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd",
+ php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT,
row, Z_LVAL_P(result));
RETURN_FALSE;
}
@@ -2791,9 +2821,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
if (ce->constructor) {
fci.size = sizeof(fci);
- fci.function_table = &ce->function_table;
ZVAL_UNDEF(&fci.function_name);
- fci.symbol_table = NULL;
fci.object = Z_OBJ_P(return_value);
fci.retval = &retval;
fci.params = NULL;
@@ -2815,12 +2843,12 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
fcc.initialized = 1;
fcc.function_handler = ce->constructor;
- fcc.calling_scope = EG(scope);
+ fcc.calling_scope = zend_get_executed_scope();
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object = Z_OBJ_P(return_value);
if (zend_call_function(&fci, &fcc) == FAILURE) {
- zend_throw_exception_ex(zend_ce_exception, 0, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
+ zend_throw_exception_ex(zend_ce_exception, 0, "Could not execute %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
} else {
zval_ptr_dtor(&retval);
}
@@ -2828,7 +2856,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
efree(fci.params);
}
} else if (ctor_params) {
- zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
+ zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name));
}
}
}
@@ -2872,25 +2900,31 @@ PHP_FUNCTION(pg_fetch_object)
}
/* }}} */
-/* {{{ proto array pg_fetch_all(resource result)
+/* {{{ proto array pg_fetch_all(resource result [, int result_type])
Fetch all rows into array */
PHP_FUNCTION(pg_fetch_all)
{
zval *result;
+ long result_type = PGSQL_ASSOC;
PGresult *pgsql_result;
pgsql_result_handle *pg_result;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &result, &result_type) == FAILURE) {
return;
}
+ if (!(result_type & PGSQL_BOTH)) {
+ php_error_docref(NULL, E_WARNING, "Invalid result type");
+ RETURN_FALSE;
+ }
+
if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) {
RETURN_FALSE;
}
pgsql_result = pg_result->result;
array_init(return_value);
- if (php_pgsql_result2array(pgsql_result, return_value) == FAILURE) {
+ if (php_pgsql_result2array(pgsql_result, return_value, result_type) == FAILURE) {
zval_dtor(return_value);
RETURN_FALSE;
}
@@ -2920,7 +2954,7 @@ PHP_FUNCTION(pg_fetch_all_columns)
num_fields = PQnfields(pgsql_result);
if (colno >= (zend_long)num_fields || colno < 0) {
- php_error_docref(NULL, E_WARNING, "Invalid column number '%pd'", colno);
+ php_error_docref(NULL, E_WARNING, "Invalid column number '" ZEND_LONG_FMT "'", colno);
RETURN_FALSE;
}
@@ -3004,7 +3038,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
}
} else {
if (row < 0 || row >= PQntuples(pgsql_result)) {
- php_error_docref(NULL, E_WARNING, "Unable to jump to row %pd on PostgreSQL result index %pd",
+ php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT,
row, Z_LVAL_P(result));
RETURN_FALSE;
}
@@ -3289,7 +3323,7 @@ PHP_FUNCTION(pg_lo_unlink)
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"rl", &pgsql_link, &oid_long) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -3309,7 +3343,7 @@ PHP_FUNCTION(pg_lo_unlink)
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"l", &oid_long) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID is specified");
RETURN_FALSE;
}
@@ -3363,7 +3397,7 @@ PHP_FUNCTION(pg_lo_open)
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"rls", &pgsql_link, &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -3383,7 +3417,7 @@ PHP_FUNCTION(pg_lo_open)
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"ls", &oid_long, &mode_string, &mode_strlen) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -3538,11 +3572,11 @@ PHP_FUNCTION(pg_lo_write)
if (argc > 2) {
if (z_len > (zend_long)str_len) {
- php_error_docref(NULL, E_WARNING, "Cannot write more than buffer size %d. Tried to write %pd", str_len, z_len);
+ php_error_docref(NULL, E_WARNING, "Cannot write more than buffer size %d. Tried to write " ZEND_LONG_FMT, str_len, z_len);
RETURN_FALSE;
}
if (z_len < 0) {
- php_error_docref(NULL, E_WARNING, "Buffer size must be larger than 0, but %pd was specified", z_len);
+ php_error_docref(NULL, E_WARNING, "Buffer size must be larger than 0, but " ZEND_LONG_FMT " was specified", z_len);
RETURN_FALSE;
}
len = z_len;
@@ -3555,7 +3589,7 @@ PHP_FUNCTION(pg_lo_write)
RETURN_FALSE;
}
- if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, str, len)) == -1) {
+ if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, str, len)) == (size_t)-1) {
RETURN_FALSE;
}
@@ -3694,7 +3728,7 @@ PHP_FUNCTION(pg_lo_export)
/* allow string to handle large OID value correctly */
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"rlp", &pgsql_link, &oid_long, &file_out, &name_len) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -3713,7 +3747,7 @@ PHP_FUNCTION(pg_lo_export)
}
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"lp", &oid_long, &file_out, &name_len) == SUCCESS) {
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -3745,7 +3779,7 @@ PHP_FUNCTION(pg_lo_export)
else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc,
"lpr", &oid_long, &file_out, &name_len, &pgsql_link) == SUCCESS) {
php_error_docref(NULL, E_NOTICE, "Old API is used");
- if (oid_long <= InvalidOid) {
+ if (oid_long <= (zend_long)InvalidOid) {
php_error_docref(NULL, E_NOTICE, "Invalid OID specified");
RETURN_FALSE;
}
@@ -4408,6 +4442,7 @@ PHP_FUNCTION(pg_escape_bytea)
to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len);
RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */
+ PQfreemem(to);
}
/* }}} */
@@ -6485,7 +6520,7 @@ PHP_FUNCTION(pg_convert)
}
/* }}} */
-static int do_exec(smart_str *querystr, int expect, PGconn *pg_link, zend_ulong opt) /* {{{ */
+static int do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link, zend_ulong opt) /* {{{ */
{
if (opt & PGSQL_DML_ASYNC) {
if (PQsendQuery(pg_link, ZSTR_VAL(querystr->s))) {
@@ -7010,7 +7045,7 @@ PHP_FUNCTION(pg_delete)
/* {{{ php_pgsql_result2array
*/
-PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array)
+PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, long result_type)
{
zval row;
char *field_name;
@@ -7025,16 +7060,24 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array)
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
array_init(&row);
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
+ field_name = PQfname(pg_result, i);
if (PQgetisnull(pg_result, pg_row, i)) {
- field_name = PQfname(pg_result, i);
- add_assoc_null(&row, field_name);
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_null(&row, field_name);
+ }
+ if (result_type & PGSQL_NUM) {
+ add_next_index_null(&row);
+ }
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
const size_t element_len = strlen(element);
-
- field_name = PQfname(pg_result, i);
- add_assoc_stringl(&row, field_name, element, element_len);
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_stringl(&row, field_name, element, element_len);
+ }
+ if (result_type & PGSQL_NUM) {
+ add_next_index_stringl(&row, element, element_len);
+ }
}
}
}
@@ -7046,7 +7089,7 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array)
/* {{{ php_pgsql_select
*/
-PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_ulong opt, zend_string **sql)
+ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids_array, zval *ret_array, zend_ulong opt, long result_type, zend_string **sql)
{
zval ids_converted;
smart_str querystr = {0};
@@ -7084,7 +7127,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids
pg_result = PQexec(pg_link, ZSTR_VAL(querystr.s));
if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
- ret = php_pgsql_result2array(pg_result, ret_array);
+ ret = php_pgsql_result2array(pg_result, ret_array, result_type);
} else {
php_error_docref(NULL, E_NOTICE, "Failed to execute '%s'", ZSTR_VAL(querystr.s));
}
@@ -7102,7 +7145,7 @@ cleanup:
}
/* }}} */
-/* {{{ proto mixed pg_select(resource db, string table, array ids[, int options])
+/* {{{ proto mixed pg_select(resource db, string table, array ids[, int options [, int result_type])
Select records that has ids (id=>value) */
PHP_FUNCTION(pg_select)
{
@@ -7110,18 +7153,23 @@ PHP_FUNCTION(pg_select)
char *table;
size_t table_len;
zend_ulong option = PGSQL_DML_EXEC;
+ long result_type = PGSQL_ASSOC;
PGconn *pg_link;
zend_string *sql = NULL;
int argc = ZEND_NUM_ARGS();
if (zend_parse_parameters(argc, "rsa|l",
- &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) {
+ &pgsql_link, &table, &table_len, &ids, &option, &result_type) == FAILURE) {
return;
}
if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) {
php_error_docref(NULL, E_WARNING, "Invalid option is specified");
RETURN_FALSE;
}
+ if (!(result_type & PGSQL_BOTH)) {
+ php_error_docref(NULL, E_WARNING, "Invalid result type");
+ RETURN_FALSE;
+ }
if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) {
RETURN_FALSE;
@@ -7131,7 +7179,7 @@ PHP_FUNCTION(pg_select)
php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection");
}
array_init(return_value);
- if (php_pgsql_select(pg_link, table, ids, return_value, option, &sql) == FAILURE) {
+ if (php_pgsql_select(pg_link, table, ids, return_value, option, result_type, &sql) == FAILURE) {
zval_ptr_dtor(return_value);
RETURN_FALSE;
}