From d7460b119db741c719f511fdb32b928718bbca51 Mon Sep 17 00:00:00 2001 From: Sharad Chandran R Date: Wed, 7 Jan 2026 09:42:49 +0530 Subject: [PATCH 1/2] Add the tests and required images for blob --- tests/pdo_oci_blob.phpt | 96 ++++++++++++++++++++++++++++++++++++++++ tests/test1.gif | Bin 0 -> 2523 bytes tests/test2.gif | Bin 0 -> 35 bytes 3 files changed, 96 insertions(+) create mode 100644 tests/pdo_oci_blob.phpt create mode 100644 tests/test1.gif create mode 100644 tests/test2.gif diff --git a/tests/pdo_oci_blob.phpt b/tests/pdo_oci_blob.phpt new file mode 100644 index 0000000..ca843c0 --- /dev/null +++ b/tests/pdo_oci_blob.phpt @@ -0,0 +1,96 @@ +--TEST-- +PDO_OCI: BLOB insert and fetch test +--EXTENSIONS-- +pdo +pdo_oci +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false); + +try { + $db->exec("DROP TABLE test_blob"); +} catch (PDOException $e) { + // Table may not exist, ignore +} +// Create table +$db->exec("CREATE TABLE test_blob (id NUMBER, picture BLOB)"); + +for ($id = 1; $id < 3; $id++) { + $db->beginTransaction(); + + // Sample image data (replace with actual paths or data) + // For testing, we'll use dummy data + $imageData = file_get_contents(dirname(__FILE__) .'/test' . $id . '.gif'); + + // Insert and bind output LOB + $lob = null; + $stmt = $db->prepare("INSERT INTO test_blob (id, picture) VALUES (:id, EMPTY_BLOB()) RETURNING picture INTO :picture"); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->bindParam(':picture', $lob, PDO::PARAM_LOB); + $stmt->execute(); + + if (is_resource($lob)) { + fwrite($lob, $imageData); + fclose($lob); + } + + $db->commit(); +} + +// Select and fetch BLOB using fetchAll +echo "Using fetchAll:\n"; +$stm = $db->query("SELECT picture FROM test_blob"); +foreach ($stm->fetchAll(PDO::FETCH_NUM) as $row) { + if (is_resource($row[0])) { + rewind($row[0]); + $blob = stream_get_contents($row[0]); + } else { + $blob = $row[0]; + } + echo "Blob length: " . strlen($blob) . "\n"; +} + +echo "-----------------------------------\n"; + +// Select and fetch BLOB using fetch in loop +echo "Using fetch in loop:\n"; +$stmt = $db->query("SELECT picture FROM test_blob"); +while ($row = $stmt->fetch(PDO::FETCH_NUM)) { + if (is_resource($row[0])) { + rewind($row[0]); + $blob = stream_get_contents($row[0]); + } else { + $blob = $row[0]; + } + echo "Blob length: " . strlen($blob) . "\n"; +} +?> +--CLEAN-- +exec("begin + execute immediate 'drop table test_blob'; + exception when others then + if sqlcode <> -942 then + raise; + end if; + end;"); +?> +--EXPECT-- +Using fetchAll: +Blob length: 2523 +Blob length: 35 +----------------------------------- +Using fetch in loop: +Blob length: 2523 +Blob length: 35 diff --git a/tests/test1.gif b/tests/test1.gif new file mode 100644 index 0000000000000000000000000000000000000000..f352c7308fee4c5cb1ab4f2e3dd73d6af6cfc6f6 GIT binary patch literal 2523 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 literal 0 HcmV?d00001 diff --git a/tests/test2.gif b/tests/test2.gif new file mode 100644 index 0000000000000000000000000000000000000000..c4d4483544f711904ad44ac9c281e159aae60cae GIT binary patch literal 35 mcmZ?wbhEHbWMW`sXkcLY&%n^az@Wnb1RxOxCMF&(25SIi-UKrM literal 0 HcmV?d00001 From 1f6a58d9c607eea36e2ad15b70132c7e875f6ec8 Mon Sep 17 00:00:00 2001 From: Sharad Chandran R Date: Wed, 7 Jan 2026 11:50:35 +0530 Subject: [PATCH 2/2] Do not create new lobs, when the lob is temporary + update bug57702.phpt test --- oci_statement.c | 13 +++++++++++++ tests/bug57702.phpt | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/oci_statement.c b/oci_statement.c index 5f8f062..0522b38 100644 --- a/oci_statement.c +++ b/oci_statement.c @@ -797,6 +797,19 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo_ if (C->dtype == SQLT_BLOB || C->dtype == SQLT_CLOB) { if (C->data) { + OCILobLocator *new_lob; + boolean isTempLOB; + OCILobIsTemporary(S->H->env, S->err, (OCILobLocator*)C->data, &isTempLOB); + if (!isTempLOB && + OCIDescriptorAlloc(S->H->env, (dvoid**)&new_lob, OCI_DTYPE_LOB, 0, NULL) == OCI_SUCCESS) { + if (OCILobLocatorAssign(S->H->svc, S->err, (OCILobLocator*)C->data, &new_lob) == OCI_SUCCESS) { + php_stream *stream = oci_create_lob_stream(stmt, new_lob); + OCILobOpen(S->H->svc, S->err, new_lob, OCI_LOB_READONLY); + php_stream_to_zval(stream, result); + return 1; + } + OCIDescriptorFree(new_lob, OCI_DTYPE_LOB); + } php_stream *stream = oci_create_lob_stream(stmt, (OCILobLocator*)C->data); OCILobOpen(S->H->svc, S->err, (OCILobLocator*)C->data, OCI_LOB_READONLY); php_stream_to_zval(stream, result); diff --git a/tests/bug57702.phpt b/tests/bug57702.phpt index f2d9c3c..89e07c1 100644 --- a/tests/bug57702.phpt +++ b/tests/bug57702.phpt @@ -184,8 +184,8 @@ string(11) "row 2 col 1" string(11) "row 2 col 2" Fifth Query -string(11) "row 2 col 1" -string(11) "row 2 col 2" +string(11) "row 1 col 1" +string(11) "row 1 col 2" string(11) "row 2 col 1" string(11) "row 2 col 2"