php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #60703
Patch php-5.3.10-cursor-support-for-pdo_oci.patch revision 2012-03-20 10:19 UTC by psrustik at yandex dot ru
Patch php-5.3.8-cursor-support-for-pdo_oci.patch revision 2012-01-12 22:41 UTC by marcos dot ramirez dot aranda at gmail dot com
revision 2012-01-10 19:56 UTC by marcos dot ramirez dot aranda at gmail dot com

Patch php-5.3.8-cursor-support-for-pdo_oci.patch for PDO OCI Bug #60703

Patch version 2012-01-12 22:41 UTC

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

Developer: marcos.ramirez.aranda@gmail.com

diff -rubB php-5.3.8.old/ext/pdo_oci/oci_statement.c php-5.3.8/ext/pdo_oci/oci_statement.c
--- php-5.3.8.old/ext/pdo_oci/oci_statement.c	2010-12-31 23:19:59.000000000 -0300
+++ php-5.3.8/ext/pdo_oci/oci_statement.c	2012-01-12 19:14:45.877022497 -0300
@@ -97,6 +97,7 @@
 		for (i = 0; i < stmt->column_count; i++) {
 			if (S->cols[i].data) {
 				switch (S->cols[i].dtype) {
+					case SQLT_RSET:
 					case SQLT_BLOB:
 					case SQLT_CLOB:
 						/* do nothing */
@@ -184,6 +185,56 @@
 	return 1;
 } /* }}} */
 
+static int oci_describe_rset_object(pdo_stmt_t *stmt) {
+	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
+	ub4 colcount;
+	ub4 rowcount = 0;
+	
+	if (!S->stmt_type) {
+		STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_STMT_TYPE",
+					  (S->stmt, OCI_HTYPE_STMT, &S->stmt_type, 0, OCI_ATTR_STMT_TYPE, S->err));
+	}
+
+	/* how many columns do we have ? */
+	STMT_CALL_MSG(OCIAttrGet, "ATTR_PARAM_COUNT",
+				  (S->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));
+	stmt->column_count = (int)colcount;			
+	stmt->executed = 1;
+	stmt->row_count = 0; 
+	S->cols = ecalloc(colcount, sizeof(pdo_oci_column));
+	pdo_stmt_describe_columns(stmt);
+}
+
+static zval *oci_create_rset_object(pdo_stmt_t *p_stmt) {
+	pdo_oci_stmt *S = ecalloc(1, sizeof(pdo_oci_stmt));
+	zval *zv;
+	pdo_stmt_t *stmt;
+
+	MAKE_STD_ZVAL(zv);
+	object_init_ex(zv, p_stmt->ce);
+
+	S->exec_type = OCI_DEFAULT;   
+	S->H = ((pdo_oci_stmt*)p_stmt->driver_data)->H;
+	S->err = NULL;
+	S->last_err = 0;
+
+	stmt = (pdo_stmt_t*)zend_object_store_get_object(zv);
+	stmt->dbh = p_stmt->dbh;
+	stmt->supports_placeholders = PDO_PLACEHOLDER_NAMED;
+	
+	stmt->driver_data = S;
+	stmt->methods = &oci_stmt_methods;
+	stmt->database_object_handle = p_stmt->database_object_handle;
+	stmt->executed = 0;
+
+	
+	/* create our own private error handle */
+	STMT_CALL(OCIHandleAlloc,(S->H->env, (dvoid*)&S->err, OCI_HTYPE_ERROR, 0, NULL));
+
+	php_pdo_dbh_addref(p_stmt->dbh);
+	return zv;
+}
+
 static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp) /* {{{ */
 {
 	struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
@@ -235,6 +286,14 @@
 		*rcodepp = &P->retcode;
 		*indpp = &P->indicator;
 		return OCI_CONTINUE;
+	} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT) {
+		P->actual_len = sizeof(OCIStmt*);		
+		*bufpp = P->thing;
+		*alenpp = &P->actual_len;
+		*piecep = OCI_ONE_PIECE;
+		*rcodepp = &P->retcode;
+		*indpp = &P->indicator;
+		return OCI_CONTINUE;		
 	}
 
 	if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
@@ -284,7 +343,9 @@
 				/* figure out what we're doing */
 				switch (PDO_PARAM_TYPE(param->param_type)) {
 					case PDO_PARAM_STMT:
-						return 0;
+						P->oci_type = SQLT_RSET;
+						value_sz = sizeof(OCIStmt*);
+						break;
 
 					case PDO_PARAM_LOB:
 						/* P->thing is now an OCILobLocator * */
@@ -331,7 +392,16 @@
 					STMT_CALL(OCIDescriptorAlloc, (S->H->env, &P->thing, OCI_DTYPE_LOB, 0, NULL));
 					STMT_CALL(OCIAttrSet, (P->thing, OCI_DTYPE_LOB, &empty, 0, OCI_ATTR_LOBEMPTY, S->err));
 					S->have_blobs = 1;
+				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT) {
+					zval *zv = oci_create_rset_object(stmt);
+					pdo_stmt_t *pstmt = (pdo_stmt_t*)zend_object_store_get_object(zv);
+					pdo_oci_stmt *PS = (pdo_oci_stmt *)pstmt->driver_data;
+					// Allocate STMT
+					OCIHandleAlloc(PS->H->env, (dvoid*)&PS->stmt, OCI_HTYPE_STMT, 0, NULL);
+					P->thing = PS->stmt;
+					P->zv_rset = zv;
 				}
