Skip to content

Commit 481f895

Browse files
sim1984cmb69
authored andcommitted
Request #77863: PDO firebird support type Boolean in input parameters
1 parent bcf9d1e commit 481f895

File tree

3 files changed

+204
-11
lines changed

3 files changed

+204
-11
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ PHP NEWS
1313
- PCRE:
1414
. Fixed bug #78349 (Bundled pcre2 library missing LICENCE file). (Peter Kokot)
1515

16+
- PDO_Firebird:
17+
. Implemented FR #77863 (PDO firebird support type Boolean in input
18+
parameters). (Simonov Denis)
19+
1620
- PDO_MySQL:
1721
. Fixed bug #41997 (SP call yields additional empty result set). (cmb)
1822

ext/pdo_firebird/firebird_statement.c

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,60 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
611611
}
612612
}
613613

614+
#ifdef SQL_BOOLEAN
615+
/* keep native BOOLEAN type */
616+
if ((var->sqltype & ~1) == SQL_BOOLEAN) {
617+
switch (Z_TYPE_P(parameter)) {
618+
case IS_LONG:
619+
case IS_DOUBLE:
620+
case IS_TRUE:
621+
case IS_FALSE:
622+
*(FB_BOOLEAN*)var->sqldata = zend_is_true(parameter) ? FB_TRUE : FB_FALSE;
623+
break;
624+
case IS_STRING:
625+
{
626+
zend_long lval;
627+
double dval;
628+
629+
if ((Z_STRLEN_P(parameter) == 0)) {
630+
*(FB_BOOLEAN*)var->sqldata = FB_FALSE;
631+
break;
632+
}
633+
634+
switch (is_numeric_string(Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), &lval, &dval, 0)) {
635+
case IS_LONG:
636+
*(FB_BOOLEAN*)var->sqldata = (lval != 0) ? FB_TRUE : FB_FALSE;
637+
break;
638+
case IS_DOUBLE:
639+
*(FB_BOOLEAN*)var->sqldata = (dval != 0) ? FB_TRUE : FB_FALSE;
640+
break;
641+
default:
642+
if (!zend_binary_strncasecmp(Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), "true", 4, 4)) {
643+
*(FB_BOOLEAN*)var->sqldata = FB_TRUE;
644+
} else if (!zend_binary_strncasecmp(Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), "false", 5, 5)) {
645+
*(FB_BOOLEAN*)var->sqldata = FB_FALSE;
646+
} else {
647+
strcpy(stmt->error_code, "HY105");
648+
S->H->last_app_error = "Cannot convert string to boolean";
649+
return 0;
650+
}
651+
652+
}
653+
}
654+
break;
655+
case IS_NULL:
656+
*var->sqlind = -1;
657+
break;
658+
default:
659+
strcpy(stmt->error_code, "HY105");
660+
S->H->last_app_error = "Binding arrays/objects is not supported";
661+
return 0;
662+
}
663+
break;
664+
}
665+
#endif
666+
667+
614668
/* check if a NULL should be inserted */
615669
switch (Z_TYPE_P(parameter)) {
616670
int force_null;
@@ -646,7 +700,7 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
646700
/* keep the allow-NULL flag */
647701
var->sqltype = SQL_TEXT | (var->sqltype & 1);
648702
var->sqldata = Z_STRVAL_P(parameter);
649-
var->sqllen = Z_STRLEN_P(parameter);
703+
var->sqllen = Z_STRLEN_P(parameter);
650704
break;
651705
}
652706
case IS_NULL:
@@ -666,9 +720,9 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
666720
break;
667721

668722
case PDO_PARAM_EVT_FETCH_POST:
669-
if (param->paramno == -1) {
670-
return 0;
671-
}
723+
if (param->paramno == -1) {
724+
return 0;
725+
}
672726
if (param->is_param) {
673727
break;
674728
}
@@ -696,13 +750,13 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
696750
break;
697751
}
698752
case PDO_PARAM_EVT_NORMALIZE:
699-
if (!param->is_param) {
700-
char *s = ZSTR_VAL(param->name);
701-
while (*s != '\0') {
702-
*s = toupper(*s);
703-
s++;
704-
}
705-
}
753+
if (!param->is_param) {
754+
char *s = ZSTR_VAL(param->name);
755+
while (*s != '\0') {
756+
*s = toupper(*s);
757+
s++;
758+
}
759+
}
706760
break;
707761
default:
708762
ZVAL_NULL(parameter);

