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: 2012-01-12 22:41 UTC | 2012-01-10 19:56 UTC

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-10 15:27:41.276135756 -0300
 @@ -97,6 +97,9 @@
 +++ 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:
 +						 OCIHandleFree(S->cols[i].data, OCI_HTYPE_STMT);
 +						 break;
 +					case SQLT_RSET:
   					case SQLT_BLOB:
   					case SQLT_CLOB:
   						/* do nothing */
 @@ -235,6 +238,14 @@
 @@ -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*);               
 +		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;            
 +		return OCI_CONTINUE;		
   	}
   
   	if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
 @@ -258,6 +269,55 @@
  	return OCI_CONTINUE;
  } /* }}} */
  
 +zend_object_value *oci_create_rset(pdo_stmt_t *stmt, OCIStmt *oci_stmt) {
 +	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
 +	//	pdo_oci_column *C = &S->cols[colno];
 +
 +	ub4 colcount;
 +	pdo_oci_stmt *NS = ecalloc(1, sizeof(*NS));
 +	zend_object_value *retval = ecalloc(1, sizeof(*retval));
 +			
 +	*retval = stmt->ce->create_object (stmt->ce);
 +	pdo_stmt_t *stm = (pdo_stmt_t*)zend_object_store_get_object_by_handle(retval->handle);
 +	
 +	//			OCIHandleAlloc( (dvoid *) S->H->env, (dvoid **) &p_err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);
 +	stm->dbh = stmt->dbh;
 +	
 +	NS->exec_type = OCI_DEFAULT;
 +	NS->H = S->H;
 +	
 +	stm->supports_placeholders = PDO_PLACEHOLDER_NAMED;
 +	efree(NS->stmt);
 +	// NS->stmt = *((OCIStmt**)C->data);
 +	NS->stmt = oci_stmt;
 +	// Allocate new handle 
 +
 +	stm->driver_data = NS;
 +	stm->methods = &oci_stmt_methods;
 +	//stm->methods = stmt->methods;
 +	
 +	/* create our own private error handle */
 +	OCIHandleAlloc(S->H->env, (dvoid*)&NS->err, OCI_HTYPE_ERROR, 0, NULL);
 +	
 +	stm->database_object_handle = stmt->database_object_handle;
 +	
 +	/* do first-time-only definition of bind/mapping stuff */
 +	if (!NS->stmt_type) {
 +		STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_STMT_TYPE",
 +					  (NS->stmt, OCI_HTYPE_STMT, &NS->stmt_type, 0, OCI_ATTR_STMT_TYPE, S->err));
 +	}
 +	/* how many columns do we have ? */
 +	STMT_CALL_MSG(OCIAttrGet, "ATTR_PARAM_COUNT",
 +				  (NS->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));
 +	stm->column_count = (int)colcount;			
 +	stm->executed = 1;
 +	NS->cols = ecalloc(colcount, sizeof(pdo_oci_column));
 +	pdo_stmt_describe_columns(stm);
 +	stm->executed = 1;
 +
 +	return retval;
 +}
 +
  static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC) /* {{{ */
  {
  	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
 @@ -284,7 +344,10 @@
 @@ -284,7 +343,9 @@
   				/* figure out what we're doing */
   				switch (PDO_PARAM_TYPE(param->param_type)) {
   					case PDO_PARAM_STMT:
  -						return 0;
 +						/* P->thing is now an  OCIStmt* */
  +						P->oci_type = SQLT_RSET;
  +						value_sz = sizeof(OCIStmt*);
  +						break;
   
   					case PDO_PARAM_LOB:
   						/* P->thing is now an OCILobLocator * */
 @@ -305,15 +368,15 @@
  				if (param->name) {
  					STMT_CALL(OCIBindByName, (S->stmt,
  							&P->bind, S->err, (text*)param->name,
 -							param->namelen, 0, value_sz, P->oci_type,
 +							param->namelen, P->oci_type == SQLT_RSET ? &P->thing : 0, value_sz, P->oci_type,
  							&P->indicator, 0, &P->retcode, 0, 0,
 -							OCI_DATA_AT_EXEC));
 +							P->oci_type == SQLT_RSET ? OCI_DEFAULT : OCI_DATA_AT_EXEC));
  				} else {
  					STMT_CALL(OCIBindByPos, (S->stmt,
  							&P->bind, S->err, param->paramno+1,
 -							0, value_sz, P->oci_type,
 +							P->oci_type == SQLT_RSET ? &P->thing : 0, value_sz, P->oci_type,
  							&P->indicator, 0, &P->retcode, 0, 0,
 -							OCI_DATA_AT_EXEC));
 +							P->oci_type == SQLT_RSET ? OCI_DEFAULT : OCI_DATA_AT_EXEC));
  				}
  
  				STMT_CALL(OCIBindDynamic, (P->bind,
 @@ -331,6 +394,8 @@
 @@ -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) {
 +					STMT_CALL(OCIHandleAlloc,(S->H->env, &P->thing, OCI_HTYPE_STMT, 0, 0));
 +					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;
   
 @@ -358,6 +423,11 @@
  			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) {
 +					zend_object_value *retval = oci_create_rset(stmt, (OCIStmt*)P->thing);
 +					//      STMT_CALL(OCIHandleAlloc,(S->H->env, &P->thing, OCI_HTYPE_STMT, 0, 0));
 +					Z_TYPE_P(param->parameter) = IS_OBJECT;
 +					param->parameter->value.obj = *retval;
 +					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;
   
 @@ -537,6 +607,16 @@
 @@ -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;
 +			S->cols[colno].data = ecalloc(1,sizeof(OCIStmt*));
 +			//S->cols[colno].datalen = sizeof(OCIStmt*);
 +			S->cols[colno].datalen = 0;
 +			STMT_CALL(OCIHandleAlloc,
 +					  (S->H->env, (dvoid **) S->cols[colno].data,
 +					   OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
 +			dyn = FALSE;
 +			break;
 +	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 +734,7 @@
 @@ -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,6 +814,20 @@
 @@ -734,8 +825,17 @@
   			}
   			*len = 0;
   			return *ptr ? 1 : 0;
 -		}
  +		} else if (C->dtype == SQLT_RSET) {
 +			zend_object_value *retval = oci_create_rset(stmt, *((OCIStmt**)C->data));
 +			// Allocate new handle 
 +			STMT_CALL(OCIHandleAlloc,
 +					  (S->H->env, (dvoid **) C->data,
 +					   OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));                  
 +			// not needed
 +			// STMT_CALL(OCIDefineByPos, (S->stmt, &C->def, S->err, colno+1,
 +			// 						   C->data, 0, SQLT_RSET, &C->indicator,
 +			//						   &C->fetched_len, &C->retcode, OCI_DEFAULT));
 +			*ptr = (char *)retval;
 +			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;
 +			*caller_frees = 0;
  +			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-10 14:45:06.400977840 -0300
 @@ -574,6 +574,18 @@
  				type = new_type;
  			}
 +++ 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;
 +				break;
  +			}
 + 
 +			zend_object_value *retval ;
 +			retval = (zend_object_value *)value;
 +			Z_TYPE_P(dest) = IS_OBJECT;
 +			dest->value.obj = *retval;
 +			
 +			zval *zv = (zval *)value;
 +			ZVAL_ZVAL(dest, zv, 0, 1);
  +			break;
  			
  		case PDO_PARAM_INT:
  			if (value && value_len == sizeof(long)) {
  		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-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 20:01:29 2024 UTC