Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions oci_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,11 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
dyn = TRUE;
break;

case SQLT_BOL:
S->cols[colno].datalen = 1;
S->cols[colno].data = emalloc(S->cols[colno].datalen + 1);
break;

case SQLT_BIN:
default:
if (dtype == SQLT_DAT || dtype == SQLT_NUM || dtype == SQLT_RDD
Expand Down Expand Up @@ -795,6 +800,11 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo_
} else if (C->indicator == 0) {
/* it was stored perfectly */

if (C->dtype == SQLT_BOL) {
ZVAL_BOOL(result, strlen(C->data));
return 1;
}

if (C->dtype == SQLT_BLOB || C->dtype == SQLT_CLOB) {
if (C->data) {
php_stream *stream = oci_create_lob_stream(stmt, (OCILobLocator*)C->data);
Expand Down Expand Up @@ -970,6 +980,10 @@ static int oci_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_val
add_assoc_string(return_value, "oci:decl_type", "BINARY_DOUBLE");
add_assoc_string(return_value, "native_type", "BINARY_DOUBLE");
break;
case SQLT_BOL:
add_assoc_string(return_value, "oci:decl_type", "BOOLEAN");
add_assoc_string(return_value, "native_type", "BOOLEAN");
break;
default:
add_assoc_long(return_value, "oci:decl_type", dtype);
add_assoc_string(return_value, "native_type", "UNKNOWN");
Expand All @@ -981,6 +995,9 @@ static int oci_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_val
}

switch (dtype) {
case SQLT_BOL:
add_assoc_long(return_value, "pdo_type", PDO_PARAM_BOOL);
break;
case SQLT_BLOB:
case SQLT_CLOB:
add_assoc_long(return_value, "pdo_type", PDO_PARAM_LOB);
Expand All @@ -1002,6 +1019,9 @@ static int oci_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_val

/* PDO type */
switch (dtype) {
case SQLT_BOL:
add_assoc_long(return_value, "pdo_type", PDO_PARAM_BOOL);
break;
case SQLT_BFILE:
case SQLT_BLOB:
case SQLT_CLOB:
Expand Down
70 changes: 70 additions & 0 deletions tests/pdo_oci_insert_boolean.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
--TEST--
PDO_OCI: Insert BOOLEAN values into BOOLEAN column (Oracle 23ai+)
--EXTENSIONS--
pdo
pdo_oci
--SKIPIF--
<?php
require(getenv('PDO_TEST_DIR').'/pdo_test.inc');
$db = PDOTest::factory();

$version = $db->getAttribute(PDO::ATTR_SERVER_VERSION);
preg_match('/^(\d+)\./', $version, $matches);
$majorVersion = (int)$matches[1];
if ($majorVersion < 23) {
die('skip BOOLEAN type supported from Oracle Database 23ai');
}

PDOTest::skip();
?>
--FILE--
<?php

require_once(getenv('PDO_TEST_DIR').'/pdo_test.inc');
$db = PDOTest::factory();

// Create table
$db->exec("CREATE TABLE IF NOT EXISTS test_bool (id NUMBER, bool_val BOOLEAN)");

// Insert true
$stmt = $db->prepare("INSERT INTO test_bool (id, bool_val) VALUES (1, :val)");
$val = true;
$stmt->bindParam(':val', $val, PDO::PARAM_BOOL);
$stmt->execute();

// Insert false
$stmt = $db->prepare("INSERT INTO test_bool (id, bool_val) VALUES (2, :val)");
$val = false;
$stmt->bindParam(':val', $val, PDO::PARAM_BOOL);
$stmt->execute();

// Fetch and dump
$stmt = $db->query("SELECT id, bool_val FROM test_bool ORDER BY id");
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
?>
--CLEAN--
<?php

require_once(getenv('PDO_TEST_DIR').'/pdo_test.inc');
$db = PDOTest::factory();

$db->exec("DROP TABLE test_bool PURGE");

?>
--EXPECT--
array(2) {
[0]=>
array(2) {
["id"]=>
string(1) "1"
["bool_val"]=>
string(1) "1"
}
[1]=>
array(2) {
["id"]=>
string(1) "2"
["bool_val"]=>
string(1) "0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to not return false/true here directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mvorisek for reviewing.
I wanted to keep this similar to #29 and make it consistent.

Any suggestions in the code as to how I can get this to return true/false?
If so, should we make changes for the fix we did for #29 to return true/false as well?

}
}