diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 5db0c7f75aa1..2dc0755a6146 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -681,6 +681,14 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */ if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->in_sqlda)) { break; } + + /* make all parameters nullable */ + unsigned int i; + XSQLVAR* var; + for (i = 0, var = S->in_sqlda->sqlvar; i < S->in_sqlda->sqld; i++, var++) { + /* The low bit of sqltype indicates that the parameter can take a NULL value */ + var->sqltype |= 1; + } } stmt->driver_data = S; diff --git a/ext/pdo_firebird/tests/bug_15604.phpt b/ext/pdo_firebird/tests/bug_15604.phpt new file mode 100644 index 000000000000..52ab04d18af6 --- /dev/null +++ b/ext/pdo_firebird/tests/bug_15604.phpt @@ -0,0 +1,78 @@ +--TEST-- +Bug #15604 It is not possible to pass a NULL value as an input parameter if the field is marked as NOT NULL. +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +exec(' +recreate table t_bug_15604 ( + id bigint not null, + a int not null, + b int, + constraint pk_bug_15604 primary key(id) +) +'); + +$dbh->exec('recreate sequence g_bug_15604'); + +$dbh->exec(<<<'SQL' +create or alter trigger t_bug_15604_bi0 for t_bug_15604 +active before insert position 0 +as +begin + if (new.id is null) then + new.id = next value for g_bug_15604; +end +SQL +); + +$stmt = $dbh->prepare('insert into t_bug_15604(id, a, b) values(?, ?, ?)'); +$stmt->execute([null, 1, 2]); +$stmt->execute([2, 2, null]); +unset($stmt); + +$stmt2 = $dbh->prepare('SELECT id, a, b FROM t_bug_15604 WHERE id = ?'); + +$stmt2->execute([null]); +$data = $stmt2->fetch(\PDO::FETCH_ASSOC); +$stmt2->closeCursor(); +var_dump($data); + +$stmt2->execute([2]); +$data = $stmt2->fetch(\PDO::FETCH_ASSOC); +$stmt2->closeCursor(); +var_dump($data); + +unset($stmt2); + +echo "\nOK\n"; +?> +--CLEAN-- +exec('drop table t_bug_15604'); +@$dbh->exec('drop sequence g_bug_15604'); +unset($dbh); +?> +--EXPECT-- +bool(false) +array(3) { + ["ID"]=> + int(2) + ["A"]=> + int(2) + ["B"]=> + NULL +} + +OK