~maria-captains/mariadb-native-client/trunk

« back to all changes in this revision

Viewing changes to unittest/libmysql/basic-t.c

  • Committer: Georg Richter
  • Date: 2012-11-26 07:32:41 UTC
  • Revision ID: georg@linux-eozo-20121126073241-ues51lp2vo9td9vd
Added openssl layer support
Imported libmysql unittests
Added simple ssl tests
minor cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 
3
 
 
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>.
 
10
 
 
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.
 
14
 
 
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
 
18
for more details.
 
19
 
 
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
 
23
*/
 
24
 
 
25
 
 
26
/**
 
27
  Some basic tests of the client API.
 
28
*/
 
29
 
 
30
#include "my_test.h"
 
31
 
 
32
static int basic_connect(MYSQL *mysql)
 
33
{
 
34
  MYSQL_ROW row;
 
35
  MYSQL_RES *res;
 
36
  int rc;
 
37
 
 
38
  MYSQL *my= mysql_init(NULL);
 
39
  FAIL_IF(!my, "mysql_init() failed");
 
40
 
 
41
  FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema,
 
42
                         port, socketname, 0), mysql_error(my));
 
43
 
 
44
  rc= mysql_query(my, "SELECT @@version");
 
45
  check_mysql_rc(rc, my);
 
46
 
 
47
  res= mysql_store_result(my);
 
48
  FAIL_IF(!res, mysql_error(my));
 
49
 
 
50
  while ((row= mysql_fetch_row(res)) != NULL)
 
51
  {
 
52
    FAIL_IF(mysql_num_fields(res) != 1, "Got the wrong number of fields");
 
53
  }
 
54
  FAIL_IF(mysql_errno(my), mysql_error(my));
 
55
 
 
56
  mysql_free_result(res);
 
57
  mysql_close(my);
 
58
 
 
59
  return OK;
 
60
}
 
61
 
 
62
 
 
63
static int use_utf8(MYSQL *my)
 
64
{
 
65
  MYSQL_ROW row;
 
66
  MYSQL_RES *res;
 
67
  int rc;
 
68
 
 
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);
 
72
 
 
73
  res= mysql_store_result(my);
 
74
  FAIL_IF(!res, mysql_error(my));
 
75
 
 
76
  while ((row= mysql_fetch_row(res)) != NULL)
 
77
  {
 
78
    FAIL_IF(strcmp(row[0], "utf8"), "wrong character set");
 
79
  }
 
80
  FAIL_IF(mysql_errno(my), mysql_error(my));
 
81
 
 
82
 
 
83
  return OK;
 
84
}
 
85
 
 
86
int client_query(MYSQL *mysql) {
 
87
  int rc;
 
88
 
 
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, "
 
93
                         "name varchar(20))");
 
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);
 
114
 
 
115
  return OK;
 
116
}
 
117
 
 
118
static int test_bug12001(MYSQL *mysql)
 
119
{
 
120
  MYSQL_RES *result;
 
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);";
 
127
  int rc, res;
 
128
 
 
129
 
 
130
  rc= mysql_query(mysql, query);
 
131
  check_mysql_rc(rc, mysql);
 
132
 
 
133
  do
 
134
  {
 
135
    if (mysql_field_count(mysql) &&
 
136
        (result= mysql_use_result(mysql)))
 
137
    {
 
138
      mysql_free_result(result);
 
139
    }
 
140
  }
 
141
  while (!(res= mysql_next_result(mysql)));
 
142
 
 
143
  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_table");
 
144
  check_mysql_rc(rc, mysql);
 
145
 
 
146
  FAIL_UNLESS(res==1, "res != 1");
 
147
 
 
148
  return OK;
 
149
}
 
150
 
 
151
 
 
152
/* connection options */
 
153
struct my_option_st opt_utf8[] = {
 
154
  {MYSQL_SET_CHARSET_NAME, "utf8"},
 
155
  {0, NULL}
 
156
};
 
