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

LTP GCOV extension - code coverage report
Current view: directory - oci8 - oci8_statement.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 765
Code covered: 84.7 % Executed lines: 648
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:33 +0000 (36 hours ago)

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