2
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
4
The MySQL Connector/C is licensed under the terms of the GPLv2
5
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
6
MySQL Connectors. There are special exceptions to the terms and
7
conditions of the GPLv2 as it is applied to this software, see the
8
FLOSS License Exception
9
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published
13
by the Free Software Foundation; version 2 of the License.
15
This program is distributed in the hope that it will be useful, but
16
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20
You should have received a copy of the GNU General Public License along
21
with this program; if not, write to the Free Software Foundation, Inc.,
22
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
Some basic tests of the client API.
32
static int basic_connect(MYSQL *mysql)
38
MYSQL *my= mysql_init(NULL);
39
FAIL_IF(!my, "mysql_init() failed");
41
FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
42
port, socketname, 0), mysql_error(my));
44
rc= mysql_query(my, "SELECT @@version");
45
check_mysql_rc(rc, my);
47
res= mysql_store_result(my);
48
FAIL_IF(!res, mysql_error(my));
50
while ((row= mysql_fetch_row(res)) != NULL)
52
FAIL_IF(mysql_num_fields(res) != 1, "Got the wrong number of fields");
54
FAIL_IF(mysql_errno(my), mysql_error(my));
56
mysql_free_result(res);
63
static int use_utf8(MYSQL *my)
69
/* Make sure that we actually ended up with utf8. */
70
rc= mysql_query(my, "SELECT @@character_set_connection");
71
check_mysql_rc(rc, my);
73
res= mysql_store_result(my);
74
FAIL_IF(!res, mysql_error(my));
76
while ((row= mysql_fetch_row(res)) != NULL)
78
FAIL_IF(strcmp(row[0], "utf8"), "wrong character set");
80
FAIL_IF(mysql_errno(my), mysql_error(my));
86
int client_query(MYSQL *mysql) {
89
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
90
check_mysql_rc(rc, mysql);
91
rc= mysql_query(mysql, "CREATE TABLE t1("
92
"id int primary key auto_increment, "
94
check_mysql_rc(rc, mysql);
95
rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
96
FAIL_IF(!rc, "Error expected");
97
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
98
check_mysql_rc(rc, mysql);
99
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
100
check_mysql_rc(rc, mysql);
101
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
102
check_mysql_rc(rc, mysql);
103
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
104
check_mysql_rc(rc, mysql);
105
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
106
check_mysql_rc(rc, mysql);
107
rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
108
"WHERE name= 'deleted'");
109
check_mysql_rc(rc, mysql);
110
rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
111
FAIL_IF(!rc, "Error expected");
112
rc= mysql_query(mysql, "drop table t1");
113
check_mysql_rc(rc, mysql);
118
static int test_bug12001(MYSQL *mysql)
121
const char *query= "DROP TABLE IF EXISTS test_table;"
122
"CREATE TABLE test_table(id INT);"
123
"INSERT INTO test_table VALUES(10);"
124
"UPDATE test_table SET id=20 WHERE id=10;"
125
"SELECT * FROM test_table;"
126
"INSERT INTO non_existent_table VALUES(11);";
130
rc= mysql_query(mysql, query);
131
check_mysql_rc(rc, mysql);
135
if (mysql_field_count(mysql) &&
136
(result= mysql_use_result(mysql)))
138
mysql_free_result(result);
141
while (!(res= mysql_next_result(mysql)));
143
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_table");
144
check_mysql_rc(rc, mysql);
146
FAIL_UNLESS(res==1, "res != 1");
152
/* connection options */
153
struct my_option_st opt_utf8[] = {
154
{MYSQL_SET_CHARSET_NAME, "utf8"},
158
static int test_bad_union(MYSQL *mysql)
162
const char *query= "SELECT 1, 2 union SELECT 1";
164
stmt= mysql_stmt_init(mysql);
165
FAIL_IF(!stmt, mysql_error(mysql));
166
rc= mysql_stmt_prepare(stmt, query, strlen(query));
167
FAIL_UNLESS(rc && mysql_errno(mysql) == 1222, "Error expected");
169
mysql_stmt_close(stmt);
174
Test that mysql_insert_id() behaves as documented in our manual
176
static int test_mysql_insert_id(MYSQL *mysql)
181
if (mysql_get_server_version(mysql) < 50100) {
182
diag("Test requires MySQL Server version 5.1 or above");
186
rc= mysql_query(mysql, "drop table if exists t1");
187
check_mysql_rc(rc, mysql);
188
rc= mysql_query(mysql, "drop table if exists t2");
189
check_mysql_rc(rc, mysql);
190
/* table without auto_increment column */
191
rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
192
check_mysql_rc(rc, mysql);
193
rc= mysql_query(mysql, "insert into t1 values (1,'a')");
194
check_mysql_rc(rc, mysql);
195
res= mysql_insert_id(mysql);
196
FAIL_UNLESS(res == 0, "");
197
rc= mysql_query(mysql, "insert into t1 values (null,'b')");
198
check_mysql_rc(rc, mysql);
199
res= mysql_insert_id(mysql);
200
FAIL_UNLESS(res == 0, "");
201
rc= mysql_query(mysql, "insert into t1 select 5,'c'");
202
check_mysql_rc(rc, mysql);
203
res= mysql_insert_id(mysql);
204
FAIL_UNLESS(res == 0, "");
207
Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
210
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
211
check_mysql_rc(rc, mysql);
212
rc= mysql_query(mysql, "insert into t2 values (null,'b')");
213
check_mysql_rc(rc, mysql);
214
rc= mysql_query(mysql, "insert into t1 select 5,'c'");
215
check_mysql_rc(rc, mysql);
216
res= mysql_insert_id(mysql);
217
FAIL_UNLESS(res == 0, "");
218
rc= mysql_query(mysql, "drop table t2");
219
check_mysql_rc(rc, mysql);
221
rc= mysql_query(mysql, "insert into t1 select null,'d'");
222
check_mysql_rc(rc, mysql);
223
res= mysql_insert_id(mysql);
224
FAIL_UNLESS(res == 0, "");
225
rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
226
check_mysql_rc(rc, mysql);
227
res= mysql_insert_id(mysql);
228
FAIL_UNLESS(res == 300, "");
229
rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
230
check_mysql_rc(rc, mysql);
231
res= mysql_insert_id(mysql);
233
Behaviour change: old code used to return 0; but 400 is consistent
234
with INSERT VALUES, and the manual's section of mysql_insert_id() does not
235
say INSERT SELECT should be different.
237
FAIL_UNLESS(res == 400, "");
239
/* table with auto_increment column */
240
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
241
check_mysql_rc(rc, mysql);
242
rc= mysql_query(mysql, "insert into t2 values (1,'a')");
243
check_mysql_rc(rc, mysql);
244
res= mysql_insert_id(mysql);
245
FAIL_UNLESS(res == 1, "");
246
/* this should not influence next INSERT if it doesn't have auto_inc */
247
rc= mysql_query(mysql, "insert into t1 values (10,'e')");
248
check_mysql_rc(rc, mysql);
249
res= mysql_insert_id(mysql);
250
FAIL_UNLESS(res == 0, "");
252
rc= mysql_query(mysql, "insert into t2 values (null,'b')");
253
check_mysql_rc(rc, mysql);
254
res= mysql_insert_id(mysql);
255
FAIL_UNLESS(res == 2, "");
256
rc= mysql_query(mysql, "insert into t2 select 5,'c'");
257
check_mysql_rc(rc, mysql);
258
res= mysql_insert_id(mysql);
260
Manual says that for multirow insert this should have been 5, but does not
261
say for INSERT SELECT. This is a behaviour change: old code used to return
262
0. We try to be consistent with INSERT VALUES.
264
FAIL_UNLESS(res == 5, "");
265
rc= mysql_query(mysql, "insert into t2 select null,'d'");
266
check_mysql_rc(rc, mysql);
267
res= mysql_insert_id(mysql);
268
FAIL_UNLESS(res == 6, "");
269
/* with more than one row */
270
rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
271
check_mysql_rc(rc, mysql);
272
res= mysql_insert_id(mysql);
273
FAIL_UNLESS(res == 11, "");
274
rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
275
check_mysql_rc(rc, mysql);
276
res= mysql_insert_id(mysql);
278
Manual says that for multirow insert this should have been 13, but does
279
not say for INSERT SELECT. This is a behaviour change: old code used to
280
return 0. We try to be consistent with INSERT VALUES.
282
FAIL_UNLESS(res == 13, "");
283
rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
284
check_mysql_rc(rc, mysql);
285
res= mysql_insert_id(mysql);
286
FAIL_UNLESS(res == 14, "");
287
rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
288
check_mysql_rc(rc, mysql);
289
res= mysql_insert_id(mysql);
290
FAIL_UNLESS(res == 16, "");
291
rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
292
FAIL_IF(!rc, "Error expected");
293
rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
294
check_mysql_rc(rc, mysql);
295
res= mysql_insert_id(mysql);
296
FAIL_UNLESS(res == 0, "");
297
rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
298
FAIL_IF(!rc, "Error expected");
299
res= mysql_insert_id(mysql);
300
FAIL_UNLESS(res == 0, "");
301
rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
302
check_mysql_rc(rc, mysql);
303
res= mysql_insert_id(mysql);
304
FAIL_UNLESS(res == 0, "");
305
/* mixing autogenerated and explicit values */
306
rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
307
FAIL_IF(!rc, "Error expected");
308
rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
309
FAIL_IF(!rc, "Error expected");
310
rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
311
check_mysql_rc(rc, mysql);
312
res= mysql_insert_id(mysql);
314
according to the manual, this might be 20 or 300, but it looks like
315
auto_increment column takes priority over last_insert_id().
317
FAIL_UNLESS(res == 20, "");
318
/* If first autogenerated number fails and 2nd works: */
319
rc= mysql_query(mysql, "drop table t2");
320
check_mysql_rc(rc, mysql);
321
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
322
"auto_increment, f2 varchar(255), unique (f2))");
323
check_mysql_rc(rc, mysql);
324
rc= mysql_query(mysql, "insert into t2 values (null,'e')");
325
res= mysql_insert_id(mysql);
326
FAIL_UNLESS(res == 1, "");
327
rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
328
check_mysql_rc(rc, mysql);
329
res= mysql_insert_id(mysql);
330
FAIL_UNLESS(res == 2, "");
331
/* If autogenerated fails and explicit works: */
332
rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
333
check_mysql_rc(rc, mysql);
334
res= mysql_insert_id(mysql);
336
Behaviour change: old code returned 3 (first autogenerated, even if it
337
fails); we now return first successful autogenerated.
339
FAIL_UNLESS(res == 13, "");
340
/* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
341
rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
342
check_mysql_rc(rc, mysql);
343
res= mysql_insert_id(mysql);
344
FAIL_UNLESS(res == 0, "");
345
rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
346
check_mysql_rc(rc, mysql);
347
res= mysql_insert_id(mysql);
348
FAIL_UNLESS(res == 0, "");
349
rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
350
check_mysql_rc(rc, mysql);
351
res= mysql_insert_id(mysql);
352
FAIL_UNLESS(res == 372, "");
353
/* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
354
rc= mysql_query(mysql, "insert into t2 values (null,'g')");
355
check_mysql_rc(rc, mysql);
356
res= mysql_insert_id(mysql);
357
FAIL_UNLESS(res == 15, "");
358
rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
359
check_mysql_rc(rc, mysql);
360
res= mysql_insert_id(mysql);
361
FAIL_UNLESS(res == 0, "");
363
Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
364
mysql_insert_id() returns the id of the row, instead of not being
367
rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
368
"update f2=concat('we updated ',f2)");
369
check_mysql_rc(rc, mysql);
370
res= mysql_insert_id(mysql);
371
FAIL_UNLESS(res == 15, "");
373
rc= mysql_query(mysql, "drop table t1,t2");
374
check_mysql_rc(rc, mysql);
378
/* Test simple select to debug */
380
static int test_select_direct(MYSQL *mysql)
386
rc= mysql_autocommit(mysql, TRUE);
387
check_mysql_rc(rc, mysql);
389
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
390
check_mysql_rc(rc, mysql);
392
rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
395
" name varchar(50))");
396
check_mysql_rc(rc, mysql);
398
/* insert a row and commit the transaction */
399
rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
400
check_mysql_rc(rc, mysql);
402
rc= mysql_commit(mysql);
403
check_mysql_rc(rc, mysql);
405
rc= mysql_query(mysql, "SELECT * FROM test_select");
406
check_mysql_rc(rc, mysql);
409
result= mysql_store_result(mysql);
410
FAIL_IF(!result, "Invalid result set");
412
mysql_free_result(result);
417
Ensure we execute the status code while testing
420
static int test_status(MYSQL *mysql)
423
check_mysql_rc(mysql_errno(mysql), mysql);
427
struct my_tests_st my_tests[] = {
428
{"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL},
429
{"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL},
430
{"client_query", client_query, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
431
{"test_bad_union", test_bad_union, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
432
{"test_select_direct", test_select_direct, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
433
{"test_mysql_insert_id", test_mysql_insert_id, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
434
{"test_bug12001", test_bug12001, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL, NULL},
435
{"test_status", test_status, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL, NULL},
436
{NULL, NULL, 0, 0, NULL, NULL}
440
int main(int argc, char **argv)
444
get_options(&argc, &argv);
450
return(exit_status());