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