Patch pgsql_convert_boolean_and_integer_in_results for PostgreSQL related Bug #60187
Patch version 2012-01-27 03:34 UTC
Return to Bug #60187 |
Download this patch
Patch Revisions:
Developer: morphunreal@gmail.com
Index: pgsql.c
===================================================================
--- pgsql.c (revision 322837)
+++ pgsql.c (working copy)
@@ -73,7 +73,16 @@
RETURN_LONG((long)oid); \
} while(0)
+/* from postgresql/src/include/catalog/pg_type.h */
+#define PGSQL_OID_BOOL 16
+#define PGSQL_OID_BYTEA 17
+#define PGSQL_OID_INT8 20
+#define PGSQL_OID_INT2 21
+#define PGSQL_OID_INT4 23
+#define PGSQL_OID_TEXT 25
+#define PGSQL_OID_OID 26
+
#if HAVE_PQSETNONBLOCKING
#define PQ_SETNONBLOCKING(pg_link, flag) PQsetnonblocking(pg_link, flag)
#else
@@ -265,6 +274,7 @@
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)
@@ -910,6 +920,8 @@
STD_PHP_INI_BOOLEAN( "pgsql.auto_reset_persistent", "0", PHP_INI_SYSTEM, OnUpdateBool, auto_reset_persistent, zend_pgsql_globals, pgsql_globals)
STD_PHP_INI_BOOLEAN( "pgsql.ignore_notice", "0", PHP_INI_ALL, OnUpdateBool, ignore_notices, zend_pgsql_globals, pgsql_globals)
STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpdateBool, log_notices, zend_pgsql_globals, pgsql_globals)
+STD_PHP_INI_BOOLEAN( "pgsql.convert_boolean_type", "0", PHP_INI_ALL, OnUpdateBool, convert_boolean_type, zend_pgsql_globals, pgsql_globals)
+STD_PHP_INI_BOOLEAN( "pgsql.convert_integer_type", "0", PHP_INI_ALL, OnUpdateBool, convert_integer_type, zend_pgsql_globals, pgsql_globals)
PHP_INI_END()
/* }}} */
@@ -2498,27 +2510,51 @@
} else {
char *element = PQgetvalue(pgsql_result, pgsql_row, i);
if (element) {
+ Oid oid = PQftype(pgsql_result, i);
char *data;
int data_len;
int should_copy=0;
const uint element_len = strlen(element);
-
- if (PG(magic_quotes_runtime)) {
- data = php_addslashes(element, element_len, &data_len, 0 TSRMLS_CC);
+
+ if (oid == PGSQL_OID_BOOL && PGG(convert_boolean_type)){
+ int boolval = *element != 'f' ? 1 : 0;
+ if (result_type & PGSQL_NUM) {
+ add_index_bool(return_value, i, boolval);
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ field_name = PQfname(pgsql_result, i);
+ add_assoc_bool(return_value, field_name, boolval);
+ }
+ } else if ((oid == PGSQL_OID_INT2 || oid == PGSQL_OID_INT4 ||
+ (oid == PGSQL_OID_INT8 && sizeof(long)>=8)) && PGG(convert_integer_type)){
+ long int longval = atol(element);
+ if (result_type & PGSQL_NUM) {
+ add_index_long(return_value, i, longval);
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ field_name = PQfname(pgsql_result, i);
+ add_assoc_long(return_value, field_name, longval);
+ }
} else {
- data = safe_estrndup(element, element_len);
- data_len = element_len;
- }
-
- if (result_type & PGSQL_NUM) {
- add_index_stringl(return_value, i, data, data_len, should_copy);
- should_copy=1;
- }
-
- if (result_type & PGSQL_ASSOC) {
- field_name = PQfname(pgsql_result, i);
- add_assoc_stringl(return_value, field_name, data, data_len, should_copy);
- }
+ if (PG(magic_quotes_runtime)) {
+ data = php_addslashes(element, element_len, &data_len, 0 TSRMLS_CC);
+ } else {
+ data = safe_estrndup(element, element_len);
+ data_len = element_len;
+ }
+
+ if (result_type & PGSQL_NUM) {
+ add_index_stringl(return_value, i, data, data_len, should_copy);
+ should_copy=1;
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ field_name = PQfname(pgsql_result, i);
+ add_assoc_stringl(return_value, field_name, data, data_len, should_copy);
+ }
+ }
}
}
}
@@ -2628,15 +2664,17 @@
}
/* }}} */
-/* {{{ 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;
PGresult *pgsql_result;
pgsql_result_handle *pg_result;
+ long result_type = PGSQL_ASSOC;
+
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &result_type) == FAILURE) {
return;
}
@@ -2644,7 +2682,7 @@
pgsql_result = pg_result->result;
array_init(return_value);
- if (php_pgsql_result2array(pgsql_result, return_value TSRMLS_CC) == FAILURE) {
+ if (php_pgsql_result2array(pgsql_result, result_type, return_value TSRMLS_CC) == FAILURE) {
zval_dtor(return_value);
RETURN_FALSE;
}
@@ -6206,11 +6244,12 @@
/* {{{ php_pgsql_result2array
*/
-PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC)
+PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, long result_type, zval *ret_array TSRMLS_DC)
{
zval *row;
- char *field_name;
- size_t num_fields;
+ char **field_names;
+ Oid *field_types;
+ int num_fields;
int pg_numrows, pg_row;
uint i;
assert(Z_TYPE_P(ret_array) == IS_ARRAY);
@@ -6218,29 +6257,75 @@
if ((pg_numrows = PQntuples(pg_result)) <= 0) {
return FAILURE;
}
+ num_fields = PQnfields(pg_result);
+ if (result_type & PGSQL_ASSOC){
+ field_names = ecalloc(num_fields, sizeof*field_names);
+ for(i = 0; i < num_fields; i++){
+ field_names[i] = PQfname(pg_result, i);
+ }
+ }
+ if (PGG(convert_boolean_type) || PGG(convert_integer_type)){
+ field_types = ecalloc(num_fields, sizeof field_types);
+ for (i = 0; i < num_fields; i++){
+ field_types[i] = PQftype(pg_result, i);
+ }
+ }
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
MAKE_STD_ZVAL(row);
array_init(row);
add_index_zval(ret_array, pg_row, row);
- for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
+ for (i = 0; i < num_fields; i++) {
if (PQgetisnull(pg_result, pg_row, i)) {
- field_name = PQfname(pg_result, i);
- add_assoc_null(row, field_name);
+ if (result_type & PGSQL_NUM) {
+ add_index_null(row, i);
+ }
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_null(row, field_names[i]);
+ }
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
char *data;
- size_t data_len;
- const size_t element_len = strlen(element);
-
- if (PG(magic_quotes_runtime)) {
- data = php_addslashes(element, element_len, &data_len, 0 TSRMLS_CC);
+ int data_len;
+ int should_copy=0;
+ const uint element_len = strlen(element);
+
+ if (field_types[i] == PGSQL_OID_BOOL && PGG(convert_boolean_type)){
+ int boolval = *element != 'f' ? 1 : 0;
+ if (result_type & PGSQL_NUM) {
+ add_index_bool(row, i, boolval);
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_bool(row, field_names[i], boolval);
+ }
+ } else if ((field_types[i] == PGSQL_OID_INT2 || field_types[i] == PGSQL_OID_INT4 ||
+ (field_types[i] == PGSQL_OID_INT8 && sizeof(long)>=8)) && PGG(convert_integer_type)){
+ long int longval = atol(element);
+ if (result_type & PGSQL_NUM) {
+ add_index_long(row, i, longval);
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_long(row, field_names[i], longval);
+ }
} else {
- data = safe_estrndup(element, element_len);
- data_len = element_len;
+ if (PG(magic_quotes_runtime)) {
+ data = php_addslashes(element, element_len, &data_len, 0 TSRMLS_CC);
+ } else {
+ data = safe_estrndup(element, element_len);
+ data_len = element_len;
+ }
+
+ if (result_type & PGSQL_NUM) {
+ add_index_stringl(row, i, data, data_len, should_copy);
+ should_copy=1;
+ }
+
+ if (result_type & PGSQL_ASSOC) {
+ add_assoc_stringl(row, field_names[i], data, data_len, should_copy);
+ }
}
- field_name = PQfname(pg_result, i);
- add_assoc_stringl(row, field_name, data, data_len, 0);
}
}
}
@@ -6289,7 +6374,7 @@
pg_result = PQexec(pg_link, querystr.c);
if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
- ret = php_pgsql_result2array(pg_result, ret_array TSRMLS_CC);
+ ret = php_pgsql_result2array(pg_result, PGSQL_ASSOC, ret_array TSRMLS_CC);
} else {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed to execute '%s'", querystr.c);
}
Index: php_pgsql.h
===================================================================
--- php_pgsql.h (revision 322837)
+++ php_pgsql.h (working copy)
@@ -202,7 +202,7 @@
PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, ulong opt , char **sql TSRMLS_DC);
PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, ulong opt, char **sql TSRMLS_DC);
PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, ulong opt, char **sql TSRMLS_DC);
-PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array TSRMLS_DC);
+PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, long result_type, zval *ret_array TSRMLS_DC);
/* internal functions */
static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);
@@ -284,6 +284,7 @@
int le_lofp,le_string;
int ignore_notices,log_notices;
HashTable notices; /* notice message for each connection */
+ int convert_boolean_type, convert_integer_type;
ZEND_END_MODULE_GLOBALS(pgsql)
ZEND_EXTERN_MODULE_GLOBALS(pgsql)
|