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