xref: /PHP-8.1/ext/pdo_pgsql/tests/bug_33876.phpt (revision c0cbf3a6)
1--TEST--
2PDO PgSQL Bug #33876 (PDO misquotes/miscasts bool(false))
3--EXTENSIONS--
4pdo
5pdo_pgsql
6--SKIPIF--
7<?php
8require __DIR__ . '/config.inc';
9require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
10PDOTest::skip();
11?>
12--FILE--
13<?php
14require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
15$db = PDOTest::test_factory(__DIR__ . '/common.phpt');
16$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
17
18$db->exec("SET LC_MESSAGES='C'");
19$db->exec('CREATE TABLE test (foo varchar(5) NOT NULL, bar bool NOT NULL)');
20$db->exec("INSERT INTO test VALUES('false','f')");
21$db->exec("INSERT INTO test VALUES('true', 't')");
22
23$res = $db->prepare('SELECT foo from test where bar = ?');
24
25# this is the portable approach to binding a bool
26$res->bindValue(1, false, PDO::PARAM_BOOL);
27if (!$res->execute())
28    print_r($res->errorInfo());
29else
30    print_r($res->fetchAll(PDO::FETCH_ASSOC));
31
32# this is the portable approach to binding a bool
33$res->bindValue(1, true, PDO::PARAM_BOOL);
34if (!$res->execute())
35    print_r($res->errorInfo());
36else
37    print_r($res->fetchAll(PDO::FETCH_ASSOC));
38
39
40# true gets cast to string (because the implied default is string)
41# true-as-string is 1, so this "works"
42if (!$res->execute(array(true)))
43    print_r($res->errorInfo());
44else
45    print_r($res->fetchAll(PDO::FETCH_ASSOC));
46
47# Expected to fail; unless told otherwise, PDO assumes string inputs
48# false -> "" as string, which pgsql doesn't like
49if (!$res->execute(array(false)))
50    print_r(normalizeErrorInfo($res->errorInfo()));
51else
52    print_r($res->fetchAll(PDO::FETCH_ASSOC));
53
54# And now using emulator prepares
55echo "EMUL\n";
56
57
58$res = $db->prepare('SELECT foo from test where bar = ?', array(
59    PDO::ATTR_EMULATE_PREPARES => true));
60
61# this is the portable approach to binding a bool
62$res->bindValue(1, false, PDO::PARAM_BOOL);
63if (!$res->execute())
64    print_r($res->errorInfo());
65else
66    print_r($res->fetchAll(PDO::FETCH_ASSOC));
67
68# this is the portable approach to binding a bool
69$res->bindValue(1, true, PDO::PARAM_BOOL);
70if (!$res->execute())
71    print_r($res->errorInfo());
72else
73    print_r($res->fetchAll(PDO::FETCH_ASSOC));
74
75
76# true gets cast to string (because the implied default is string)
77# true-as-string is 1, so this "works"
78if (!$res->execute(array(true)))
79    print_r($res->errorInfo());
80else
81    print_r($res->fetchAll(PDO::FETCH_ASSOC));
82
83# Expected to fail; unless told otherwise, PDO assumes string inputs
84# false -> "" as string, which pgsql doesn't like
85if (!$res->execute(array(false))) {
86    print_r(normalizeErrorInfo($res->errorInfo()));
87} else {
88    print_r($res->fetchAll(PDO::FETCH_ASSOC));
89}
90
91function normalizeErrorInfo(array $err): array {
92    // Strip additional lines outputted by recent PgSQL versions
93    $err[2] = trim(current(explode("\n", $err[2])));
94    return $err;
95}
96
97?>
98--EXPECTF--
99Array
100(
101    [0] => Array
102        (
103            [foo] => false
104        )
105
106)
107Array
108(
109    [0] => Array
110        (
111            [foo] => true
112        )
113
114)
115Array
116(
117    [0] => Array
118        (
119            [foo] => true
120        )
121
122)
123Array
124(
125    [0] => 22P02
126    [1] => 7
127    [2] => %s:  %sboolean%s
128)
129EMUL
130Array
131(
132    [0] => Array
133        (
134            [foo] => false
135        )
136
137)
138Array
139(
140    [0] => Array
141        (
142            [foo] => true
143        )
144
145)
146Array
147(
148    [0] => Array
149        (
150            [foo] => true
151        )
152
153)
154Array
155(
156    [0] => 22P02
157    [1] => 7
158    [2] => %s:  %sboolean%s
159)
160