ext/pdo_firebird/tests/bug_77863.phpt

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
--TEST--
2+
PDO_Firebird: Bug #76488 PDO Firebird does not support boolean datatype in input parameters
3+
--SKIPIF--
4+
<?php require('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
require 'testdb.inc';
9+
10+
$sql = <<<SQL
11+
with t(b, s) as (
12+
select true, 'true' from rdb\$database
13+
union all
14+
select false, 'false' from rdb\$database
15+
union all
16+
select unknown, 'unknown' from rdb\$database
17+
)
18+
select trim(s) as s from t where b is not distinct from :p
19+
SQL;
20+
21+
try {
22+
$query = $dbh->prepare($sql);
23+
24+
// PDO::PARAM_BOOL
25+
$query->bindValue('p', 0, PDO::PARAM_BOOL);
26+
$query->execute();
27+
var_dump($query->fetchColumn(0));
28+
29+
$query->bindValue('p', 1, PDO::PARAM_BOOL);
30+
$query->execute();
31+
var_dump($query->fetchColumn(0));
32+
33+
$query->bindValue('p', false, PDO::PARAM_BOOL);
34+
$query->execute();
35+
var_dump($query->fetchColumn(0));
36+
37+
$query->bindValue('p', true, PDO::PARAM_BOOL);
38+
$query->execute();
39+
var_dump($query->fetchColumn(0));
40+
41+
$query->bindValue('p', 'false', PDO::PARAM_BOOL);
42+
$query->execute();
43+
var_dump($query->fetchColumn(0));
44+
45+
$query->bindValue('p', 'True', PDO::PARAM_BOOL);
46+
$query->execute();
47+
var_dump($query->fetchColumn(0));
48+
49+
$query->bindValue('p', null, PDO::PARAM_BOOL);
50+
$query->execute();
51+
var_dump($query->fetchColumn(0));
52+
53+
// PDO::PARAM_STR
54+
$query->bindValue('p', false, PDO::PARAM_STR);
55+
$query->execute();
56+
var_dump($query->fetchColumn(0));
57+
58+
$query->bindValue('p', true, PDO::PARAM_STR);
59+
$query->execute();
60+
var_dump($query->fetchColumn(0));
61+
62+
$query->bindValue('p', 0, PDO::PARAM_STR);
63+
$query->execute();
64+
var_dump($query->fetchColumn(0));
65+
66+
$query->bindValue('p', 1, PDO::PARAM_STR);
67+
$query->execute();
68+
var_dump($query->fetchColumn(0));
69+
70+
$query->bindValue('p', 'false', PDO::PARAM_STR);
71+
$query->execute();
72+
var_dump($query->fetchColumn(0));
73+
74+
$query->bindValue('p', 'true', PDO::PARAM_STR);
75+
$query->execute();
76+
var_dump($query->fetchColumn(0));
77+
78+
$query->bindValue('p', null, PDO::PARAM_STR);
79+
$query->execute();
80+
var_dump($query->fetchColumn(0));
81+
82+
// PDO::PARAM_INT
83+
$query->bindValue('p', false, PDO::PARAM_INT);
84+
$query->execute();
85+
var_dump($query->fetchColumn(0));
86+
87+
$query->bindValue('p', true, PDO::PARAM_INT);
88+
$query->execute();
89+
var_dump($query->fetchColumn(0));
90+
91+
$query->bindValue('p', 0, PDO::PARAM_INT);
92+
$query->execute();
93+
var_dump($query->fetchColumn(0));
94+
95+
$query->bindValue('p', 1, PDO::PARAM_INT);
96+
$query->execute();
97+
var_dump($query->fetchColumn(0));
98+
99+
$query->bindValue('p', 'false', PDO::PARAM_INT);
100+
$query->execute();
101+
var_dump($query->fetchColumn(0));
102+
103+
$query->bindValue('p', 'true', PDO::PARAM_INT);
104+
$query->execute();
105+
var_dump($query->fetchColumn(0));
106+
107+
echo "OK\n";
108+
}
109+
catch(Exception $e) {
110+
echo $e->getMessage() . '<br>';
111+
echo $e->getTraceAsString();
112+
}
113+
?>
114+
--EXPECT--
115+
string(5) "false"
116+
string(4) "true"
117+
string(5) "false"
118+
string(4) "true"
119+
string(5) "false"
120+
string(4) "true"
121+
string(7) "unknown"
122+
string(5) "false"
123+
string(4) "true"
124+
string(5) "false"
125+
string(4) "true"
126+
string(5) "false"
127+
string(4) "true"
128+
string(7) "unknown"
129+
string(5) "false"
130+
string(4) "true"
131+
string(5) "false"
132+
string(4) "true"
133+
string(5) "false"
134+
string(4) "true"
135+
OK

0 commit comments

Comments
 (0)