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