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;
|