PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/oci8 - oci8_statement.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 678 794 85.4 %
Date: 2014-08-04 Functions: 22 23 95.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
      16             :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17             :    |                                                                      |
      18             :    | Collection support by Andy Sautins <asautins@veripost.net>           |
      19             :    | Temporary LOB support by David Benson <dbenson@mancala.com>          |
      20             :    | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at>        |
      21             :    |                                                                      |
      22             :    | Redesigned by: Antony Dovgal <antony@zend.com>                       |
      23             :    |                Andi Gutmans <andi@zend.com>                          |
      24             :    |                Wez Furlong <wez@omniti.com>                          |
      25             :    +----------------------------------------------------------------------+
      26             : */
      27             : 
      28             : /* $Id$ */
      29             : 
      30             : 
      31             : #ifdef HAVE_CONFIG_H
      32             : #include "config.h"
      33             : #endif
      34             : 
      35             : #include "php.h"
      36             : #include "ext/standard/info.h"
      37             : #include "php_ini.h"
      38             : 
      39             : #if HAVE_OCI8
      40             : 
      41             : #include "php_oci8.h"
      42             : #include "php_oci8_int.h"
      43             : 
      44             : /* {{{ php_oci_statement_create()
      45             :  Create statemend handle and allocate necessary resources */
      46       34506 : php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char *query, int query_len TSRMLS_DC)
      47             : {
      48             :         php_oci_statement *statement;
      49             :         sword errstatus;
      50             : 
      51       34506 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
      52             : 
      53       34506 :         statement = ecalloc(1,sizeof(php_oci_statement));
      54             : 
      55       34506 :         if (!query_len) {
      56             :                 /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */
      57        1445 :                 PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL));
      58             :         }
      59             :                 
      60       34506 :         PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL));
      61             :         
      62       34506 :         if (query_len > 0) {
      63       33061 :                 PHP_OCI_CALL_RETURN(errstatus, OCIStmtPrepare2,
      64             :                                 (
      65             :                                  connection->svc,
      66             :                                  &(statement->stmt),
      67             :                                  connection->err,
      68             :                                  (text *)query,
      69             :                                  query_len,
      70             :                                  NULL,
      71             :                                  0,
      72             :                                  OCI_NTV_SYNTAX,
      73             :                                  OCI_DEFAULT
      74             :                                 )
      75             :                 );
      76             : #ifdef HAVE_OCI8_DTRACE
      77             :                 if (DTRACE_OCI8_SQLTEXT_ENABLED()) {
      78             :                         DTRACE_OCI8_SQLTEXT(connection, connection->client_id, statement, query);
      79             :                 }
      80             : #endif /* HAVE_OCI8_DTRACE */
      81             : 
      82       33061 :                 if (errstatus != OCI_SUCCESS) {
      83           5 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
      84             : 
      85           5 :                         PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, OCI_STRLS_CACHE_DELETE));
      86           5 :                         PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR));
      87           5 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
      88           5 :                         efree(statement);
      89           5 :                         return NULL;
      90             :                 }
      91             :         }
      92             :         
      93       67557 :         if (query && query_len) {
      94       33056 :                 statement->last_query = estrndup(query, query_len);
      95       33056 :                 statement->last_query_len = query_len;
      96             :         }
      97             :         else {
      98        1445 :                 statement->last_query = NULL;
      99        1445 :                 statement->last_query_len = 0;
     100             :         }
     101             : 
     102       34501 :         statement->connection = connection;
     103       34501 :         statement->has_data = 0;
     104       34501 :         statement->has_descr = 0;
     105       34501 :         statement->parent_stmtid = 0;
     106       34501 :         statement->impres_child_stmt = NULL;
     107       34501 :         statement->impres_count = 0;
     108       34501 :         statement->impres_flag = PHP_OCI_IMPRES_UNKNOWN;  /* may or may not have Implicit Result Set children */
     109       34501 :         zend_list_addref(statement->connection->id);
     110             : 
     111       34501 :         if (OCI_G(default_prefetch) >= 0) {
     112       34501 :                 php_oci_statement_set_prefetch(statement, (ub4)OCI_G(default_prefetch) TSRMLS_CC);
     113             :         } else {
     114           0 :                 php_oci_statement_set_prefetch(statement, (ub4)100 TSRMLS_CC); /* semi-arbitrary, "sensible default" */
     115             :         }
     116             :         
     117       34501 :         PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
     118             : 
     119       34501 :         OCI_G(num_statements)++;
     120             :         
     121       34501 :         return statement;
     122             : }
     123             : /* }}} */
     124             : 
     125             : /* {{{ php_oci_get_implicit_resultset()
     126             :    Fetch implicit result set statement resource */
     127           0 : php_oci_statement *php_oci_get_implicit_resultset(php_oci_statement *statement TSRMLS_DC)
     128             : {
     129             : #if (OCI_MAJOR_VERSION < 12)
     130           0 :         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Implicit results are available in Oracle Database 12c onwards");
     131           0 :         return NULL;
     132             : #else
     133             :         void *result;
     134             :         ub4   rtype;
     135             :         php_oci_statement *statement2;  /* implicit result set statement handle */
     136             :         sword errstatus;
     137             : 
     138             :         PHP_OCI_CALL_RETURN(errstatus, OCIStmtGetNextResult, (statement->stmt, statement->err, &result, &rtype, OCI_DEFAULT));
     139             :         if (errstatus == OCI_NO_DATA) {
     140             :                 return NULL;
     141             :         }
     142             : 
     143             :         if (rtype != OCI_RESULT_TYPE_SELECT) {
     144             :                 /* Only OCI_RESULT_TYPE_SELECT is supported by Oracle DB 12cR1 */
     145             :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected implicit result type returned from Oracle Database");
     146             :                 return NULL;
     147             :         } else {
     148             :                 statement2 = ecalloc(1,sizeof(php_oci_statement));
     149             : 
     150             :                 PHP_OCI_CALL(OCIHandleAlloc, (statement->connection->env, (dvoid **)&(statement2->err), OCI_HTYPE_ERROR, 0, NULL));
     151             :                 statement2->stmt = (OCIStmt *)result;        
     152             :                 statement2->parent_stmtid = statement->id;
     153             :                 statement2->impres_child_stmt = NULL;
     154             :                 statement2->impres_count = 0;
     155             :                 statement2->impres_flag = PHP_OCI_IMPRES_IS_CHILD;
     156             :                 statement2->connection = statement->connection;
     157             :                 statement2->errcode = 0;
     158             :                 statement2->last_query = NULL;
     159             :                 statement2->last_query_len = 0;
     160             :                 statement2->columns = NULL;
     161             :                 statement2->binds = NULL;
     162             :                 statement2->defines = NULL;
     163             :                 statement2->ncolumns = 0;
     164             :                 statement2->executed = 0;
     165             :                 statement2->has_data = 0;
     166             :                 statement2->has_descr = 0;
     167             :                 statement2->stmttype = 0;
     168             : 
     169             :                 zend_list_addref(statement->id);
     170             :                 zend_list_addref(statement2->connection->id);
     171             : 
     172             :                 php_oci_statement_set_prefetch(statement2, statement->prefetch_count TSRMLS_CC);
     173             :                 
     174             :                 PHP_OCI_REGISTER_RESOURCE(statement2, le_statement);
     175             :         
     176             :                 OCI_G(num_statements)++;
     177             :                 
     178             :                 return statement2;
     179             :         }
     180             : #endif /* OCI_MAJOR_VERSION < 12 */
     181             : }
     182             : /* }}} */
     183             : 
     184             : /* {{{ php_oci_statement_set_prefetch()
     185             :  Set prefetch buffer size for the statement */
     186       34517 : int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch  TSRMLS_DC)
     187             : {
     188             :         sword errstatus;
     189             : 
     190       34517 :         if (prefetch > 20000) {
     191           0 :                 prefetch = 20000;               /* keep it somewhat sane */
     192             :         }
     193             : 
     194       34517 :         PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err));
     195             :         
     196       34517 :         if (errstatus != OCI_SUCCESS) {
     197           0 :                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     198           0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     199           0 :                 statement->prefetch_count = 0;
     200           0 :                 return 1;
     201             :         }
     202       34517 :         statement->prefetch_count = prefetch;
     203       34517 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     204       34517 :         return 0;
     205             : }
     206             : /* }}} */
     207             : 
     208             : /* {{{ php_oci_cleanup_pre_fetch()
     209             :    Helper function to cleanup ref-cursors and descriptors from the previous row */
     210      445258 : int php_oci_cleanup_pre_fetch(void *data TSRMLS_DC)
     211             : {
     212      445258 :         php_oci_out_column *outcol = data;
     213             : 
     214      445258 :         if (!outcol->is_descr && !outcol->is_cursor)
     215      100306 :                 return ZEND_HASH_APPLY_KEEP;
     216             : 
     217      344952 :         switch(outcol->data_type) {
     218             :                 case SQLT_CLOB:
     219             :                 case SQLT_BLOB:
     220             :                 case SQLT_RDD:
     221             :                 case SQLT_BFILE:
     222      343526 :                         if (outcol->descid) {
     223      283364 :                                 zend_list_delete(outcol->descid);
     224      283364 :                                 outcol->descid = 0;
     225             :                         }
     226      343526 :                         break;
     227             :                 case SQLT_RSET:
     228        1426 :                         if (outcol->stmtid) {
     229          16 :                                 zend_list_delete(outcol->stmtid);
     230          16 :                                 outcol->stmtid = 0;
     231          16 :                                 outcol->nested_statement = NULL;
     232             :                         }
     233             :                         break;
     234             :                 default:
     235             :                         break;
     236             :         }
     237      344952 :         return ZEND_HASH_APPLY_KEEP;
     238             : 
     239             : }
     240             : /* }}} */
     241             : 
     242             : /* {{{ php_oci_statement_fetch()
     243             :  Fetch a row from the statement */
     244      232102 : int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC)
     245             : {
     246             :         int i;
     247             :         void *handlepp;
     248             :         ub4 typep, iterp, idxp;
     249             :         ub1 in_outp, piecep;
     250      232102 :         zend_bool piecewisecols = 0;
     251             :         php_oci_out_column *column;
     252             :         sword errstatus;
     253             : 
     254      232102 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     255             : 
     256      232102 :         if (statement->has_descr && statement->columns) {
     257      224472 :                 zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch TSRMLS_CC);
     258             :     }
     259             : 
     260      232102 :         PHP_OCI_CALL_RETURN(errstatus, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
     261             : 
     262      232102 :         if (errstatus == OCI_NO_DATA || nrows == 0) {
     263       30352 :                 if (statement->last_query == NULL) {
     264             :                         /* reset define-list for refcursors */
     265          20 :                         if (statement->columns) {
     266          18 :                                 zend_hash_destroy(statement->columns);
     267          18 :                                 efree(statement->columns);
     268          18 :                                 statement->columns = NULL;
     269          18 :                                 statement->ncolumns = 0;
     270             :                         }
     271          20 :                         statement->executed = 0;
     272             :                 }
     273             : 
     274       30352 :                 statement->has_data = 0;
     275             : 
     276       30352 :                 if (nrows == 0) {
     277             :                         /* this is exactly what we requested */
     278           8 :                         return 0;
     279             :                 }
     280       30344 :                 return 1;
     281             :         }
     282             : 
     283             :         /* reset length for all piecewise columns */
     284      594530 :         for (i = 0; i < statement->ncolumns; i++) {
     285      392780 :                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     286      392780 :                 if (column && column->piecewise) {
     287          13 :                         column->retlen4 = 0;
     288          13 :                         piecewisecols = 1;
     289             :                 }
     290             :         }
     291             :         
     292      403516 :         while (errstatus == OCI_NEED_DATA) {
     293          16 :                 if (piecewisecols) {
     294          16 :                         PHP_OCI_CALL_RETURN(errstatus,
     295             :                                 OCIStmtGetPieceInfo,
     296             :                                    (
     297             :                                         statement->stmt,
     298             :                                         statement->err,
     299             :                                         &handlepp,
     300             :                                         &typep,
     301             :                                         &in_outp,
     302             :                                         &iterp,
     303             :                                         &idxp,
     304             :                                         &piecep
     305             :                                    )
     306             :                         );
     307             : 
     308             :                         /* scan through our columns for a piecewise column with a matching handle */
     309          42 :                         for (i = 0; i < statement->ncolumns; i++) {
     310          26 :                                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     311          26 :                                 if (column && column->piecewise && handlepp == column->oci_define)   {
     312          16 :                                         if (!column->data) {
     313           5 :                                                 column->data = (text *) ecalloc(1, PHP_OCI_PIECE_SIZE + 1);
     314             :                                         } else {
     315          11 :                                                 column->data = erealloc(column->data, column->retlen4 + PHP_OCI_PIECE_SIZE + 1);
     316             :                                         }
     317          16 :                                         column->cb_retlen = PHP_OCI_PIECE_SIZE;
     318             : 
     319             :                                         /* and instruct fetch to fetch waiting piece into our buffer */
     320          16 :                                         PHP_OCI_CALL(OCIStmtSetPieceInfo,
     321             :                                                    (
     322             :                                                         (void *) column->oci_define,
     323             :                                                         OCI_HTYPE_DEFINE,
     324             :                                                         statement->err,
     325             :                                                         ((char*)column->data) + column->retlen4,
     326             :                                                         &(column->cb_retlen),
     327             :                                                         piecep,
     328             :                                                         &column->indicator,
     329             :                                                         &column->retcode
     330             :                                                    )
     331             :                                         );
     332             :                                 }
     333             :                         }
     334             :                 }
     335             : 
     336          16 :                 PHP_OCI_CALL_RETURN(errstatus, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT));
     337             : 
     338          16 :                 if (piecewisecols) {
     339          42 :                         for (i = 0; i < statement->ncolumns; i++) {
     340          26 :                                 column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     341          26 :                                 if (column && column->piecewise && handlepp == column->oci_define)        {
     342          16 :                                         column->retlen4 += column->cb_retlen;
     343             :                                 }
     344             :                         }
     345             :                 }
     346             :         }
     347             : 
     348      201750 :         if (errstatus == OCI_SUCCESS_WITH_INFO || errstatus == OCI_SUCCESS) {
     349      201741 :                 statement->has_data = 1;
     350             : 
     351             :                 /* do the stuff needed for OCIDefineByName */
     352      594514 :                 for (i = 0; i < statement->ncolumns; i++) {
     353      392773 :                         column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     354      392773 :                         if (column == NULL) {
     355           0 :                                 continue;
     356             :                         }
     357             :                         
     358      392773 :                         if (!column->define) {
     359      302726 :                                 continue;
     360             :                         }
     361             :                         
     362       90047 :                         zval_dtor(column->define->zval);
     363       90047 :                         php_oci_column_to_zval(column, column->define->zval, 0 TSRMLS_CC);
     364             :                 }
     365             : 
     366      201741 :                 return 0;
     367             :         }
     368             : 
     369           9 :         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     370           9 :         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     371             : 
     372           9 :         statement->has_data = 0;
     373             : 
     374           9 :         return 1;
     375             : }
     376             : /* }}} */
     377             : 
     378             : /* {{{ php_oci_statement_get_column()
     379             :  Get column from the result set */
     380     1178666 : php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, long column_index, char *column_name, int column_name_len TSRMLS_DC)
     381             : {
     382     1178666 :         php_oci_out_column *column = NULL;
     383             :         int i;
     384             : 
     385     1178666 :         if (statement->columns == NULL) { /* we release the columns at the end of a fetch */
     386           0 :                 return NULL;
     387             :         }
     388             : 
     389     1178666 :         if (column_name) {
     390         344 :                 for (i = 0; i < statement->ncolumns; i++) {
     391         337 :                         column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC);
     392         337 :                         if (column == NULL) {
     393           0 :                                 continue;
     394         337 :                         } else if (((int) column->name_len == column_name_len) && (!strncmp(column->name, column_name, column_name_len))) {
     395          69 :                                 return column;
     396             :                         }
     397             :                 }
     398     1178590 :         } else if (column_index != -1) {
     399     1178583 :                 if (zend_hash_index_find(statement->columns, column_index, (void **)&column) == FAILURE) {
     400           7 :                         return NULL;
     401             :                 }
     402     1178576 :                 return column;
     403             :         }
     404             : 
     405          14 :         return NULL;
     406             : }
     407             : /* }}} */
     408             : 
     409             : /* {{{ php_oci_define_callback() */
     410      284856 : sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp)
     411             : {
     412      284856 :         php_oci_out_column *outcol = (php_oci_out_column *)ctx;
     413             :         TSRMLS_FETCH();
     414             : 
     415      284856 :         if (!outcol) {
     416             :                 
     417           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid context pointer value");
     418           0 :                 return OCI_ERROR;
     419             :         }
     420             :         
     421      284856 :         switch(outcol->data_type) {
     422             :                 case SQLT_RSET: {
     423             :                                 php_oci_statement *nested_stmt;
     424             : 
     425        1417 :                                 nested_stmt = php_oci_statement_create(outcol->statement->connection, NULL, 0 TSRMLS_CC);
     426        1417 :                                 if (!nested_stmt) {
     427           0 :                                         return OCI_ERROR;
     428             :                                 }
     429        1417 :                                 nested_stmt->parent_stmtid = outcol->statement->id;
     430        1417 :                                 zend_list_addref(outcol->statement->id);
     431        1417 :                                 outcol->nested_statement = nested_stmt;
     432        1417 :                                 outcol->stmtid = nested_stmt->id;
     433             : 
     434        1417 :                                 *bufpp = nested_stmt->stmt;
     435        1417 :                                 *alenpp = &(outcol->retlen4);
     436        1417 :                                 *piecep = OCI_ONE_PIECE;
     437        1417 :                                 *indpp = &(outcol->indicator);
     438        1417 :                                 *rcpp = &(outcol->retcode);
     439        1417 :                                 return OCI_CONTINUE;
     440             :                         }
     441             :                         break;
     442             :                 case SQLT_RDD:
     443             :                 case SQLT_BLOB:
     444             :                 case SQLT_CLOB:
     445             :                 case SQLT_BFILE: {
     446             :                                 php_oci_descriptor *descr;
     447             :                                 int dtype;
     448             : 
     449      283439 :                                 if (outcol->data_type == SQLT_BFILE) {
     450           3 :                                         dtype = OCI_DTYPE_FILE;
     451      283436 :                                 } else if (outcol->data_type == SQLT_RDD ) {
     452           1 :                                         dtype = OCI_DTYPE_ROWID;
     453             :                                 } else {
     454      283435 :                                         dtype = OCI_DTYPE_LOB;
     455             :                                 }
     456             : 
     457      283439 :                                 descr = php_oci_lob_create(outcol->statement->connection, dtype TSRMLS_CC);
     458      283439 :                                 if (!descr) {
     459           0 :                                         return OCI_ERROR;
     460             :                                 }
     461      283439 :                                 outcol->descid = descr->id;
     462      283439 :                                 descr->charset_form = outcol->charset_form;
     463             :                                 
     464      283439 :                                 *bufpp = descr->descriptor;
     465      283439 :                                 *alenpp = &(outcol->retlen4);
     466      283439 :                                 *piecep = OCI_ONE_PIECE;
     467      283439 :                                 *indpp = &(outcol->indicator);
     468      283439 :                                 *rcpp = &(outcol->retcode);
     469             : 
     470      283439 :                                 return OCI_CONTINUE;
     471             :                         }
     472             :                         break;
     473             :         }
     474           0 :         return OCI_ERROR;
     475             : }
     476             : /* }}} */
     477             : 
     478             : /* {{{ php_oci_statement_execute()
     479             :  Execute statement */
     480       37835 : int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
     481             : {
     482             :         php_oci_out_column *outcol;
     483             :         php_oci_out_column column;
     484       37835 :         OCIParam *param = NULL;
     485             :         text *colname;
     486             :         ub4 counter;
     487             :         ub2 define_type;
     488             :         ub4 iters;
     489             :         ub4 colcount;
     490             :         ub2 dynamic;
     491             :         dvoid *buf;
     492             :         sword errstatus;
     493             : 
     494       37835 :         switch (mode) {
     495             :                 case OCI_COMMIT_ON_SUCCESS:
     496             :                 case OCI_DESCRIBE_ONLY:
     497             :                 case OCI_DEFAULT:
     498             :                         /* only these are allowed */
     499             : #ifdef HAVE_OCI8_DTRACE
     500             :                         if (DTRACE_OCI8_EXECUTE_MODE_ENABLED()) {
     501             :                                 DTRACE_OCI8_EXECUTE_MODE(statement->connection, statement->connection->client_id, statement, mode);
     502             :                         }
     503             : #endif /* HAVE_OCI8_DTRACE */
     504       37834 :                         break;
     505             :                 default:
     506           1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid execute mode given: %d", mode);
     507           1 :                         return 1;
     508             :                         break;
     509             :         }
     510             :         
     511       37834 :         if (!statement->stmttype) {
     512             :                 /* get statement type */
     513       34456 :                 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
     514             : 
     515       34456 :                 if (errstatus != OCI_SUCCESS) {
     516           0 :                         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     517           0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     518           0 :                         return 1;
     519             :                 } else {
     520       34456 :                         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     521             :                 }
     522             :         }
     523             : 
     524       37834 :         if (statement->stmttype == OCI_STMT_SELECT) {
     525       32921 :                 iters = 0;
     526             :         } else {
     527        4913 :                 iters = 1;
     528             :         }
     529             :         
     530       37834 :         if (statement->last_query) { /* Don't execute REFCURSORS or Implicit Result Set handles */
     531             : 
     532       36396 :                 if (statement->binds) {
     533        3677 :                         int result = 0;
     534        3677 :                         zend_hash_apply_with_argument(statement->binds, (apply_func_arg_t) php_oci_bind_pre_exec, (void *)&result TSRMLS_CC);
     535        3677 :                         if (result) {
     536           2 :                                 return 1;
     537             :                         }
     538             :                 }
     539             : 
     540             :                 /* execute statement */
     541       36394 :                 PHP_OCI_CALL_RETURN(errstatus, OCIStmtExecute, (statement->connection->svc, statement->stmt, statement->err, iters, 0, NULL, NULL, mode));
     542             : 
     543       36394 :                 if (errstatus != OCI_SUCCESS) {
     544         257 :                         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     545         257 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     546         257 :                         return 1;
     547             :                 }
     548             :                 
     549       36137 :                 if (statement->binds) {
     550        3654 :                         zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec TSRMLS_CC);
     551             :                 }
     552             : 
     553       36137 :                 if (mode & OCI_COMMIT_ON_SUCCESS) {
     554             :                         /* No need to rollback on disconnect */
     555       34456 :                         statement->connection->rb_on_disconnect = 0;
     556        1681 :                 } else if (statement->stmttype != OCI_STMT_SELECT) {
     557             :                         /* Assume some uncommitted DML occurred */
     558         915 :                         statement->connection->rb_on_disconnect = 1;
     559             :                 }
     560             :                 /* else for SELECT with OCI_NO_AUTO_COMMIT, leave
     561             :                  * "rb_on_disconnect" at its previous value.  SELECT can't
     562             :                  * initiate uncommitted DML. (An AUTONOMOUS_TRANSACTION in
     563             :                  * invoked PL/SQL must explicitly rollback/commit else the
     564             :                  * SELECT fails).
     565             :                  */
     566             : 
     567       36137 :                 statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     568             :         }
     569             : 
     570       37575 :         if (statement->stmttype == OCI_STMT_SELECT && statement->executed == 0) {
     571             :                 /* we only need to do the define step is this very statement is executed the first time! */
     572       32853 :                 statement->executed = 1;
     573             :                 
     574       32853 :                 ALLOC_HASHTABLE(statement->columns);
     575       32853 :                 zend_hash_init(statement->columns, 13, NULL, php_oci_column_hash_dtor, 0);
     576             :                 
     577       32853 :                 counter = 1;
     578             : 
     579             :                 /* get number of columns */
     580       32853 :                 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err));
     581             :                 
     582       32853 :                 if (errstatus != OCI_SUCCESS) {
     583           0 :                         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     584           0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     585           0 :                         return 1;
     586             :                 }
     587             : 
     588       32853 :                 statement->ncolumns = colcount;
     589             :                 
     590       96333 :                 for (counter = 1; counter <= colcount; counter++) {
     591       63480 :                         memset(&column,0,sizeof(php_oci_out_column));
     592             :                         
     593       63480 :                         if (zend_hash_index_update(statement->columns, counter, &column, sizeof(php_oci_out_column), (void**) &outcol) == FAILURE) {
     594           0 :                                 efree(statement->columns);
     595             :                                 /* out of memory */
     596           0 :                                 return 1;
     597             :                         }
     598             :                         
     599             :                         /* get column */
     600       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)&param, counter));
     601             :                         
     602       63480 :                         if (errstatus != OCI_SUCCESS) {
     603           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     604           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     605           0 :                                 return 1;
     606             :                         }
     607             : 
     608             :                         /* get column datatype */
     609       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err));
     610             : 
     611       63480 :                         if (errstatus != OCI_SUCCESS) {
     612           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     613           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     614           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     615           0 :                                 return 1;
     616             :                         }
     617             : 
     618             :                         /* get character set form  */
     619       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_form, (ub4 *)0, OCI_ATTR_CHARSET_FORM, statement->err));
     620             : 
     621       63480 :                         if (errstatus != OCI_SUCCESS) {
     622           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     623           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     624           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     625           0 :                                 return 1;
     626             :                         }
     627             :         
     628             :                         /* get character set id  */
     629       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_id, (ub4 *)0, OCI_ATTR_CHARSET_ID, statement->err));
     630             : 
     631       63480 :                         if (errstatus != OCI_SUCCESS) {
     632           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     633           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     634           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     635           0 :                                 return 1;
     636             :                         }
     637             :         
     638             :                         /* get size of the column */
     639       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err));
     640             :                         
     641       63480 :                         if (errstatus != OCI_SUCCESS) {
     642           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     643           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     644           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     645           0 :                                 return 1;
     646             :                         }
     647             : 
     648       63480 :                         outcol->storage_size4 = outcol->data_size;
     649       63480 :                         outcol->retlen = outcol->data_size;
     650             : 
     651             :                         /* get scale of the column */
     652       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err));
     653             :                         
     654       63480 :                         if (errstatus != OCI_SUCCESS) {
     655           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     656           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     657           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     658           0 :                                 return 1;
     659             :                         }
     660             : 
     661             :                         /* get precision of the column */
     662       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err));
     663             :                         
     664       63480 :                         if (errstatus != OCI_SUCCESS) {
     665           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     666           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     667           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     668           0 :                                 return 1;
     669             :                         }
     670             :                         
     671             :                         /* get name of the column */
     672       63480 :                         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err));
     673             :                         
     674       63480 :                         if (errstatus != OCI_SUCCESS) {
     675           0 :                                 PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     676           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     677           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     678           0 :                                 return 1;
     679             :                         }
     680       63480 :                         PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM));
     681             : 
     682       63480 :                         outcol->name = estrndup((char*) colname, outcol->name_len);
     683             : 
     684             :                         /* find a user-set define */
     685       63480 :                         if (statement->defines) {
     686       30051 :                                 if (zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define) == SUCCESS) {
     687       30046 :                                         if (outcol->define->type) {
     688          10 :                                                 outcol->data_type = outcol->define->type;
     689             :                                         }
     690             :                                 }
     691             :                         }
     692             : 
     693       63480 :                         buf = 0;
     694       63480 :                         switch (outcol->data_type) {
     695             :                                 case SQLT_RSET:
     696        1411 :                                         outcol->statement = statement; /* parent handle */
     697             : 
     698        1411 :                                         define_type = SQLT_RSET;
     699        1411 :                                         outcol->is_cursor = 1;
     700        1411 :                                         outcol->statement->has_descr = 1;
     701        1411 :                                         outcol->storage_size4 = -1;
     702        1411 :                                         outcol->retlen = -1;
     703        1411 :                                         dynamic = OCI_DYNAMIC_FETCH;
     704        1411 :                                         break;
     705             : 
     706             :                                 case SQLT_RDD:   /* ROWID */
     707             :                                 case SQLT_BLOB:  /* binary LOB */
     708             :                                 case SQLT_CLOB:  /* character LOB */
     709             :                                 case SQLT_BFILE: /* binary file LOB */
     710       60136 :                                         outcol->statement = statement; /* parent handle */
     711             : 
     712       60136 :                                         define_type = outcol->data_type;
     713       60136 :                                         outcol->is_descr = 1;
     714       60136 :                                         outcol->statement->has_descr = 1;
     715       60136 :                                         outcol->storage_size4 = -1;
     716       60136 :                                         outcol->chunk_size = 0;
     717       60136 :                                         dynamic = OCI_DYNAMIC_FETCH;
     718       60136 :                                         break;
     719             : 
     720             :                                 case SQLT_LNG:
     721             :                                 case SQLT_LBI:
     722           5 :                                         if (outcol->data_type == SQLT_LBI) {
     723           1 :                                                 define_type = SQLT_BIN;
     724             :                                         } else {
     725           4 :                                                 define_type = SQLT_CHR;
     726             :                                         }
     727           5 :                                         outcol->storage_size4 = PHP_OCI_MAX_DATA_SIZE;
     728           5 :                                         outcol->piecewise = 1;
     729           5 :                                         dynamic = OCI_DYNAMIC_FETCH;
     730           5 :                                         break;
     731             : 
     732             :                                 case SQLT_BIN:
     733             :                                 default:
     734        1928 :                                         define_type = SQLT_CHR;
     735        1928 :                                         if (outcol->data_type == SQLT_BIN) {
     736           5 :                                                 define_type = SQLT_BIN;
     737             :                                         }
     738        7228 :                                         if ((outcol->data_type == SQLT_DAT) || (outcol->data_type == SQLT_NUM)
     739             : #ifdef SQLT_TIMESTAMP
     740         846 :                                                 || (outcol->data_type == SQLT_TIMESTAMP)
     741             : #endif
     742             : #ifdef SQLT_TIMESTAMP_TZ
     743         843 :                                                 || (outcol->data_type == SQLT_TIMESTAMP_TZ)
     744             : #endif
     745             : #ifdef SQLT_TIMESTAMP_LTZ
     746         841 :                                                 || (outcol->data_type == SQLT_TIMESTAMP_LTZ)
     747             : #endif
     748             : #ifdef SQLT_INTERVAL_YM
     749         840 :                                                 || (outcol->data_type == SQLT_INTERVAL_YM)
     750             : #endif
     751             : #ifdef SQLT_INTERVAL_DS
     752         838 :                                                 || (outcol->data_type == SQLT_INTERVAL_DS)
     753             : #endif
     754             :                                                 ) {
     755        1092 :                                                 outcol->storage_size4 = 512; /* XXX this should fit "most" NLS date-formats and Numbers */
     756             : #if defined(SQLT_IBFLOAT) && defined(SQLT_IBDOUBLE)
     757         841 :                                         } else if (outcol->data_type == SQLT_IBFLOAT || outcol->data_type == SQLT_IBDOUBLE) {
     758           5 :                                                 outcol->storage_size4 = 1024;
     759             : #endif
     760             :                                         } else {
     761         831 :                                                 outcol->storage_size4++; /* add one for string terminator */
     762             :                                         }
     763             :                                         
     764        1928 :                                         outcol->storage_size4 *= 3;
     765             :                                         
     766        1928 :                                         dynamic = OCI_DEFAULT;
     767        1928 :                                         buf = outcol->data = (text *) safe_emalloc(1, outcol->storage_size4, 0);
     768        1928 :                                         memset(buf, 0, outcol->storage_size4);
     769             :                                         break;
     770             :                         }
     771             : 
     772       63480 :                         if (dynamic == OCI_DYNAMIC_FETCH) {
     773       61552 :                                 PHP_OCI_CALL_RETURN(errstatus,
     774             :                                         OCIDefineByPos,
     775             :                                         (
     776             :                                                 statement->stmt,                                                     /* IN/OUT handle to the requested SQL query */
     777             :                                                 (OCIDefine **)&outcol->oci_define,                       /* IN/OUT pointer to a pointer to a define handle */
     778             :                                                 statement->err,                                                              /* IN/OUT An error handle  */
     779             :                                                 counter,                                                                        /* IN     position in the select list */
     780             :                                                 (dvoid *)NULL,                                                          /* IN/OUT pointer to a buffer */
     781             :                                                 outcol->storage_size4,                                               /* IN     The size of each valuep buffer in bytes */
     782             :                                                 define_type,                                                            /* IN     The data type */
     783             :                                                 (dvoid *)&outcol->indicator,                             /* IN     pointer to an indicator variable or arr */
     784             :                                                 (ub2 *)NULL,                                                            /* IN/OUT Pointer to array of length of data fetched */
     785             :                                                 (ub2 *)NULL,                                                            /* OUT    Pointer to array of column-level return codes */
     786             :                                                 OCI_DYNAMIC_FETCH                                                       /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
     787             :                                         )
     788             :                                 );
     789             : 
     790             :                         } else {
     791        1928 :                                 PHP_OCI_CALL_RETURN(errstatus,
     792             :                                         OCIDefineByPos,
     793             :                                         (
     794             :                                                 statement->stmt,                                                     /* IN/OUT handle to the requested SQL query */
     795             :                                                 (OCIDefine **)&outcol->oci_define,                       /* IN/OUT pointer to a pointer to a define handle */
     796             :                                                 statement->err,                                                              /* IN/OUT An error handle  */
     797             :                                                 counter,                                                                        /* IN     position in the select list */
     798             :                                                 (dvoid *)buf,                                                           /* IN/OUT pointer to a buffer */
     799             :                                                 outcol->storage_size4,                                               /* IN     The size of each valuep buffer in bytes */
     800             :                                                 define_type,                                                            /* IN     The data type */
     801             :                                                 (dvoid *)&outcol->indicator,                             /* IN     pointer to an indicator variable or arr */
     802             :                                                 (ub2 *)&outcol->retlen,                                          /* IN/OUT Pointer to array of length of data fetched */
     803             :                                                 (ub2 *)&outcol->retcode,                                 /* OUT    Pointer to array of column-level return codes */
     804             :                                                 OCI_DEFAULT                                                                     /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
     805             :                                         )
     806             :                                 );
     807             : 
     808             :                         }
     809             :                         
     810       63480 :                         if (errstatus != OCI_SUCCESS) {
     811           0 :                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     812           0 :                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     813           0 :                                 return 1;
     814             :                         }
     815             : 
     816             :                         /* additional OCIDefineDynamic() call */
     817       63480 :                         switch (outcol->data_type) {
     818             :                                 case SQLT_RSET:
     819             :                                 case SQLT_RDD:
     820             :                                 case SQLT_BLOB:
     821             :                                 case SQLT_CLOB:
     822             :                                 case SQLT_BFILE:
     823       61547 :                                         PHP_OCI_CALL_RETURN(errstatus,
     824             :                                                 OCIDefineDynamic,
     825             :                                                 (
     826             :                                                         outcol->oci_define,
     827             :                                                         statement->err,
     828             :                                                         (dvoid *)outcol,
     829             :                                                         php_oci_define_callback
     830             :                                                 )
     831             :                                         );
     832             : 
     833       61547 :                                         if (errstatus != OCI_SUCCESS) {
     834           0 :                                                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
     835           0 :                                                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
     836           0 :                                                 return 1;
     837             :                                         }
     838             :                                         break;
     839             :                         }
     840             :                 }
     841       32853 :                 statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     842             :         }
     843             : 
     844       37575 :         return 0;
     845             : }
     846             : /* }}} */
     847             : 
     848             : /* {{{ php_oci_statement_cancel()
     849             :  Cancel statement */
     850           8 : int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC)
     851             : {
     852           8 :         return php_oci_statement_fetch(statement, 0 TSRMLS_CC);
     853             : }
     854             : /* }}} */
     855             : 
     856             : /* {{{ php_oci_statement_free()
     857             :  Destroy statement handle and free associated resources */
     858       34501 : void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC)
     859             : {
     860       34501 :         if (statement->stmt) {
     861       34501 :                 if (statement->last_query_len) { /* FIXME: magical */
     862       33056 :                         PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT));
     863        1445 :                 } else if (statement->impres_flag != PHP_OCI_IMPRES_IS_CHILD) {  /* Oracle doc says don't free Implicit Result Set handles */
     864        1445 :                         PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT));
     865             :                 }
     866       34501 :                 statement->stmt = NULL;
     867             :         }
     868             : 
     869       34501 :         if (statement->err) {
     870       34501 :                 PHP_OCI_CALL(OCIHandleFree, (statement->err, OCI_HTYPE_ERROR));
     871       34501 :                 statement->err = NULL;
     872             :         }
     873             : 
     874       34501 :         if (statement->last_query) {
     875       33056 :                 efree(statement->last_query);
     876             :         }
     877             : 
     878       34501 :         if (statement->columns) {
     879       32835 :                 zend_hash_destroy(statement->columns);
     880       32835 :                 efree(statement->columns);
     881             :         }
     882             : 
     883       34501 :         if (statement->binds) {
     884         397 :                 zend_hash_destroy(statement->binds);
     885         397 :                 efree(statement->binds);
     886             :         }
     887             : 
     888       34501 :         if (statement->defines) {
     889       15037 :                 zend_hash_destroy(statement->defines);
     890       15037 :                 efree(statement->defines);
     891             :         }
     892             : 
     893       34501 :         if (statement->parent_stmtid) {
     894        1417 :                 zend_list_delete(statement->parent_stmtid);
     895             :         }
     896             : 
     897       34501 :         zend_list_delete(statement->connection->id);
     898       34501 :         efree(statement);
     899             :         
     900       34501 :         OCI_G(num_statements)--;
     901       34501 : }
     902             : /* }}} */
     903             : 
     904             : /* {{{ php_oci_bind_pre_exec()
     905             :  Helper function */
     906        5794 : int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC)
     907             : {
     908        5794 :         php_oci_bind *bind = (php_oci_bind *) data;
     909             : 
     910        5794 :         *(int *)result = 0;
     911             : 
     912        5794 :         if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
     913             :                 /* These checks are currently valid for oci_bind_by_name, not
     914             :                  * oci_bind_array_by_name.  Also bind->type and
     915             :                  * bind->indicator are not used for oci_bind_array_by_name.
     916             :                  */
     917          23 :                 return 0;
     918             :         }       
     919        5771 :         switch (bind->type) {
     920             :                 case SQLT_NTY:
     921             :                 case SQLT_BFILEE:
     922             :                 case SQLT_CFILEE:
     923             :                 case SQLT_CLOB:
     924             :                 case SQLT_BLOB:
     925             :                 case SQLT_RDD:
     926         193 :                         if (Z_TYPE_P(bind->zval) != IS_OBJECT) {
     927           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
     928           0 :                                 *(int *)result = 1;
     929             :                         }
     930         193 :                         break;
     931             :                         
     932             :                 case SQLT_CHR:
     933             :                 case SQLT_AFC:
     934             :                 case SQLT_INT:
     935             :                 case SQLT_NUM:
     936             : #if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
     937             :                 case SQLT_BOL:
     938             : #endif
     939             :                 case SQLT_LBI:
     940             :                 case SQLT_BIN:
     941             :                 case SQLT_LNG:
     942        5543 :                         if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) {
     943           2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
     944           2 :                                 *(int *)result = 1;
     945             :                         }
     946        5543 :                         break;
     947             : 
     948             :                 case SQLT_RSET:
     949          35 :                         if (Z_TYPE_P(bind->zval) != IS_RESOURCE) {
     950           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
     951           0 :                                 *(int *)result = 1;
     952             :                         }
     953             :                         break;
     954             :         }
     955             : 
     956             :         /* reset all bind stuff to a normal state... */
     957        5771 :         bind->indicator = 0;
     958             : 
     959        5771 :         return 0;
     960             : }
     961             : /* }}} */
     962             : 
     963             : /* {{{ php_oci_bind_post_exec()
     964             :  Helper function */
     965        5765 : int php_oci_bind_post_exec(void *data TSRMLS_DC)
     966             : {
     967        5765 :         php_oci_bind *bind = (php_oci_bind *) data;
     968        5765 :         php_oci_connection *connection = bind->parent_statement->connection;
     969             :         sword errstatus;
     970             : 
     971        5765 :         if (bind->indicator == -1) { /* NULL */
     972          73 :                 zval *val = bind->zval;
     973          73 :                 if (Z_TYPE_P(val) == IS_STRING) {
     974          31 :                         *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */
     975             :                 }
     976             :                 zval_dtor(val);
     977          73 :                 ZVAL_NULL(val);
     978       20971 :         } else if (Z_TYPE_P(bind->zval) == IS_STRING
     979       10496 :                            && Z_STRLEN_P(bind->zval) > 0
     980        9587 :                            && Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] != '\0') {
     981             :                 /* The post- PHP 5.3 feature for "interned" strings disallows
     982             :                  * their reallocation but (i) any IN binds either interned or
     983             :                  * not should already be null terminated and (ii) for OUT
     984             :                  * binds, php_oci_bind_out_callback() should have allocated a
     985             :                  * new string that we can modify here.
     986             :                  */
     987           0 :                 Z_STRVAL_P(bind->zval) = erealloc(Z_STRVAL_P(bind->zval), Z_STRLEN_P(bind->zval)+1);
     988           0 :                 Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0';
     989        5692 :         } else if (Z_TYPE_P(bind->zval) == IS_ARRAY) {
     990             :                 int i;
     991             :                 zval **entry;
     992          20 :                 HashTable *hash = HASH_OF(bind->zval);
     993             :         
     994          20 :                 zend_hash_internal_pointer_reset(hash);
     995             : 
     996          20 :                 switch (bind->array.type) {
     997             :                         case SQLT_NUM:
     998             :                         case SQLT_INT:
     999             :                         case SQLT_LNG:
    1000          18 :                                 for (i = 0; i < bind->array.current_length; i++) {
    1001          25 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1002          10 :                                                 zval_dtor(*entry);
    1003          10 :                                                 ZVAL_LONG(*entry, ((ub4 *)(bind->array.elements))[i]);
    1004          10 :                                                 zend_hash_move_forward(hash);
    1005             :                                         } else {
    1006           5 :                                                 add_next_index_long(bind->zval, ((ub4 *)(bind->array.elements))[i]);
    1007             :                                         }
    1008             :                                 }
    1009           3 :                                 break;
    1010             :                         case SQLT_FLT:
    1011          12 :                                 for (i = 0; i < bind->array.current_length; i++) {
    1012          20 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1013          10 :                                                 zval_dtor(*entry);
    1014          10 :                                                 ZVAL_DOUBLE(*entry, ((double *)(bind->array.elements))[i]);
    1015          10 :                                                 zend_hash_move_forward(hash);
    1016             :                                         } else {
    1017           0 :                                                 add_next_index_double(bind->zval, ((double *)(bind->array.elements))[i]);
    1018             :                                         }
    1019             :                                 }
    1020           2 :                                 break;
    1021             :                         case SQLT_ODT:
    1022          12 :                                 for (i = 0; i < bind->array.current_length; i++) {
    1023             :                                         oratext buff[1024];
    1024          10 :                                         ub4 buff_len = 1024;
    1025             : 
    1026          10 :                                         memset((void*)buff,0,sizeof(buff));
    1027             :                                                         
    1028          20 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1029          10 :                                                 PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
    1030          10 :                                                 zval_dtor(*entry);
    1031             : 
    1032          10 :                                                 if (errstatus != OCI_SUCCESS) {
    1033           0 :                                                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
    1034           0 :                                                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1035           0 :                                                         ZVAL_NULL(*entry);
    1036             :                                                 } else {
    1037          10 :                                                         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1038          10 :                                                         ZVAL_STRINGL(*entry, (char *)buff, buff_len, 1);
    1039             :                                                 }
    1040          10 :                                                 zend_hash_move_forward(hash);
    1041             :                                         } else {
    1042           0 :                                                 PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff));
    1043           0 :                                                 if (errstatus != OCI_SUCCESS) {
    1044           0 :                                                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
    1045           0 :                                                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1046           0 :                                                         add_next_index_null(bind->zval);
    1047             :                                                 } else {
    1048           0 :                                                         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1049           0 :                                                         add_next_index_stringl(bind->zval, (char *)buff, buff_len, 1);
    1050             :                                                 }
    1051             :                                         }
    1052             :                                 }
    1053           2 :                                 break;
    1054             :         
    1055             :                         case SQLT_AFC:
    1056             :                         case SQLT_CHR:
    1057             :                         case SQLT_VCS:
    1058             :                         case SQLT_AVC:
    1059             :                         case SQLT_STR:
    1060             :                         case SQLT_LVC:
    1061         169 :                                 for (i = 0; i < bind->array.current_length; i++) {
    1062             :                                         /* int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); */
    1063         156 :                                         int curr_element_length = bind->array.element_lengths[i];
    1064         206 :                                         if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1065          50 :                                                 zval_dtor(*entry);
    1066          50 :                                                 ZVAL_STRINGL(*entry, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
    1067          50 :                                                 zend_hash_move_forward(hash);
    1068             :                                         } else {
    1069         106 :                                                 add_next_index_stringl(bind->zval, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length, 1);
    1070             :                                         }
    1071             :                                 }
    1072             :                                 break;
    1073             :                 }
    1074             :         }
    1075             : 
    1076        5765 :         return 0;
    1077             : }
    1078             : /* }}} */
    1079             : 
    1080             : /* {{{ php_oci_bind_by_name()
    1081             :  Bind zval to the given placeholder */
    1082        4177 : int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long maxlength, ub2 type TSRMLS_DC)
    1083             : {
    1084        4177 :         php_oci_collection *bind_collection = NULL;
    1085        4177 :         php_oci_descriptor *bind_descriptor = NULL;
    1086        4177 :         php_oci_statement  *bind_statement      = NULL;
    1087        4177 :         dvoid *oci_desc                                 = NULL;
    1088             :         /* dvoid *php_oci_collection               = NULL; */
    1089        4177 :         OCIStmt *oci_stmt                               = NULL;
    1090        4177 :         dvoid *bind_data                                = NULL;
    1091             :         php_oci_bind bind, *old_bind, *bindp;
    1092        4177 :         int mode = OCI_DATA_AT_EXEC;
    1093        4177 :         sb4 value_sz = -1;
    1094             :         sword errstatus;
    1095             : 
    1096        4177 :         switch (type) {
    1097             :                 case SQLT_NTY:
    1098             :                 {
    1099             :                         zval **tmp;
    1100             :                         
    1101           1 :                         if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "collection", sizeof("collection"), (void **)&tmp) == FAILURE) {
    1102           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find collection property");
    1103           0 :                                 return 1;
    1104             :                         }
    1105             : 
    1106           1 :                         PHP_OCI_ZVAL_TO_COLLECTION_EX(*tmp, bind_collection);
    1107           1 :                         value_sz = sizeof(void*);
    1108           1 :                         mode = OCI_DEFAULT;
    1109             :                 
    1110           1 :                         if (!bind_collection->collection) {
    1111           0 :                                 return 1;
    1112             :                         }
    1113             :                 }
    1114           1 :                         break;
    1115             :                 case SQLT_BFILEE:
    1116             :                 case SQLT_CFILEE:
    1117             :                 case SQLT_CLOB:
    1118             :                 case SQLT_BLOB:
    1119             :                 case SQLT_RDD:
    1120             :                 {
    1121             :                         zval **tmp;
    1122             :                         
    1123         185 :                         if (Z_TYPE_P(var) != IS_OBJECT || zend_hash_find(Z_OBJPROP_P(var), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
    1124           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find descriptor property");
    1125           0 :                                 return 1;
    1126             :                         }
    1127             : 
    1128         185 :                         PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, bind_descriptor);
    1129             : 
    1130         185 :                         value_sz = sizeof(void*);
    1131             :                         
    1132         185 :                         oci_desc = bind_descriptor->descriptor;
    1133             :                         
    1134         185 :                         if (!oci_desc) {
    1135           0 :                                 return 1;
    1136             :                         }
    1137             :                 }
    1138         185 :                         break;
    1139             :                         
    1140             :                 case SQLT_INT:
    1141             :                 case SQLT_NUM:
    1142          52 :                         if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
    1143           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
    1144           0 :                                 return 1;
    1145             :                         }
    1146          52 :                         convert_to_long(var);
    1147          52 :                         bind_data = (ub4 *)&Z_LVAL_P(var);
    1148          52 :                         value_sz = sizeof(ub4);
    1149          52 :                         mode = OCI_DEFAULT;
    1150          52 :                         break;
    1151             :                         
    1152             :                 case SQLT_LBI:
    1153             :                 case SQLT_BIN:
    1154             :                 case SQLT_LNG:
    1155             :                 case SQLT_AFC:
    1156             :                 case SQLT_CHR: /* SQLT_CHR is the default value when type was not specified */
    1157        3892 :                         if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
    1158           2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
    1159           2 :                                 return 1;
    1160             :                         }
    1161        3890 :                         if (Z_TYPE_P(var) != IS_NULL) {
    1162        3809 :                                 convert_to_string(var);
    1163             :                         }
    1164        3890 :                         if (maxlength == -1) {
    1165        3798 :                                 value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0;
    1166             :                         } else {
    1167          92 :                                 value_sz = maxlength;
    1168             :                         }
    1169        3890 :                         break;
    1170             : 
    1171             :                 case SQLT_RSET:
    1172          38 :                         if (Z_TYPE_P(var) != IS_RESOURCE) {
    1173           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
    1174           0 :                                 return 1;
    1175             :                         }
    1176          38 :                         PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement);
    1177          38 :                         value_sz = sizeof(void*);
    1178             : 
    1179          38 :                         oci_stmt = bind_statement->stmt;
    1180             : 
    1181          38 :                         if (!oci_stmt) {
    1182           0 :                                 return 1;
    1183             :                         }
    1184          38 :                         break;
    1185             : 
    1186             : #if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
    1187             :                 case SQLT_BOL:
    1188             :                         if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
    1189             :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid variable used for bind");
    1190             :                                 return 1;
    1191             :                         }
    1192             :                         convert_to_boolean(var);
    1193             :                         bind_data = (int *)&Z_LVAL_P(var);
    1194             :                         value_sz = sizeof(int);
    1195             : 
    1196             :                         mode = OCI_DEFAULT;
    1197             :                         break;
    1198             : #endif
    1199             : 
    1200             :                 default:
    1201           9 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %d", (int)type);
    1202           9 :                         return 1;
    1203             :                         break;
    1204             :         }
    1205             :         
    1206        4166 :         if (value_sz == 0) {
    1207          62 :                 value_sz = 1;
    1208             :         }
    1209             :         
    1210        4166 :         if (!statement->binds) {
    1211         377 :                 ALLOC_HASHTABLE(statement->binds);
    1212         377 :                 zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
    1213             :         }
    1214             : 
    1215        4166 :         memset((void*)&bind,0,sizeof(php_oci_bind));
    1216        4166 :         if (zend_hash_find(statement->binds, name, name_len + 1, (void **)&old_bind) == SUCCESS) {
    1217        3625 :                 bindp = old_bind;
    1218        3625 :                 if (bindp->zval) {
    1219        3625 :                         zval_ptr_dtor(&bindp->zval);
    1220             :                 }
    1221             :         } else {
    1222         541 :                 zend_hash_update(statement->binds, name, name_len + 1, &bind, sizeof(php_oci_bind), (void **)&bindp);
    1223             :         }
    1224             :         
    1225        4166 :         bindp->descriptor = oci_desc;
    1226        4166 :         bindp->statement = oci_stmt;
    1227        4166 :         bindp->parent_statement = statement;
    1228        4166 :         bindp->zval = var;
    1229        4166 :         bindp->type = type;
    1230        4166 :         zval_add_ref(&var);
    1231             :         
    1232        4166 :         PHP_OCI_CALL_RETURN(errstatus,
    1233             :                 OCIBindByName,
    1234             :                 (
    1235             :                         statement->stmt,                              /* statement handle */
    1236             :                         (OCIBind **)&bindp->bind,                 /* bind hdl (will alloc) */
    1237             :                         statement->err,                                       /* error handle */
    1238             :                         (text*) name,                                    /* placeholder name */                                 
    1239             :                         name_len,                                                /* placeholder length */
    1240             :                         (dvoid *)bind_data,                              /* in/out data */
    1241             :                         value_sz, /* PHP_OCI_MAX_DATA_SIZE, */ /* max size of input/output data */
    1242             :                         type,                                                    /* in/out data type */
    1243             :                         (dvoid *)&bindp->indicator,               /* indicator (ignored) */
    1244             :                         (ub2 *)0,                                                /* size array (ignored) */
    1245             :                         (ub2 *)&bindp->retcode,                   /* return code (ignored) */
    1246             :                         (ub4)0,                                                  /* maxarr_len (PL/SQL only?) */
    1247             :                         (ub4 *)0,                                                /* actual array size (PL/SQL only?) */
    1248             :                         mode                                                     /* mode */
    1249             :                 )
    1250             :         );
    1251             : 
    1252        4166 :         if (errstatus != OCI_SUCCESS) {
    1253           2 :                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1254           2 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1255           2 :                 return 1;
    1256             :         }
    1257             : 
    1258        4164 :         if (mode == OCI_DATA_AT_EXEC) {
    1259        4111 :                 PHP_OCI_CALL_RETURN(errstatus, OCIBindDynamic,
    1260             :                                 (
    1261             :                                  bindp->bind,
    1262             :                                  statement->err,
    1263             :                                  (dvoid *)bindp,
    1264             :                                  php_oci_bind_in_callback,
    1265             :                                  (dvoid *)bindp,
    1266             :                                  php_oci_bind_out_callback
    1267             :                                 )
    1268             :                 );
    1269             : 
    1270        4111 :                 if (errstatus != OCI_SUCCESS) {
    1271           0 :                         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1272           0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1273           0 :                         return 1;
    1274             :                 }
    1275             :         }
    1276             : 
    1277        4164 :         if (type == SQLT_NTY) {
    1278             :                 /* Bind object */
    1279           1 :                 PHP_OCI_CALL_RETURN(errstatus, OCIBindObject,
    1280             :                                 (
    1281             :                                  bindp->bind,
    1282             :                                  statement->err,
    1283             :                                  bind_collection->tdo,
    1284             :                                  (dvoid **) &(bind_collection->collection),
    1285             :                                  (ub4 *) 0,
    1286             :                                  (dvoid **) 0,
    1287             :                                  (ub4 *) 0
    1288             :                                 )
    1289             :                 );
    1290             :                 
    1291           1 :                 if (errstatus) {
    1292           0 :                         statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1293           0 :                         PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1294           0 :                         return 1;
    1295             :                 }
    1296             :         }
    1297             :         
    1298        4164 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1299        4164 :         return 0;
    1300             : }
    1301             : /* }}} */
    1302             : 
    1303             : /* {{{ php_oci_bind_in_callback()
    1304             :  Callback used when binding LOBs and VARCHARs */
    1305        4351 : sb4 php_oci_bind_in_callback(
    1306             :                                         dvoid *ictxp,     /* context pointer */
    1307             :                                         OCIBind *bindp,   /* bind handle */
    1308             :                                         ub4 iter,                 /* 0-based execute iteration value */
    1309             :                                         ub4 index,                /* index of current array for PL/SQL or row index for SQL */
    1310             :                                         dvoid **bufpp,    /* pointer to data */
    1311             :                                         ub4 *alenp,               /* size after value/piece has been read */
    1312             :                                         ub1 *piecep,      /* which piece */
    1313             :                                         dvoid **indpp)    /* indicator value */
    1314             : {
    1315             :         php_oci_bind *phpbind;
    1316             :         zval *val;
    1317             :         TSRMLS_FETCH();
    1318             : 
    1319        4351 :         if (!(phpbind=(php_oci_bind *)ictxp) || !(val = phpbind->zval)) {
    1320           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
    1321           0 :                 return OCI_ERROR;
    1322             :         }
    1323             : 
    1324        4351 :         if (ZVAL_IS_NULL(val)) {
    1325             :                 /* we're going to insert a NULL column */
    1326          51 :                 phpbind->indicator = -1;
    1327          51 :                 *bufpp = 0;
    1328          51 :                 *alenp = -1;
    1329          51 :                 *indpp = (dvoid *)&phpbind->indicator;
    1330        8394 :         } else  if ((phpbind->descriptor == 0) && (phpbind->statement == 0)) {
    1331             :                 /* "normal string bind */
    1332        4094 :                 convert_to_string(val);
    1333             : 
    1334        4094 :                 *bufpp = Z_STRVAL_P(val);
    1335        4094 :                 *alenp = Z_STRLEN_P(val);
    1336        4094 :                 *indpp = (dvoid *)&phpbind->indicator;
    1337         206 :         } else if (phpbind->statement != 0) {
    1338             :                 /* RSET */
    1339          23 :                 *bufpp = phpbind->statement;
    1340          23 :                 *alenp = -1;            /* seems to be allright */
    1341          23 :                 *indpp = (dvoid *)&phpbind->indicator;
    1342             :         } else {
    1343             :                 /* descriptor bind */
    1344         183 :                 *bufpp = phpbind->descriptor;
    1345         183 :                 *alenp = -1;            /* seems to be allright */
    1346         183 :                 *indpp = (dvoid *)&phpbind->indicator;
    1347             :         }
    1348             : 
    1349        4351 :         *piecep = OCI_ONE_PIECE; /* pass all data in one go */
    1350             : 
    1351        4351 :         return OCI_CONTINUE;
    1352             : }
    1353             : /* }}} */
    1354             : 
    1355             : /* {{{ php_oci_bind_out_callback()
    1356             :  Callback used when binding LOBs and VARCHARs */
    1357         867 : sb4 php_oci_bind_out_callback(
    1358             :                                         dvoid *octxp,      /* context pointer */
    1359             :                                         OCIBind *bindp,    /* bind handle */
    1360             :                                         ub4 iter,                  /* 0-based execute iteration value */
    1361             :                                         ub4 index,                 /* index of current array for PL/SQL or row index for SQL */
    1362             :                                         dvoid **bufpp,     /* pointer to data */
    1363             :                                         ub4 **alenpp,      /* size after value/piece has been read */
    1364             :                                         ub1 *piecep,       /* which piece */
    1365             :                                         dvoid **indpp,     /* indicator value */
    1366             :                                         ub2 **rcodepp)     /* return code */
    1367             : {
    1368             :         php_oci_bind *phpbind;
    1369             :         zval *val;
    1370         867 :         sb4 retval = OCI_ERROR;
    1371             :         TSRMLS_FETCH();
    1372             : 
    1373         867 :         if (!(phpbind=(php_oci_bind *)octxp) || !(val = phpbind->zval)) {
    1374           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid phpbind pointer value");
    1375           0 :                 return retval;
    1376             :         }
    1377             : 
    1378         867 :         if (Z_TYPE_P(val) == IS_RESOURCE) {
    1379             :                 /* Processing for ref-cursor out binds */
    1380          31 :                 if (phpbind->statement != NULL) {
    1381          31 :                         *bufpp = phpbind->statement;
    1382          31 :                         *alenpp = &phpbind->dummy_len;
    1383          31 :                         *piecep = OCI_ONE_PIECE;
    1384          31 :                         *rcodepp = &phpbind->retcode;
    1385          31 :                         *indpp = &phpbind->indicator;
    1386             :                 }
    1387          31 :                 retval = OCI_CONTINUE;
    1388         836 :         } else if (Z_TYPE_P(val) == IS_OBJECT) {
    1389             :                 zval **tmp;
    1390             :                 php_oci_descriptor *desc;
    1391             : 
    1392          80 :                 if (!phpbind->descriptor) {
    1393           0 :                         return OCI_ERROR;
    1394             :                 }
    1395             : 
    1396             :                 /* Do not use the cached lob size if the descriptor is an
    1397             :                  * out-bind as the contents would have been changed for in/out
    1398             :                  * binds (Bug #46994).
    1399             :                  */
    1400          80 :                 if (zend_hash_find(Z_OBJPROP_P(val), "descriptor", sizeof("descriptor"), (void **)&tmp) == FAILURE) {
    1401           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find object outbind descriptor property");
    1402           0 :                         return OCI_ERROR;
    1403             :                 }
    1404          80 :                 PHP_OCI_ZVAL_TO_DESCRIPTOR_EX(*tmp, desc);
    1405          80 :                 desc->lob_size = -1; /* force OCI8 to update cached size */
    1406             : 
    1407          80 :                 *alenpp = &phpbind->dummy_len;
    1408          80 :                 *bufpp = phpbind->descriptor;
    1409          80 :                 *piecep = OCI_ONE_PIECE;
    1410          80 :                 *rcodepp = &phpbind->retcode;
    1411          80 :                 *indpp = &phpbind->indicator;
    1412          80 :                 retval = OCI_CONTINUE;
    1413             :         } else {
    1414         756 :                 convert_to_string(val);
    1415             :                 zval_dtor(val);
    1416             :                 
    1417         756 :                 Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */
    1418         756 :                 Z_STRVAL_P(val) = ecalloc(1, Z_STRLEN_P(phpbind->zval) + 1);
    1419             :                 
    1420             :                 /* XXX we assume that zend-zval len has 4 bytes */
    1421         756 :                 *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval);
    1422         756 :                 *bufpp = Z_STRVAL_P(phpbind->zval);
    1423         756 :                 *piecep = OCI_ONE_PIECE;
    1424         756 :                 *rcodepp = &phpbind->retcode;
    1425         756 :                 *indpp = &phpbind->indicator;
    1426         756 :                 retval = OCI_CONTINUE;
    1427             :         }
    1428             : 
    1429         867 :         return retval;
    1430             : }
    1431             : /* }}} */
    1432             : 
    1433             : /* {{{ php_oci_statement_get_column_helper()
    1434             :  Helper function to get column by name and index */
    1435         416 : php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data)
    1436             : {
    1437             :         zval *z_statement, *column_index;
    1438             :         php_oci_statement *statement;
    1439             :         php_oci_out_column *column;
    1440             : 
    1441         416 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_statement, &column_index) == FAILURE) {
    1442           9 :                 return NULL;
    1443             :         }
    1444             : 
    1445         407 :         statement = (php_oci_statement *) zend_fetch_resource(&z_statement TSRMLS_CC, -1, "oci8 statement", NULL, 1, le_statement);
    1446             : 
    1447         407 :         if (!statement) {
    1448           8 :                 return NULL;
    1449             :         }
    1450             : 
    1451         399 :         if (need_data && !statement->has_data) {
    1452           1 :                 return NULL;
    1453             :         }
    1454             :         
    1455         398 :         if (Z_TYPE_P(column_index) == IS_STRING) {
    1456          76 :                 column = php_oci_statement_get_column(statement, -1, Z_STRVAL_P(column_index), Z_STRLEN_P(column_index) TSRMLS_CC);
    1457          76 :                 if (!column) {
    1458           7 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column name \"%s\"", Z_STRVAL_P(column_index));
    1459           7 :                         return NULL;
    1460             :                 }
    1461             :         } else {
    1462             :                 zval tmp;
    1463             :                 /* NB: for PHP4 compat only, it should be using 'Z' instead */
    1464         322 :                 tmp = *column_index;
    1465             :                 zval_copy_ctor(&tmp);
    1466         322 :                 convert_to_long(&tmp);
    1467         322 :                 column = php_oci_statement_get_column(statement, Z_LVAL(tmp), NULL, 0 TSRMLS_CC);
    1468         322 :                 if (!column) {
    1469          14 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid column index \"%ld\"", Z_LVAL(tmp));
    1470             :                         zval_dtor(&tmp);
    1471          14 :                         return NULL;
    1472             :                 }
    1473             :                 zval_dtor(&tmp);
    1474             :         }
    1475         377 :         return column;
    1476             : }
    1477             : /* }}} */
    1478             : 
    1479             : /* {{{ php_oci_statement_get_type()
    1480             :  Return type of the statement */
    1481          26 : int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC)
    1482             : {
    1483             :         ub2 statement_type;
    1484             :         sword errstatus;
    1485             :         
    1486          26 :         *type = 0;
    1487             :         
    1488          26 :         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err));
    1489             : 
    1490          26 :         if (errstatus != OCI_SUCCESS) {
    1491           0 :                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1492           0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1493           0 :                 return 1;
    1494             :         }
    1495          26 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1496          26 :         *type = statement_type;
    1497             : 
    1498          26 :         return 0;
    1499             : }
    1500             : /* }}} */
    1501             : 
    1502             : /* {{{ php_oci_statement_get_numrows()
    1503             :  Get the number of rows fetched to the clientside (NOT the number of rows in the result set) */
    1504          26 : int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC)
    1505             : {
    1506             :         ub4 statement_numrows;
    1507             :         sword errstatus;
    1508             :         
    1509          26 :         *numrows = 0;
    1510             :         
    1511          26 :         PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err));
    1512             : 
    1513          26 :         if (errstatus != OCI_SUCCESS) {
    1514           0 :                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1515           0 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1516           0 :                 return 1;
    1517             :         }
    1518          26 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1519          26 :         *numrows = statement_numrows;
    1520             : 
    1521          26 :         return 0;
    1522             : }
    1523             : /* }}} */
    1524             : 
    1525             : /* {{{ php_oci_bind_array_by_name()
    1526             :  Bind arrays to PL/SQL types */
    1527          32 : int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long max_table_length, long maxlength, long type TSRMLS_DC)
    1528             : {
    1529             :         php_oci_bind *bind, *bindp;
    1530             :         sword errstatus;
    1531             : 
    1532          32 :         convert_to_array(var);
    1533             : 
    1534          32 :         if (maxlength < -1) {
    1535           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid max length value (%ld)", maxlength);
    1536           1 :                 return 1;
    1537             :         }
    1538             :         
    1539          31 :         switch(type) {
    1540             :                 case SQLT_NUM:
    1541             :                 case SQLT_INT:
    1542             :                 case SQLT_LNG:
    1543           3 :                         bind = php_oci_bind_array_helper_number(var, max_table_length TSRMLS_CC);
    1544           3 :                         break;
    1545             : 
    1546             :                 case SQLT_FLT:
    1547           2 :                         bind = php_oci_bind_array_helper_double(var, max_table_length TSRMLS_CC);
    1548           2 :                         break;
    1549             :                         
    1550             :                 case SQLT_AFC:
    1551             :                 case SQLT_CHR:
    1552             :                 case SQLT_VCS:
    1553             :                 case SQLT_AVC:
    1554             :                 case SQLT_STR:
    1555             :                 case SQLT_LVC:
    1556          17 :                         if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(var)) == 0) {
    1557           4 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must provide max length value for empty arrays");
    1558           4 :                                 return 1;
    1559             :                         }
    1560          13 :                         bind = php_oci_bind_array_helper_string(var, max_table_length, maxlength TSRMLS_CC);
    1561          13 :                         break;
    1562             :                 case SQLT_ODT:
    1563           5 :                         bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection TSRMLS_CC);
    1564           5 :                         break;
    1565             :                 default:
    1566           4 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or unsupported datatype given: %ld", type);
    1567           4 :                         return 1;
    1568             :                         break;
    1569             :         }
    1570             : 
    1571          23 :         if (bind == NULL) {
    1572             :                 /* failed to generate bind struct */
    1573           1 :                 return 1;
    1574             :         }
    1575             :         
    1576          22 :         if (!statement->binds) {
    1577          20 :                 ALLOC_HASHTABLE(statement->binds);
    1578          20 :                 zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0);
    1579             :         }
    1580             : 
    1581          22 :         zend_hash_update(statement->binds, name, name_len + 1, bind, sizeof(php_oci_bind), (void **)&bindp);
    1582             : 
    1583          22 :         bindp->descriptor = NULL;
    1584          22 :         bindp->statement = NULL;
    1585          22 :         bindp->parent_statement = statement;
    1586          22 :         bindp->bind = NULL;
    1587          22 :         bindp->zval = var;
    1588          22 :         bindp->array.type = type;
    1589          22 :         bindp->indicator = 0;                /* not used for array binds */
    1590          22 :         bindp->type = 0;                     /* not used for array binds */
    1591             : 
    1592          22 :         zval_add_ref(&var);
    1593             : 
    1594          22 :         PHP_OCI_CALL_RETURN(errstatus,
    1595             :                                                         OCIBindByName,
    1596             :                                                         (
    1597             :                                                                 statement->stmt,
    1598             :                                                                 (OCIBind **)&bindp->bind,
    1599             :                                                                 statement->err,
    1600             :                                                                 (text *)name,
    1601             :                                                                 name_len,
    1602             :                                                                 (dvoid *) bindp->array.elements,
    1603             :                                                                 (sb4) bind->array.max_length,
    1604             :                                                                 (ub2)type,
    1605             :                                                                 (dvoid *)bindp->array.indicators,
    1606             :                                                                 (ub2 *)bind->array.element_lengths,
    1607             :                                                                 (ub2 *)0, /* bindp->array.retcodes, */
    1608             :                                                                 (ub4) max_table_length,
    1609             :                                                                 (ub4 *) &(bindp->array.current_length),
    1610             :                                                                 (ub4) OCI_DEFAULT
    1611             :                                                         )
    1612             :                                                 );
    1613             :         
    1614             :                 
    1615          22 :         if (errstatus != OCI_SUCCESS) {
    1616           1 :                 efree(bind);
    1617           1 :                 statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC);
    1618           1 :                 PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
    1619           1 :                 return 1;
    1620             :         }
    1621          21 :         statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1622          21 :         efree(bind);
    1623          21 :         return 0;
    1624             : }
    1625             : /* }}} */
    1626             : 
    1627             : /* {{{ php_oci_bind_array_helper_string()
    1628             :  Bind arrays to PL/SQL types */
    1629          13 : php_oci_bind *php_oci_bind_array_helper_string(zval *var, long max_table_length, long maxlength TSRMLS_DC)
    1630             : {
    1631             :         php_oci_bind *bind;
    1632             :         ub4 i;
    1633             :         HashTable *hash;
    1634             :         zval **entry;
    1635             : 
    1636          13 :         hash = HASH_OF(var);
    1637             : 
    1638          13 :         if (maxlength == -1) {
    1639           4 :                 zend_hash_internal_pointer_reset(hash);
    1640          28 :                 while (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
    1641          20 :                         convert_to_string_ex(entry);
    1642          20 :                         if (Z_STRLEN_PP(entry) > maxlength) {
    1643           8 :                                 maxlength = Z_STRLEN_PP(entry) + 1;
    1644             :                         }
    1645          20 :                         zend_hash_move_forward(hash);
    1646             :                 }
    1647             :         }
    1648             :         
    1649          13 :         bind = emalloc(sizeof(php_oci_bind));
    1650          13 :         bind->array.elements         = (text *)safe_emalloc(max_table_length * (maxlength + 1), sizeof(text), 0);
    1651          13 :         memset(bind->array.elements, 0, max_table_length * (maxlength + 1) * sizeof(text));
    1652          13 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1653          13 :         bind->array.old_length               = bind->array.current_length;
    1654          13 :         bind->array.max_length               = maxlength;
    1655          13 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1656          13 :         memset(bind->array.element_lengths, 0, max_table_length*sizeof(ub2));
    1657          13 :         bind->array.indicators               = safe_emalloc(max_table_length, sizeof(sb2), 0);
    1658          13 :         memset(bind->array.indicators, 0, max_table_length*sizeof(sb2));
    1659             :         
    1660          13 :         zend_hash_internal_pointer_reset(hash);
    1661             :         
    1662         126 :         for (i = 0; i < bind->array.current_length; i++) {
    1663          50 :                 if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
    1664          80 :                         convert_to_string_ex(entry);
    1665          50 :                         bind->array.element_lengths[i] = Z_STRLEN_PP(entry);
    1666          50 :                         if (Z_STRLEN_PP(entry) == 0) {
    1667           5 :                                 bind->array.indicators[i] = -1;
    1668             :                         }
    1669          50 :                         zend_hash_move_forward(hash);
    1670             :                 } else {
    1671           0 :                         break;
    1672             :                 }
    1673             :         }
    1674             : 
    1675          13 :         zend_hash_internal_pointer_reset(hash);
    1676         273 :         for (i = 0; i < max_table_length; i++) {
    1677         310 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1678             :                         int element_length;
    1679             :                         
    1680          50 :                         convert_to_string_ex(entry);
    1681          50 :                         element_length = (maxlength > Z_STRLEN_PP(entry)) ? Z_STRLEN_PP(entry) : maxlength;
    1682             :                         
    1683          50 :                         memcpy((text *)bind->array.elements + i*maxlength, Z_STRVAL_PP(entry), element_length);
    1684          50 :                         ((text *)bind->array.elements)[i*maxlength + element_length] = '\0';
    1685             :                         
    1686          50 :                         zend_hash_move_forward(hash);
    1687             :                 } else {
    1688         210 :                         ((text *)bind->array.elements)[i*maxlength] = '\0';
    1689             :                 }
    1690             :         }
    1691          13 :         zend_hash_internal_pointer_reset(hash);
    1692             : 
    1693          13 :         return bind;
    1694             : }
    1695             : /* }}} */
    1696             : 
    1697             : /* {{{ php_oci_bind_array_helper_number()
    1698             :  Bind arrays to PL/SQL types */
    1699           3 : php_oci_bind *php_oci_bind_array_helper_number(zval *var, long max_table_length TSRMLS_DC)
    1700             : {
    1701             :         php_oci_bind *bind;
    1702             :         ub4 i;
    1703             :         HashTable *hash;
    1704             :         zval **entry;
    1705             : 
    1706           3 :         hash = HASH_OF(var);
    1707             : 
    1708           3 :         bind = emalloc(sizeof(php_oci_bind));
    1709           3 :         bind->array.elements         = (ub4 *)safe_emalloc(max_table_length, sizeof(ub4), 0);
    1710           3 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1711           3 :         bind->array.old_length               = bind->array.current_length;
    1712           3 :         bind->array.max_length               = sizeof(ub4);
    1713           3 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1714           3 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1715           3 :         bind->array.indicators               = NULL;
    1716             :         
    1717           3 :         zend_hash_internal_pointer_reset(hash);
    1718          23 :         for (i = 0; i < max_table_length; i++) {
    1719          20 :                 if (i < bind->array.current_length) {
    1720          10 :                         bind->array.element_lengths[i] = sizeof(ub4);
    1721             :                 }
    1722          30 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1723          10 :                         convert_to_long_ex(entry);
    1724          10 :                         ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_PP(entry);
    1725          10 :                         zend_hash_move_forward(hash);
    1726             :                 } else {
    1727          10 :                         ((ub4 *)bind->array.elements)[i] = 0;
    1728             :                 }
    1729             :         }
    1730           3 :         zend_hash_internal_pointer_reset(hash);
    1731             : 
    1732           3 :         return bind;
    1733             : }
    1734             : /* }}} */
    1735             : 
    1736             : /* {{{ php_oci_bind_array_helper_double()
    1737             :  Bind arrays to PL/SQL types */
    1738           2 : php_oci_bind *php_oci_bind_array_helper_double(zval *var, long max_table_length TSRMLS_DC)
    1739             : {
    1740             :         php_oci_bind *bind;
    1741             :         ub4 i;
    1742             :         HashTable *hash;
    1743             :         zval **entry;
    1744             : 
    1745           2 :         hash = HASH_OF(var);
    1746             : 
    1747           2 :         bind = emalloc(sizeof(php_oci_bind));
    1748           2 :         bind->array.elements         = (double *)safe_emalloc(max_table_length, sizeof(double), 0);
    1749           2 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1750           2 :         bind->array.old_length               = bind->array.current_length;
    1751           2 :         bind->array.max_length               = sizeof(double);
    1752           2 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1753           2 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1754           2 :         bind->array.indicators               = NULL;
    1755             :         
    1756           2 :         zend_hash_internal_pointer_reset(hash);
    1757          17 :         for (i = 0; i < max_table_length; i++) {
    1758          15 :                 if (i < bind->array.current_length) {
    1759          10 :                         bind->array.element_lengths[i] = sizeof(double);
    1760             :                 }
    1761          25 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1762          10 :                         convert_to_double_ex(entry);
    1763          10 :                         ((double *)bind->array.elements)[i] = (double) Z_DVAL_PP(entry);
    1764          10 :                         zend_hash_move_forward(hash);
    1765             :                 } else {
    1766           5 :                         ((double *)bind->array.elements)[i] = 0;
    1767             :                 }
    1768             :         }
    1769           2 :         zend_hash_internal_pointer_reset(hash);
    1770             : 
    1771           2 :         return bind;
    1772             : }
    1773             : /* }}} */
    1774             : 
    1775             : /* {{{ php_oci_bind_array_helper_date()
    1776             :  Bind arrays to PL/SQL types */
    1777           5 : php_oci_bind *php_oci_bind_array_helper_date(zval *var, long max_table_length, php_oci_connection *connection TSRMLS_DC)
    1778             : {
    1779             :         php_oci_bind *bind;
    1780             :         ub4 i;
    1781             :         HashTable *hash;
    1782             :         zval **entry;
    1783             :         sword errstatus;
    1784             : 
    1785           5 :         hash = HASH_OF(var);
    1786             : 
    1787           5 :         bind = emalloc(sizeof(php_oci_bind));
    1788           5 :         bind->array.elements         = (OCIDate *)safe_emalloc(max_table_length, sizeof(OCIDate), 0);
    1789           5 :         bind->array.current_length   = zend_hash_num_elements(Z_ARRVAL_P(var));
    1790           5 :         bind->array.old_length               = bind->array.current_length;
    1791           5 :         bind->array.max_length               = sizeof(OCIDate);
    1792           5 :         bind->array.element_lengths  = safe_emalloc(max_table_length, sizeof(ub2), 0);
    1793           5 :         memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
    1794           5 :         bind->array.indicators               = NULL;
    1795             : 
    1796           5 :         zend_hash_internal_pointer_reset(hash);
    1797          30 :         for (i = 0; i < max_table_length; i++) {
    1798             :                 OCIDate oci_date;
    1799          26 :                 if (i < bind->array.current_length) {
    1800          15 :                         bind->array.element_lengths[i] = sizeof(OCIDate);
    1801             :                 }
    1802          40 :                 if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) {
    1803             :                         
    1804          15 :                         convert_to_string_ex(entry);
    1805          15 :                         PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date));
    1806             : 
    1807          15 :                         if (errstatus != OCI_SUCCESS) {
    1808             :                                 /* failed to convert string to date */
    1809           1 :                                 efree(bind->array.element_lengths);
    1810           1 :                                 efree(bind->array.elements);
    1811           1 :                                 efree(bind);
    1812           1 :                                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
    1813           1 :                                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1814           1 :                                 return NULL;
    1815             :                         }
    1816             :                         
    1817          14 :                         ((OCIDate *)bind->array.elements)[i] = oci_date;
    1818          14 :                         zend_hash_move_forward(hash);
    1819             :                 } else {
    1820          11 :                         PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)"01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date));
    1821             : 
    1822          11 :                         if (errstatus != OCI_SUCCESS) {
    1823             :                                 /* failed to convert string to date */
    1824           0 :                                 efree(bind->array.element_lengths);
    1825           0 :                                 efree(bind->array.elements);
    1826           0 :                                 efree(bind);
    1827           0 :                                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
    1828           0 :                                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
    1829           0 :                                 return NULL;
    1830             :                         }
    1831             :         
    1832          11 :                         ((OCIDate *)bind->array.elements)[i] = oci_date;
    1833             :                 }
    1834          25 :                 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
    1835             :         }
    1836           4 :         zend_hash_internal_pointer_reset(hash);
    1837             : 
    1838           4 :         return bind;
    1839             : }
    1840             : /* }}} */
    1841             : 
    1842             : #endif /* HAVE_OCI8 */
    1843             : 
    1844             : /*
    1845             :  * Local variables:
    1846             :  * tab-width: 4
    1847             :  * c-basic-offset: 4
    1848             :  * End:
    1849             :  * vim600: noet sw=4 ts=4 fdm=marker
    1850             :  * vim<600: noet sw=4 ts=4
    1851             :  */

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:08 +0000 (28 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.