+
 				return 1;
 
 			case PDO_PARAM_EVT_EXEC_POST:
@@ -358,6 +428,10 @@
 						Z_STRVAL_P(param->parameter) = erealloc(Z_STRVAL_P(param->parameter), P->actual_len+1);
 						Z_STRVAL_P(param->parameter)[P->actual_len] = '\0';
 					}
+				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT && P->thing) {
+					pdo_stmt_t *rset_stmt = (pdo_stmt_t*)zend_object_store_get_object(P->zv_rset);
+					oci_describe_rset_object(rset_stmt);
+					ZVAL_ZVAL(param->parameter, P->zv_rset, 0, 1);
 				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
 					php_stream *stm;
 
@@ -478,6 +552,16 @@
 	TSRMLS_FETCH();
 
 	switch (col->dtype) {
+		case SQLT_RSET: {
+			pdo_stmt_t *stmt = (pdo_stmt_t*)col->stmt;
+			pdo_oci_stmt *S = (pdo_oci_stmt *)stmt->driver_data;
+			OCIHandleAlloc(S->H->env, (dvoid *)&col->data, OCI_HTYPE_STMT, 0, NULL);
+			*bufpp = col->data;
+			*piecep = OCI_ONE_PIECE;
+			*alenpp = &col->datalen;
+			*indpp = (dvoid *)&col->indicator;
+			break ;
+		}
 		case SQLT_BLOB:
 		case SQLT_CLOB:
 			*piecep = OCI_ONE_PIECE;
@@ -537,6 +621,13 @@
 
 	/* how much room do we need to store the field */
 	switch (dtype) {
+	case SQLT_RSET:
+		col->param_type = PDO_PARAM_STMT;
+		dyn = TRUE;
+		S->cols[colno].stmt = stmt;
+		S->cols[colno].datalen = sizeof(OCIStmt*);
+		break;
+
 		case SQLT_LBI:
 		case SQLT_LNG:
 			if (dtype == SQLT_LBI) {
@@ -654,7 +745,7 @@
 
 	if (close_handle) {
 		OCILobClose(self->S->H->svc, self->S->err, self->lob);
-		OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
+		// OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
 		efree(self);
 	}
 
@@ -734,8 +825,17 @@
 			}
 			*len = 0;
 			return *ptr ? 1 : 0;
-		}
+		} else if (C->dtype == SQLT_RSET) {
+			zval *zv = oci_create_rset_object(stmt);
+			pdo_stmt_t *cstmt = (pdo_stmt_t*)zend_object_store_get_object(zv);
+			pdo_oci_stmt *CS = (pdo_oci_stmt *)cstmt->driver_data;
+			CS->stmt = (OCIStmt *)C->data;
+			oci_describe_rset_object(cstmt);
 
+			*ptr = (char *)zv;
+			*len = C->fetched_len;
+			return 1;
+		}
 		*ptr = C->data;
 		*len = C->fetched_len;
 		return 1;
diff -rubB php-5.3.8.old/ext/pdo_oci/php_pdo_oci_int.h php-5.3.8/ext/pdo_oci/php_pdo_oci_int.h
--- php-5.3.8.old/ext/pdo_oci/php_pdo_oci_int.h	2010-12-31 23:19:59.000000000 -0300
+++ php-5.3.8/ext/pdo_oci/php_pdo_oci_int.h	2012-01-12 19:14:45.878023745 -0300
@@ -55,6 +55,7 @@
 
 	ub2 dtype;
 
+  	pdo_stmt_t *stmt;
 } pdo_oci_column;
 
 typedef struct {
@@ -80,6 +81,7 @@
 	dvoid		*thing;	/* for LOBS, REFCURSORS etc. */
 
 	unsigned used_for_output;
+  	zval *zv_rset;
 } pdo_oci_bound_param;
 
 extern const ub4 PDO_OCI_INIT_MODE;
diff -rubB php-5.3.8.old/ext/pdo/pdo_stmt.c php-5.3.8/ext/pdo/pdo_stmt.c
--- php-5.3.8.old/ext/pdo/pdo_stmt.c	2011-06-18 11:56:14.000000000 -0400
+++ php-5.3.8/ext/pdo/pdo_stmt.c	2012-01-12 19:14:45.878023745 -0300
@@ -583,6 +583,14 @@
 			ZVAL_NULL(dest);
 			break;
 
+		case PDO_PARAM_STMT:
+			if (!value) {
+				ZVAL_NULL(dest);
+				break;
+			}
+			zval *zv = (zval *)value;
+			ZVAL_ZVAL(dest, zv, 0, 1);
+			break;
 		case PDO_PARAM_BOOL:
 			if (value && value_len == sizeof(zend_bool)) {
 				ZVAL_BOOL(dest, *(zend_bool*)value);
@@ -650,6 +658,9 @@
 
 	if (type != new_type) {
 		switch (new_type) {
+			case PDO_PARAM_STMT:
+				convert_to_object_ex(&dest);
+				break;
 			case PDO_PARAM_INT:
 				convert_to_long_ex(&dest);
 				break;
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Jul 05 14:01:39 2020 UTC