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

Patch bug45259_sqlite-bind-params-autodetect for PDO related Bug #45259

Patch version 2010-12-19 12:46 UTC

Return to Bug #45259 | Download this patch
Patch Revisions:

Developer: sl9@gmx.net

Index: ext/pdo_sqlite/sqlite_statement.c
===================================================================
--- ext/pdo_sqlite/sqlite_statement.c	(revision 306430)
+++ ext/pdo_sqlite/sqlite_statement.c	(working copy)
@@ -78,6 +78,8 @@
 static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
 		enum pdo_param_event event_type TSRMLS_DC)
 {
+	int hookResult = 0; // failure
+
 	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
 
 	switch (event_type) {
@@ -86,39 +88,97 @@
 				sqlite3_reset(S->stmt);
 				S->done = 1;
 			}
-			
+
 			if (param->is_param) {
-				
 				if (param->paramno == -1) {
 					param->paramno = sqlite3_bind_parameter_index(S->stmt, param->name) - 1;
 				}
 
+				if(PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_ZVAL){
+					// XXX: User didn't specify a PDO_PARAM_* value, so let's do autodetect using the ZVAL type
+					switch(Z_TYPE_P(param->parameter)){
+						case IS_STRING:
+							param->param_type = PDO_PARAM_STR;
+						break;
+						case IS_LONG:
+							param->param_type = PDO_PARAM_INT;
+						break;
+						case IS_NULL:
+							param->param_type = PDO_PARAM_NULL;
+						break;
+						case IS_BOOL:
+							param->param_type = PDO_PARAM_BOOL;
+						break;
+						case IS_DOUBLE:
+							param->param_type = PDO_PARAM_INT;
+						break;
+						case IS_RESOURCE:
+							param->param_type = PDO_PARAM_LOB;
+						break;
+						default:
+							pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Invalid parameter type" TSRMLS_CC);
+					}
+				}
+
 				switch (PDO_PARAM_TYPE(param->param_type)) {
 					case PDO_PARAM_STMT:
-						return 0;
-
+						pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Invalid parameter type" TSRMLS_CC);
+					break;
 					case PDO_PARAM_NULL:
-						if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
-							return 1;
+						if(sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
+							hookResult = 1; // success
+						}else{
+							pdo_sqlite_error_stmt(stmt);
 						}
-						pdo_sqlite_error_stmt(stmt);
-						return 0;
-					
+					break;
 					case PDO_PARAM_INT:
-					case PDO_PARAM_BOOL:
-						if (Z_TYPE_P(param->parameter) == IS_NULL) {
+						if (Z_TYPE_P(param->parameter) == IS_LONG) {
+							// no conversion
+						}else if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
+							if (sqlite3_bind_double(S->stmt, param->paramno + 1, Z_DVAL_P(param->parameter)) == SQLITE_OK) {
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
+							}
+						}else if (Z_TYPE_P(param->parameter) == IS_NULL) {
 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
-								return 1;
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
 							}
-						} else {
+						}else{
 							convert_to_long(param->parameter);
-							if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter))) {
-								return 1;
+						}
+
+						if (Z_TYPE_P(param->parameter) == IS_LONG) {
+							if (sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter)) == SQLITE_OK) {
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
 							}
 						}
-						pdo_sqlite_error_stmt(stmt);
-						return 0;
-					
+					break;
+					case PDO_PARAM_BOOL:
+						if (Z_TYPE_P(param->parameter) == IS_BOOL) {
+							// no conversion
+						}else if (Z_TYPE_P(param->parameter) == IS_NULL) {
+							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
+							}
+						}else{
+							convert_to_boolean(param->parameter);
+						}
+
+						if (Z_TYPE_P(param->parameter) == IS_BOOL) {
+							if (sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter)) == SQLITE_OK) {
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
+							}
+						}
+					break;
 					case PDO_PARAM_LOB:
 						if (Z_TYPE_P(param->parameter) == IS_RESOURCE) {
 							php_stream *stm;
@@ -128,54 +188,70 @@
 								Z_TYPE_P(param->parameter) = IS_STRING;
 								Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
 									&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
-							} else {
+							}else{
 								pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
-								return 0;
 							}
 						} else if (Z_TYPE_P(param->parameter) == IS_NULL) {
 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
-								return 1;
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
 							}
-							pdo_sqlite_error_stmt(stmt);
-							return 0;
 						} else {
 							convert_to_string(param->parameter);
+							if(
+								sqlite3_bind_blob(
+									S->stmt, param->paramno + 1,
+									Z_STRVAL_P(param->parameter),
+									Z_STRLEN_P(param->parameter),
+									SQLITE_STATIC
+								) == SQLITE_OK
+							){
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
+							}
 						}
-						
-						if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
-								Z_STRVAL_P(param->parameter),
-								Z_STRLEN_P(param->parameter),
-								SQLITE_STATIC)) {
-							return 1;	
-						}
-						pdo_sqlite_error_stmt(stmt);
-						return 0;
-							
+					break;
+
 					case PDO_PARAM_STR:
 					default:
-						if (Z_TYPE_P(param->parameter) == IS_NULL) {
+						if (Z_TYPE_P(param->parameter) == IS_STRING) {
+							// no conversion
+						} else if (Z_TYPE_P(param->parameter) == IS_NULL) {
 							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
-								return 1;
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
 							}
 						} else {
 							convert_to_string(param->parameter);
-							if(SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
+						}
+
+						if(Z_TYPE_P(param->parameter) == IS_STRING){
+							if(
+								sqlite3_bind_text(
+									S->stmt, param->paramno + 1,
 									Z_STRVAL_P(param->parameter),
 									Z_STRLEN_P(param->parameter),
-									SQLITE_STATIC)) {
-								return 1;	
+									SQLITE_STATIC
+								) == SQLITE_OK
+							){
+								hookResult = 1; // success
+							}else{
+								pdo_sqlite_error_stmt(stmt);
 							}
 						}
-						pdo_sqlite_error_stmt(stmt);
-						return 0;
+					break;
 				}
+			}else{
+				hookResult = 1; // success
 			}
-			break;
-
+		break;
 		default:
-			;
+			hookResult = 1; // success
 	}
-	return 1;
+	return hookResult;
 }
 
 static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
Index: ext/pdo/pdo_stmt.c
===================================================================
--- ext/pdo/pdo_stmt.c	(revision 306430)
+++ ext/pdo/pdo_stmt.c	(working copy)
@@ -468,6 +468,13 @@
 			}
 
 			param.param_type = PDO_PARAM_STR;
+			if(strcmp(stmt->dbh->driver->driver_name, "sqlite") == 0){
+				// Sqlite does own mapping of zvals to pdo params now.
+				// Setting param type to a constant to signal that no explicit type was set
+				// gives the driver the opportunity to autodetect the type from the zval itself
+				param.param_type = PDO_PARAM_ZVAL;
+			}
+
 			MAKE_STD_ZVAL(param.parameter);
 			MAKE_COPY_ZVAL(tmp, param.parameter);
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 20:01:29 2024 UTC