php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

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)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 00:01:30 2024 UTC