Patch php-5.3.8-cursor-support-for-pdo_oci.patch for PDO OCI Bug #60703
Patch version 2012-01-10 19:56 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-10 15:27:41.276135756 -0300
@@ -97,6 +97,9 @@
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_BLOB:
case SQLT_CLOB:
/* do nothing */
@@ -235,6 +238,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) {
@@ -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 @@
/* 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 @@
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));
}
return 1;
@@ -358,6 +423,11 @@
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;
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
php_stream *stm;
@@ -537,6 +607,16 @@
/* 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_LBI:
case SQLT_LNG:
if (dtype == SQLT_LBI) {
@@ -654,7 +734,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 @@
}
*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;
+ *len = C->fetched_len;
+ *caller_frees = 0;
+ return 1;
}
*ptr = C->data;
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;
}
break;
+ case PDO_PARAM_STMT:
+ if (!value) {
+ ZVAL_NULL(dest);
+ break;
+ }
+
+ zend_object_value *retval ;
+ retval = (zend_object_value *)value;
+ Z_TYPE_P(dest) = IS_OBJECT;
+ dest->value.obj = *retval;
+
+ break;
case PDO_PARAM_INT:
if (value && value_len == sizeof(long)) {
|