157
 
 
158
static int test_bad_union(MYSQL *mysql)
 
159
{
 
160
  MYSQL_STMT *stmt;
 
161
  int        rc;
 
162
  const char *query= "SELECT 1, 2 union SELECT 1";
 
163
 
 
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");
 
168
 
 
169
  mysql_stmt_close(stmt);
 
170
  return OK;
 
171
}
 
172
 
 
173
/*
 
174
   Test that mysql_insert_id() behaves as documented in our manual
 
175
*/
 
176
static int test_mysql_insert_id(MYSQL *mysql)
 
177
{
 
178
  my_ulonglong res;
 
179
  int rc;
 
180
 
 
181
  if (mysql_get_server_version(mysql) < 50100) {
 
182
    diag("Test requires MySQL Server version 5.1 or above");
 
183
    return SKIP;
 
184
  }
 
185
 
 
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, "");
 
205
 
 
206
  /*
 
207
    Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
 
208
    sporadically
 
209
  */
 
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);
 
220
  
 
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);
 
232
  /*
 
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.
 
236
  */
 
237
  FAIL_UNLESS(res == 400, "");
 
238
 
 
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, "");
 
251
 
 
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);
 
259
  /*
 
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.
 
263
  */
 
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);
 
277
  /*
 
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.
 
281
  */
 
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);
 
313
  /*
 
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().
 
316
  */
 
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);
 
335
  /*
 
336
    Behaviour change: old code returned 3 (first autogenerated, even if it
 
337
    fails); we now return first successful autogenerated.
 
338
  */
 
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, "");
 
362
  /*
 
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
 
365
    affected.
 
366
  */
 
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, "");
 
372
 
 
373
  rc= mysql_query(mysql, "drop table t1,t2");
 
374
  check_mysql_rc(rc, mysql);
 
375
  return OK;
 
376
}
 
377
 
 
378
/* Test simple select to debug */
 
379
 
 
380
static int test_select_direct(MYSQL *mysql)
 
381
{
 
382
  int        rc;
 
383
  MYSQL_RES  *result;
 
384
 
 
385
 
 
386
  rc= mysql_autocommit(mysql, TRUE);
 
387
  check_mysql_rc(rc, mysql);
 
388
 
 
389
  rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
 
390
  check_mysql_rc(rc, mysql);
 
391
 
 
392
  rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
 
393
                                                 " id2 float, "
 
394
                                                 " id3 double, "
 
395
                                                 " name varchar(50))");
 
396
  check_mysql_rc(rc, mysql);
 
397
 
 
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);
 
401
 
 
402
  rc= mysql_commit(mysql);
 
403
  check_mysql_rc(rc, mysql);
 
404
 
 
405
  rc= mysql_query(mysql, "SELECT * FROM test_select");
 
406
  check_mysql_rc(rc, mysql);
 
407
 
 
408
  /* get the result */
 
409
  result= mysql_store_result(mysql);
 
410
  FAIL_IF(!result, "Invalid result set");
 
411
 
 
412
  mysql_free_result(result);
 
413
  return OK;
 
414
}
 
415
 
 
416
/*
 
417
  Ensure we execute the status code while testing
 
418
*/
 
419
 
 
420
static int test_status(MYSQL *mysql)
 
421
{
 
422
  mysql_stat(mysql);
 
423
  check_mysql_rc(mysql_errno(mysql), mysql);
 
424
  return OK;
 
425
}
 
426
 
 
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}
 
437
};
 
438
 
 
439
 
 
440
int main(int argc, char **argv)
 
441
{
 
442
/*
 
443
  if (argc > 1)
 
444
    get_options(&argc, &argv);
 
445
*/
 
446
  get_envvars();
 
447
 
 
448
  run_tests(my_tests);
 
449
 
 
450
  return(exit_status());
 
451
}