diff options
| author | Antony Dovgal <tony2001@php.net> | 2007-01-11 11:27:52 +0000 |
|---|---|---|
| committer | Antony Dovgal <tony2001@php.net> | 2007-01-11 11:27:52 +0000 |
| commit | 12d54fa6832df1860970470ccd404141ca700997 (patch) | |
| tree | 077ad264623ad89c38819d7c430254b3ddb4ecd2 /ext | |
| parent | 5e74c607a2bf0d00a850a251cc935e3967ee50f0 (diff) | |
| download | php-git-12d54fa6832df1860970470ccd404141ca700997.tar.gz | |
MFH: fix #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name())
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/oci8/oci8.c | 7 | ||||
| -rw-r--r-- | ext/oci8/oci8_statement.c | 10 | ||||
| -rw-r--r-- | ext/oci8/php_oci8_int.h | 2 | ||||
| -rw-r--r-- | ext/oci8/tests/bug40078.phpt | 55 |
4 files changed, 70 insertions, 4 deletions
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 35f1a00d03..8be07b31cd 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -778,13 +778,16 @@ void php_oci_bind_hash_dtor(void *data) if (bind->array.elements) { efree(bind->array.elements); } + if (bind->array.element_lengths) { efree(bind->array.element_lengths); } -/* + if (bind->array.indicators) { efree(bind->array.indicators); - } + } + +/* if (bind->array.retcodes) { efree(bind->array.retcodes); } diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index e839950449..e043cc9717 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -1270,7 +1270,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam (dvoid *) bindp->array.elements, (sb4) bind->array.max_length, type, - (dvoid *)0, /* bindp->array.indicators, */ + (dvoid *)bindp->array.indicators, (ub2 *)bind->array.element_lengths, (ub2 *)0, /* bindp->array.retcodes, */ (ub4) max_table_length, @@ -1320,6 +1320,8 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, bind->array.max_length = maxlength; bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0); memset(bind->array.element_lengths, 0, max_table_length*sizeof(ub2)); + bind->array.indicators = safe_emalloc(max_table_length, sizeof(sb2), 0); + memset(bind->array.indicators, 0, max_table_length*sizeof(sb2)); zend_hash_internal_pointer_reset(hash); @@ -1327,6 +1329,9 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) { convert_to_string_ex(entry); bind->array.element_lengths[i] = Z_STRLEN_PP(entry); + if (Z_STRLEN_PP(entry) == 0) { + bind->array.indicators[i] = -1; + } zend_hash_move_forward(hash); } else { break; @@ -1372,6 +1377,7 @@ php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length bind->array.max_length = sizeof(ub4); bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0); memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2)); + bind->array.indicators = NULL; zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { @@ -1409,6 +1415,7 @@ php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length bind->array.max_length = sizeof(double); bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0); memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2)); + bind->array.indicators = NULL; zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { @@ -1446,6 +1453,7 @@ php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, p bind->array.max_length = sizeof(OCIDate); bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0); memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2)); + bind->array.indicators = NULL; zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 4ddefe2ae3..cee37dbc73 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -180,7 +180,7 @@ typedef struct { /* php_oci_bind {{{ */ php_oci_statement *parent_statement; /* pointer to the parent statement */ struct { void *elements; -/* ub2 *indicators; */ + sb2 *indicators; ub2 *element_lengths; /* ub2 *retcodes; */ ub4 current_length; diff --git a/ext/oci8/tests/bug40078.phpt b/ext/oci8/tests/bug40078.phpt new file mode 100644 index 0000000000..4a234e176d --- /dev/null +++ b/ext/oci8/tests/bug40078.phpt @@ -0,0 +1,55 @@ +--TEST-- +Bug #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name()) +--SKIPIF-- +<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?> +--FILE-- +<?php + +require dirname(__FILE__).'/connect.inc'; + +$create_pkg = " +CREATE OR REPLACE PACKAGE ARRAYBINDPKG1 AS + TYPE ARRTYPE IS TABLE OF VARCHAR(20) INDEX BY BINARY_INTEGER; + PROCEDURE nullbind(c1 OUT ARRTYPE); +END ARRAYBINDPKG1;"; +$statement = oci_parse($c, $create_pkg); +oci_execute($statement); + +$create_pkg_body = " +CREATE OR REPLACE PACKAGE BODY ARRAYBINDPKG1 AS + PROCEDURE nullbind(c1 OUT ARRTYPE) IS + BEGIN + c1(1) := 'one'; + c1(2) := 'two'; + c1(3) := ''; + c1(4) := 'four'; + c1(5) := 'five'; + END nullbind; +END ARRAYBINDPKG1;"; +$statement = oci_parse($c, $create_pkg_body); +oci_execute($statement); + +$statement = oci_parse($c, "BEGIN ARRAYBINDPKG1.nullbind(:c1); END;"); + +oci_bind_array_by_name($statement, ":c1", $array, 5, 20, SQLT_CHR); + +oci_execute($statement); + +var_dump($array); + +echo "Done\n"; +?> +--EXPECTF-- +array(5) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(0) "" + [3]=> + string(4) "four" + [4]=> + string(4) "five" +} +Done |
