xref: /PHP-7.4/ext/mysqli/tests/bug79375.phpt (revision fcabe693)
1--TEST--
2Bug #79375: mysqli_store_result does not report error from lock wait timeout
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7if (!defined('MYSQLI_STORE_RESULT_COPY_DATA')) die('skip requires mysqlnd');
8?>
9--FILE--
10<?php
11
12require_once("connect.inc");
13mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
14$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
15$mysqli2 = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
16
17$mysqli->query('DROP TABLE IF EXISTS test');
18$mysqli->query('CREATE TABLE test (first int) ENGINE = InnoDB');
19$mysqli->query('INSERT INTO test VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)');
20
21function testStmtStoreResult(mysqli $mysqli, string $name) {
22    $mysqli->query("SET innodb_lock_wait_timeout = 1");
23    $mysqli->query("START TRANSACTION");
24    $query = "SELECT first FROM test WHERE first = 1 FOR UPDATE";
25    echo "Running query on $name\n";
26    $stmt = $mysqli->prepare($query);
27    $stmt->execute();
28    try {
29        $stmt->store_result();
30        echo "Got {$stmt->num_rows} for $name\n";
31    } catch(mysqli_sql_exception $e) {
32        echo $e->getMessage()."\n";
33    }
34}
35function testStmtGetResult(mysqli $mysqli, string $name) {
36    $mysqli->query("SET innodb_lock_wait_timeout = 1");
37    $mysqli->query("START TRANSACTION");
38    $query = "SELECT first FROM test WHERE first = 1 FOR UPDATE";
39    echo "Running query on $name\n";
40    $stmt = $mysqli->prepare($query);
41    $stmt->execute();
42    try {
43        $res = $stmt->get_result();
44        echo "Got {$res->num_rows} for $name\n";
45    } catch(mysqli_sql_exception $e) {
46        echo $e->getMessage()."\n";
47    }
48}
49function testNormalQuery(mysqli $mysqli, string $name) {
50    $mysqli->query("SET innodb_lock_wait_timeout = 1");
51    $mysqli->query("START TRANSACTION");
52    $query = "SELECT first FROM test WHERE first = 1 FOR UPDATE";
53    echo "Running query on $name\n";
54    try {
55        $res = $mysqli->query($query);
56        echo "Got {$res->num_rows} for $name\n";
57    } catch(mysqli_sql_exception $e) {
58        echo $e->getMessage()."\n";
59    }
60}
61function testStmtUseResult(mysqli $mysqli, string $name) {
62    $mysqli->query("SET innodb_lock_wait_timeout = 1");
63    $mysqli->query("START TRANSACTION");
64    $query = "SELECT first FROM test WHERE first = 1 FOR UPDATE";
65    echo "Running query on $name\n";
66    $stmt = $mysqli->prepare($query);
67    $stmt->execute();
68    try {
69        $stmt->fetch(); // should throw an error
70        $stmt->fetch();
71        echo "Got {$stmt->num_rows} for $name\n";
72    } catch (mysqli_sql_exception $e) {
73        echo $e->getMessage()."\n";
74    }
75}
76function testResultFetchRow(mysqli $mysqli, string $name) {
77    $mysqli->query("SET innodb_lock_wait_timeout = 1");
78    $mysqli->query("START TRANSACTION");
79    $query = "SELECT first FROM test WHERE first = 1 FOR UPDATE";
80    echo "Running query on $name\n";
81    $res = $mysqli->query($query, MYSQLI_USE_RESULT);
82    try {
83        $res->fetch_row();
84        $res->fetch_row();
85        echo "Got {$res->num_rows} for $name\n";
86    } catch(mysqli_sql_exception $e) {
87        echo $e->getMessage()."\n";
88    }
89}
90
91testStmtStoreResult($mysqli, 'first connection');
92testStmtStoreResult($mysqli2, 'second connection');
93
94$mysqli->close();
95$mysqli2->close();
96
97echo "\n";
98//  try it again for get_result
99$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
100$mysqli2 = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
101
102testStmtGetResult($mysqli, 'first connection');
103testStmtGetResult($mysqli2, 'second connection');
104
105$mysqli->close();
106$mysqli2->close();
107
108echo "\n";
109//  try it again with unprepared query
110$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
111$mysqli2 = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
112
113testNormalQuery($mysqli, 'first connection');
114testNormalQuery($mysqli2, 'second connection');
115
116$mysqli->close();
117$mysqli2->close();
118
119echo "\n";
120//  try it again with unprepared query
121$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
122$mysqli2 = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
123
124testStmtUseResult($mysqli, 'first connection');
125testStmtUseResult($mysqli2, 'second connection');
126
127$mysqli->close();
128$mysqli2->close();
129
130echo "\n";
131//  try it again using fetch_row on a result object
132$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
133$mysqli2 = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
134
135testResultFetchRow($mysqli, 'first connection');
136testResultFetchRow($mysqli2, 'second connection');
137
138$mysqli->close();
139$mysqli2->close();
140
141?>
142--CLEAN--
143<?php
144    require_once("clean_table.inc");
145?>
146--EXPECTF--
147Running query on first connection
148Got %d for first connection
149Running query on second connection
150Lock wait timeout exceeded; try restarting transaction
151
152Running query on first connection
153Got %d for first connection
154Running query on second connection
155Lock wait timeout exceeded; try restarting transaction
156
157Running query on first connection
158Got %d for first connection
159Running query on second connection
160Lock wait timeout exceeded; try restarting transaction
161
162Running query on first connection
163Got %d for first connection
164Running query on second connection
165Lock wait timeout exceeded; try restarting transaction
166
167Running query on first connection
168Got 1 for first connection
169Running query on second connection
170Lock wait timeout exceeded; try restarting transaction
171