xref: /PHP-8.1/ext/mysqli/tests/mysqli_report.phpt (revision b6b4a628)
1--TEST--
2mysqli_report()
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once('skipifconnectfailure.inc');
8?>
9--FILE--
10<?php
11    require_once("connect.inc");
12
13    if (true !== ($tmp = mysqli_report(-1)))
14        printf("[002] Expecting boolean/true even for invalid flags, got %s/%s\n", gettype($tmp), $tmp);
15
16    if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ERROR)))
17        printf("[003] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
18
19    if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_STRICT)))
20        printf("[004] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
21
22    if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_INDEX)))
23        printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
24
25    if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ALL)))
26        printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
27
28    if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_OFF)))
29        printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
30
31    require('table.inc');
32
33    /*
34    Internal macro MYSQL_REPORT_ERROR
35    */
36    mysqli_report(MYSQLI_REPORT_ERROR);
37
38    mysqli_multi_query($link, "BAR; FOO;");
39    mysqli_query($link, "FOO");
40    try {
41        mysqli_kill($link, -1);
42    } catch (\ValueError $e) {
43        echo $e->getMessage() . \PHP_EOL;
44    }
45
46    // mysqli_ping() cannot be tested, because one would need to cause an error inside the C function to test it
47    mysqli_prepare($link, "FOO");
48    mysqli_real_query($link, "FOO");
49    if (@mysqli_select_db($link, "Oh lord, let this be an unknown database name"))
50        printf("[009] select_db should have failed\n");
51    // mysqli_store_result() and mysqli_use_result() cannot be tested, because one would need to cause an error inside the C function to test it
52
53    mysqli_multi_query($link, "SELECT 1; FOO;");
54    mysqli_autocommit($link, true);
55    mysqli_commit($link);
56    mysqli_rollback($link);
57    $stmt = mysqli_stmt_init($link);
58    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
59    while(mysqli_more_results($link)) {
60        mysqli_next_result($link);
61        $res = mysqli_store_result($link);
62    }
63    mysqli_next_result($link);
64
65    $stmt = mysqli_prepare($link, "SELECT 1");
66    mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE);
67
68    // Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would
69    // not have been set. If that would be the case, the test would be broken.
70    mysqli_report(MYSQLI_REPORT_OFF);
71
72    mysqli_multi_query($link, "BAR; FOO;");
73    mysqli_query($link, "FOO");
74    try {
75        mysqli_kill($link, -1);
76    } catch (\ValueError $e) {
77        echo $e->getMessage() . \PHP_EOL;
78    }
79    mysqli_prepare($link, "FOO");
80    mysqli_real_query($link, "FOO");
81    mysqli_select_db($link, "Oh lord, let this be an unknown database name");
82
83    mysqli_multi_query($link, "SELECT 1; FOO;");
84    mysqli_autocommit($link, true);
85    mysqli_commit($link);
86    mysqli_rollback($link);
87    $stmt = mysqli_stmt_init($link);
88    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
89    while(mysqli_more_results($link)) {
90        mysqli_next_result($link);
91        $res = mysqli_store_result($link);
92    }
93    mysqli_next_result($link);
94
95    $stmt = mysqli_prepare($link, "SELECT 1");
96    mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE);
97
98    /*
99    Internal macro MYSQL_REPORT_STMT_ERROR
100    */
101
102    mysqli_report(MYSQLI_REPORT_ERROR);
103
104    $stmt = mysqli_stmt_init($link);
105    mysqli_stmt_prepare($stmt, "FOO");
106
107    $stmt = mysqli_stmt_init($link);
108    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
109    $id = 1;
110    mysqli_kill($link, mysqli_thread_id($link));
111    mysqli_stmt_bind_param($stmt, "i", $id);
112    mysqli_stmt_close($stmt);
113    mysqli_close($link);
114
115    /* mysqli_stmt_execute() = mysql_stmt_execute cannot be tested from PHP */
116    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
117            printf("[008] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
118    $stmt = mysqli_stmt_init($link);
119    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
120    $id = 1;
121    mysqli_stmt_bind_param($stmt, "i", $id);
122    // mysqli_kill($link, mysqli_thread_id($link));
123    mysqli_stmt_execute($stmt);
124    mysqli_stmt_close($stmt);
125    mysqli_close($link);
126
127    /* mysqli_kill() "trick" does not work for any of the following because of an E_COMMANDS_OUT_OF_SYNC */
128    /* mysqli_stmt_bind_result() = mysql_stmt_bind_result() cannot be tested from PHP */
129    /* mysqli_stmt_fetch() = mysql_stmt_fetch() cannot be tested from PHP */
130    /* mysqli_stmt_result_metadata() = mysql_stmt_result_metadata() cannot be tested from PHP */
131    /* mysqli_stmt_store_result() = mysql_stmt_store_result() cannot be tested from PHP */
132
133    // Check
134    mysqli_report(MYSQLI_REPORT_OFF);
135
136    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
137        printf("[010] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
138    $stmt = mysqli_stmt_init($link);
139    mysqli_stmt_prepare($stmt, "FOO");
140
141    $stmt = mysqli_stmt_init($link);
142    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
143    $id = 1;
144    mysqli_kill($link, mysqli_thread_id($link));
145    mysqli_stmt_bind_param($stmt, "i", $id);
146    mysqli_stmt_close($stmt);
147    mysqli_close($link);
148
149    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
150        printf("[011] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
151    $stmt = mysqli_stmt_init($link);
152    mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
153    $id = 1;
154    mysqli_stmt_bind_param($stmt, "i", $id);
155    mysqli_kill($link, mysqli_thread_id($link));
156    mysqli_stmt_execute($stmt);
157    mysqli_stmt_close($stmt);
158    mysqli_close($link);
159
160    /*
161    MYSQLI_REPORT_STRICT
162
163    MYSQLI_REPORT_STRICT --->
164    php_mysqli_report_error() ->
165        MYSQLI_REPORT_MYSQL_ERROR,
166        MYSQLI_REPORT_STMT_ERROR ->
167            already tested
168
169    php_mysqli_throw_sql_exception() ->
170        my_mysqli_real_connect()
171        my_mysqli_connect()
172
173    can't be tested: mysqli_query() via mysql_use_result()/mysql_store_result()
174    */
175    mysqli_report(MYSQLI_REPORT_OFF);
176    mysqli_report(MYSQLI_REPORT_STRICT);
177
178    try {
179
180        if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket))
181            printf("[012] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n",
182                $host, $user . 'unknown_really', $db, $port, $socket);
183        mysqli_close($link);
184
185    } catch (mysqli_sql_exception $e) {
186        printf("[013] %s\n", $e->getMessage());
187    }
188
189    try {
190        if (!$link = mysqli_init())
191            printf("[014] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
192
193        if ($link = my_mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket))
194            printf("[015] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n",
195                $host, $user . 'unknown_really', $db, $port, $socket);
196        mysqli_close($link);
197    } catch (mysqli_sql_exception $e) {
198        printf("[016] %s\n", $e->getMessage());
199    }
200
201    /*
202    MYSQLI_REPORT_INDEX --->
203    mysqli_query()
204    mysqli_stmt_execute()
205    mysqli_prepare()
206    mysqli_real_query()
207    mysqli_store_result()
208    mysqli_use_result()
209
210    No test, because of to many prerequisites:
211        - Server needs to be started with and
212            --log-slow-queries --log-queries-not-using-indexes
213        - query must cause the warning on all MySQL versions
214
215    TODO:
216    */
217    $log_slow_queries = false;
218    $log_queries_not_using_indexes = false;
219    mysqli_report(MYSQLI_REPORT_OFF);
220    mysqli_report(MYSQLI_REPORT_INDEX);
221
222    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
223        printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
224
225    if (mysqli_get_server_version($link) <= 50600) {
226        // this might cause a warning - no index used
227        if (!$res = @mysqli_query($link, "SHOW VARIABLES LIKE 'log_slow_queries'"))
228            printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
229
230        if (!$row = mysqli_fetch_assoc($res))
231            printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
232
233        $log_slow_query = ('ON' == $row['Value']);
234
235        if (mysqli_get_server_version($link) >= 50111) {
236            // this might cause a warning - no index used
237            if (!$res = @mysqli_query($link, "SHOW VARIABLES LIKE 'log_queries_not_using_indexes'"))
238                printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
239
240            if (!$row = mysqli_fetch_assoc($res))
241                printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
242
243            $log_queries_not_using_indexes = ('ON' == $row['Value']);
244
245            if ($log_slow_queries && $log_queries_not_using_indexes) {
246
247                for ($i = 100; $i < 20000; $i++) {
248                    if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES ($i, 'z')"))
249                        printf("[022 - %d] [%d] %s\n", $i - 99, mysqli_errno($link), mysqli_error($link));
250                }
251
252                // this might cause a warning - no index used
253                if (!$res = @mysqli_query($link, "SELECT id, label FROM test WHERE id = 1323"))
254                    printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
255
256                mysqli_free_result($res);
257            }
258        }
259    }
260
261    // Maybe we've provoked an index message, maybe not.
262    // All we can do is make a few dummy calls to ensure that all codes gets executed which
263    // checks the flag. Functions to check: mysqli_query() - done above,
264    // mysqli_stmt_execute(), mysqli_prepare(), mysqli_real_query(), mysqli_store_result()
265    // mysqli_use_result(), mysqli_thread_safe(), mysqli_thread_id()
266    mysqli_report(MYSQLI_REPORT_OFF);
267    mysqli_close($link);
268    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
269        printf("[024] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
270
271    if (!$stmt = mysqli_stmt_init($link))
272        printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
273
274    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test'))
275        printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
276
277    if (!mysqli_stmt_execute($stmt))
278        printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
279
280    mysqli_stmt_close($stmt);
281
282    if (!mysqli_real_query($link, 'SELECT label, id FROM test'))
283        printf("[028] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
284
285    if (!$res = mysqli_use_result($link))
286        printf("[029] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
287
288    mysqli_free_result($res);
289
290    if (!mysqli_real_query($link, 'SELECT label, id FROM test'))
291        printf("[030]  [%d] %s\n", mysqli_errno($link), mysqli_error($link));
292
293    if (!$res = mysqli_store_result($link))
294        printf("[031]  [%d] %s\n", mysqli_errno($link), mysqli_error($link));
295
296    mysqli_free_result($res);
297
298    if (!$stmt = mysqli_prepare($link, 'SELECT id * 3 FROM test'))
299        printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
300    else
301        mysqli_stmt_close($stmt);
302
303    if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')", MYSQLI_USE_RESULT) ||
304            !mysqli_query($link, 'DELETE FROM test WHERE id > 50', MYSQLI_USE_RESULT))
305        printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
306
307    $tmp = mysqli_thread_id($link);
308
309    mysqli_close($link);
310    print "done!";
311?>
312--CLEAN--
313<?php
314    require_once("clean_table.inc");
315?>
316--EXPECTF--
317Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d
318
319Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
320mysqli_kill(): Argument #2 ($process_id) must be greater than 0
321
322Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
323
324Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
325
326Warning: mysqli_autocommit(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
327
328Warning: mysqli_commit(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
329
330Warning: mysqli_rollback(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
331
332Warning: mysqli_stmt_prepare(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
333
334Warning: mysqli_next_result(): (%s/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
335
336Warning: mysqli_store_result(): (%s/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
337
338Warning: mysqli_stmt_attr_set(): (%s/%d): Not implemented in %s on line %d
339mysqli_kill(): Argument #2 ($process_id) must be greater than 0
340
341Warning: mysqli_stmt_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
342[013] Access denied for user '%s'@'%s'%r( \(using password: \w+\)){0,1}%r
343[016] Access denied for user '%s'@'%s'%r( \(using password: \w+\)){0,1}%r
344done!
345