1--TEST--
2mysqli_stmt_affected_rows()
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 (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
13        printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
14            $host, $user, $db, $port, $socket);
15    }
16    $stmt = mysqli_stmt_init($link);
17
18    if (!mysqli_stmt_prepare($stmt, 'DROP TABLE IF EXISTS test') ||
19        !mysqli_stmt_execute($stmt)) {
20        printf("[003] Failed to drop old test table: [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
21    }
22
23    if (!mysqli_stmt_prepare($stmt, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE = ' . $engine) ||
24        !mysqli_stmt_execute($stmt)) {
25        printf("[004] Failed to create test table: [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
26    }
27
28    if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
29        printf("[005] Expecting int/0, got %s/'%s'\n", gettype($tmp), $tmp);
30
31    mysqli_stmt_close($stmt);
32    $stmt = mysqli_stmt_init($link);
33
34    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1, 'a')") ||
35        !mysqli_stmt_execute($stmt))
36        printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
37
38    mysqli_stmt_close($stmt);
39    $stmt = mysqli_stmt_init($link);
40
41    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") ||
42        !mysqli_stmt_execute($stmt))
43        printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
44
45    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
46        printf("[008] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp);
47
48    mysqli_stmt_close($stmt);
49    $stmt = mysqli_stmt_init($link);
50
51    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") ||
52        !mysqli_stmt_execute($stmt))
53        // NOTE: the error message varies with the MySQL Server version, dump only the error code!
54        printf("[009] [%d] (error message varies with the MySQL Server version, check the error code)\n", mysqli_stmt_errno($stmt));
55
56    /* an error occurred: affected rows should return -1 */
57    if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
58        printf("[010] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
59
60    mysqli_stmt_close($stmt);
61    $stmt = mysqli_stmt_init($link);
62
63    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1, 'a') ON DUPLICATE KEY UPDATE id = 4") ||
64        !mysqli_stmt_execute($stmt))
65        printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
66
67    if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
68        printf("[012] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp);
69
70    mysqli_stmt_close($stmt);
71    $stmt = mysqli_stmt_init($link);
72
73    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (2, 'b'), (3, 'c')") ||
74        !mysqli_stmt_execute($stmt))
75        printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
76
77    if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
78        printf("[014] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp);
79
80    mysqli_stmt_close($stmt);
81    $stmt = mysqli_stmt_init($link);
82
83    if (!mysqli_stmt_prepare($stmt, "INSERT IGNORE INTO test(id, label) VALUES (1, 'a')") ||
84        !mysqli_stmt_execute($stmt))
85        printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
86
87    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
88        printf("[016] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp);
89
90    if (!($res = mysqli_query($link, "SELECT count(id) AS num FROM test")) ||
91        !($tmp = mysqli_fetch_assoc($res)))
92        printf("[017] [%d] %s\n", mysqli_error($link), mysqli_error($link));
93    $num = (int)$tmp['num'];
94    mysqli_free_result($res);
95
96    mysqli_stmt_close($stmt);
97    $stmt = mysqli_stmt_init($link);
98
99    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) SELECT id + 10, label FROM test") ||
100        !mysqli_stmt_execute($stmt))
101        printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
102
103    if ($num !== ($tmp = mysqli_stmt_affected_rows($stmt)))
104        printf("[019] Expecting int/%d, got %s/%s\n", $num, gettype($tmp), $tmp);
105
106    mysqli_stmt_close($stmt);
107    $stmt = mysqli_stmt_init($link);
108
109    if (!mysqli_stmt_prepare($stmt, "REPLACE INTO test(id, label) values (4, 'd')") ||
110        !mysqli_stmt_execute($stmt))
111        printf("[020] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
112
113    if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
114        printf("[021] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp);
115
116    mysqli_stmt_close($stmt);
117    $stmt = mysqli_stmt_init($link);
118
119    if (!mysqli_stmt_prepare($stmt, "REPLACE INTO test(id, label) values (5, 'e')") ||
120        !mysqli_stmt_execute($stmt))
121        printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
122
123    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
124        printf("[023] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp);
125
126    mysqli_stmt_close($stmt);
127    $stmt = mysqli_stmt_init($link);
128
129    if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 2") ||
130        !mysqli_stmt_execute($stmt))
131        printf("[024] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
132
133    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
134        printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp);
135
136    if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 2") ||
137        !mysqli_stmt_execute($stmt))
138        printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
139
140    if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
141        printf("[027] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
142
143    mysqli_stmt_close($stmt);
144    $stmt = mysqli_stmt_init($link);
145
146    if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 100") ||
147        !mysqli_stmt_execute($stmt))
148        printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
149
150    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
151        printf("[029] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp);
152
153    if (!mysqli_stmt_prepare($stmt, 'SELECT label FROM test WHERE id = 100') ||
154        !mysqli_stmt_execute($stmt))
155        printf("[030] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
156
157    /* use it like num_rows */
158    /* PS are unbuffered, num_rows cannot determine the row count before all rows have been fetched and/or buffered */
159    if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
160        printf("[031] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp);
161
162    if (0 !== ($tmp = mysqli_stmt_num_rows($stmt)))
163        printf("[032] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
164
165    if (!mysqli_stmt_store_result($stmt))
166        printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
167
168    if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
169        printf("[034] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
170
171    if (1 !== ($tmp = mysqli_stmt_num_rows($stmt)))
172        printf("[035] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
173
174    mysqli_stmt_free_result($stmt);
175    mysqli_stmt_close($stmt);
176    $stmt = mysqli_stmt_init($link);
177
178    if (!mysqli_stmt_prepare($stmt, 'SELECT label FROM test WHERE 1 = 2') ||
179        !mysqli_stmt_execute($stmt))
180        printf("[036] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
181
182    /* use it like num_rows */
183    if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
184        printf("[037] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp);
185
186    if (true !== ($tmp = mysqli_stmt_store_result($stmt)))
187        printf("[038] Expecting boolean/true, got %s\%s\n", gettype($tmp), $tmp);
188
189    if (0 !== ($tmp = mysqli_stmt_num_rows($stmt)))
190        printf("[039] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
191
192    if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
193        printf("[040] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
194
195    /* try to use stmt_affected_rows like stmt_num_rows */
196    /* stmt_affected_rows is not really meant for SELECT! */
197    if (mysqli_stmt_prepare($stmt, 'SELECT unknown_column FROM this_table_does_not_exist') ||
198        mysqli_stmt_execute($stmt))
199        printf("[041] Expecting SELECT statement to fail on purpose\n");
200
201    if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
202        printf("[042] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp);
203
204    if (true !== ($tmp = mysqli_stmt_store_result($stmt)))
205        printf("[043] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
206
207    if (0 !== ($tmp = mysqli_stmt_num_rows($stmt)))
208        printf("[044] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
209
210    if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt)))
211        printf("[045] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp);
212
213    mysqli_stmt_close($stmt);
214    $stmt = mysqli_stmt_init($link);
215
216    if (!mysqli_stmt_prepare($stmt, "DROP TABLE IF EXISTS test") ||
217        !mysqli_stmt_execute($stmt))
218        printf("[046] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
219
220    mysqli_stmt_close($stmt);
221
222    try {
223        mysqli_stmt_affected_rows($stmt);
224    } catch (Error $exception) {
225        echo $exception->getMessage() . "\n";
226    }
227
228    mysqli_close($link);
229
230    print "done!";
231?>
232--CLEAN--
233<?php
234    require_once("clean_table.inc");
235?>
236--EXPECTF--
237[009] [%d] (error message varies with the MySQL Server version, check the error code)
238mysqli_stmt object is already closed
239done!
240