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 #include "ma_common.h"
32 
test_conc75(MYSQL * my)33 static int test_conc75(MYSQL *my)
34 {
35   int rc;
36   MYSQL *mysql;
37   int i;
38   my_bool reconnect= 1;
39 
40   SKIP_SKYSQL;
41   SKIP_MAXSCALE;
42 
43   mysql= mysql_init(NULL);
44 
45   mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
46   my_test_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
47 
48   rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
49   check_mysql_rc(rc, mysql);
50 
51   rc= mysql_query(mysql, "CREATE TABLE a (a varchar(200))");
52   check_mysql_rc(rc, mysql);
53 
54   rc= mysql_set_character_set(mysql, "utf8");
55   check_mysql_rc(rc, mysql);
56 
57   for (i=0; i < 10; i++)
58   {
59     ulong thread_id= mysql_thread_id(mysql);
60     /* force reconnect */
61     mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
62     diag("killing connection");
63     mysql_kill(my, thread_id);
64     mysql_ping(mysql);
65     rc= mysql_query(mysql, "load data local infile './nonexistingfile.csv' into table a (`a`)");
66     FAIL_IF(!test(mysql->options.client_flag | CLIENT_LOCAL_FILES), "client_flags not correct");
67     diag("thread1: %ld %ld", thread_id, mysql_thread_id(mysql));
68     FAIL_IF(thread_id == mysql_thread_id(mysql), "new thread id expected");
69     //diag("cs: %s", mysql->charset->csname);
70     //FAIL_IF(strcmp(mysql->charset->csname, "utf8"), "wrong character set");
71   }
72   rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
73   check_mysql_rc(rc, mysql);
74   mysql_close(mysql);
75   return OK;
76 }
77 
78 
test_conc74(MYSQL * unused)79 static int test_conc74(MYSQL *unused __attribute__((unused)))
80 {
81   int rc;
82   MYSQL *mysql;
83 
84   mysql= mysql_init(NULL);
85 
86 
87   if (!my_test_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS))
88   {
89     diag("Error: %s", mysql_error(mysql));
90     mysql_close(mysql);
91     return FAIL;
92   }
93 
94   rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
95   check_mysql_rc(rc, mysql);
96 
97   rc= mysql_query(mysql, "CREATE TABLE a (a varchar(200))");
98   check_mysql_rc(rc, mysql);
99 
100   mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
101 
102   rc= mysql_query(mysql, "load data local infile './nonexistingfile.csv' into table a (`a`)");
103   FAIL_IF(!rc, "Error expected");
104 
105   rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
106   check_mysql_rc(rc, mysql);
107 
108   mysql_close(mysql);
109   return OK;
110 }
111 
112 
test_conc71(MYSQL * my)113 static int test_conc71(MYSQL *my)
114 {
115   int rc;
116   MYSQL *mysql;
117 
118   /* uncomment if you want to test manually */
119   return SKIP;
120 
121   mysql= mysql_init(NULL);
122 
123 
124   mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8");
125   mysql_options(mysql, MYSQL_OPT_COMPRESS, 0);
126   mysql_options(mysql, MYSQL_INIT_COMMAND, "/*!40101 SET SQL_MODE='' */");
127   mysql_options(mysql, MYSQL_INIT_COMMAND, "/*!40101 set @@session.wait_timeout=28800 */");
128 
129   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
130                          port, socketname, 0), mysql_error(my));
131 
132   diag("kill server");
133 
134   rc= mysql_query(mysql, "SELECT 'foo' FROM DUAL");
135   check_mysql_rc(rc, mysql);
136 
137   mysql_close(mysql);
138   return OK;
139 }
140 
test_conc70(MYSQL * my)141 static int test_conc70(MYSQL *my)
142 {
143   int rc;
144   MYSQL_RES *res;
145   MYSQL_ROW row;
146   MYSQL *mysql;
147 
148   SKIP_CONNECTION_HANDLER;
149 
150   SKIP_SKYSQL;
151   SKIP_MAXSCALE;
152 
153   mysql= mysql_init(NULL);
154 
155   rc= mysql_query(my, "SET @a:=@@max_allowed_packet");
156   check_mysql_rc(rc, my);
157 
158   mysql_query(my, "SET global max_allowed_packet=1024*1024*22");
159   check_mysql_rc(rc, my);
160 
161   mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
162   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
163                          port, socketname, 0), mysql_error(my));
164 
165   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
166   check_mysql_rc(rc, mysql);
167 
168   rc= mysql_query(mysql, "CREATE TABLE t1 (a LONGBLOB) engine=MyISAM");
169   check_mysql_rc(rc, mysql);
170 
171   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (REPEAT('A', 1024 * 1024 * 20))");
172   check_mysql_rc(rc, mysql);
173 
174   if (mysql_warning_count(mysql))
175   {
176     diag("server doesn't accept package size");
177     return SKIP;
178   }
179 
180 
181   rc= mysql_query(mysql, "SELECT a FROM t1");
182   check_mysql_rc(rc, mysql);
183 
184   if (!(res= mysql_store_result(mysql)))
185   {
186     diag("Error: %s", mysql_error(mysql));
187     return FAIL;
188   }
189 
190   row= mysql_fetch_row(res);
191   diag("Length: %ld", (long)strlen(row[0]));
192   FAIL_IF(strlen(row[0]) != 1024 * 1024 * 20, "Wrong length");
193 
194   mysql_free_result(res);
195   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
196   check_mysql_rc(rc, mysql);
197 
198   mysql_close(mysql);
199 
200   rc= mysql_query(my, "SET global max_allowed_packet=@a");
201   check_mysql_rc(rc, my);
202 
203   return OK;
204 }
205 
test_conc68(MYSQL * my)206 static int test_conc68(MYSQL *my)
207 {
208   int rc;
209   MYSQL_RES *res;
210   MYSQL_ROW row;
211   MYSQL *mysql;
212 
213   SKIP_CONNECTION_HANDLER;
214   SKIP_SKYSQL;
215   SKIP_MAXSCALE;
216 
217   mysql= mysql_init(NULL);
218 
219   rc= mysql_query(my, "SET @a:=@@max_allowed_packet");
220   check_mysql_rc(rc, my);
221 
222   mysql_query(my, "SET global max_allowed_packet=1024*1024*22");
223 
224   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
225                          port, socketname, 0), mysql_error(my));
226 
227   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
228   check_mysql_rc(rc, mysql);
229 
230   rc= mysql_query(mysql, "CREATE TABLE t1 (a LONGBLOB) ENGINE=MyISAM");
231   check_mysql_rc(rc, mysql);
232 
233   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (REPEAT('A', 1024 * 1024 * 20))");
234   check_mysql_rc(rc, mysql);
235   if (mysql_warning_count(mysql))
236   {
237     diag("server doesn't accept package size");
238     return SKIP;
239   }
240 
241   rc= mysql_query(mysql, "SELECT a FROM t1");
242   check_mysql_rc(rc, mysql);
243 
244   if (!(res= mysql_store_result(mysql)))
245   {
246     diag("Error: %s", mysql_error(mysql));
247     return FAIL;
248   }
249 
250   row= mysql_fetch_row(res);
251   diag("Length: %ld", (long)strlen(row[0]));
252   FAIL_IF(strlen(row[0]) != 1024 * 1024 * 20, "Wrong length");
253 
254   mysql_free_result(res);
255   mysql_close(mysql);
256 
257   rc= mysql_query(my, "SET global max_allowed_packet=@a");
258   check_mysql_rc(rc, my);
259 
260   return OK;
261 }
262 
263 
basic_connect(MYSQL * unused)264 static int basic_connect(MYSQL *unused __attribute__((unused)))
265 {
266   MYSQL_ROW row;
267   MYSQL_RES *res;
268   MYSQL_FIELD *field;
269   int rc;
270   MYSQL *my;
271 
272   my= mysql_init(NULL);
273   FAIL_IF(!my, "mysql_init() failed");
274 
275   FAIL_IF(!my_test_connect(my, hostname, username, password, schema,
276                          port, socketname, 0), mysql_error(my));
277 
278   rc= mysql_query(my, "SELECT @@version");
279   check_mysql_rc(rc, my);
280 
281   res= mysql_store_result(my);
282   FAIL_IF(!res, mysql_error(my));
283   field= mysql_fetch_fields(res);
284   FAIL_IF(!field, "couldn't fetch field");
285   while ((row= mysql_fetch_row(res)) != NULL)
286   {
287     FAIL_IF(mysql_num_fields(res) != 1, "Got the wrong number of fields");
288   }
289   FAIL_IF(mysql_errno(my), mysql_error(my));
290 
291   mysql_free_result(res);
292   mysql_close(my);
293 
294   return OK;
295 }
296 
297 
use_utf8(MYSQL * my)298 static int use_utf8(MYSQL *my)
299 {
300   MYSQL_ROW row;
301   MYSQL_RES *res;
302   int rc;
303 
304   /* Make sure that we actually ended up with utf8. */
305   rc= mysql_query(my, "SELECT @@character_set_connection");
306   check_mysql_rc(rc, my);
307 
308   res= mysql_store_result(my);
309   FAIL_IF(!res, mysql_error(my));
310 
311   while ((row= mysql_fetch_row(res)) != NULL)
312   {
313     FAIL_IF(strncmp(row[0], "utf8", 4), "wrong character set");
314   }
315   FAIL_IF(mysql_errno(my), mysql_error(my));
316   mysql_free_result(res);
317 
318   return OK;
319 }
320 
client_query(MYSQL * mysql)321 int client_query(MYSQL *mysql) {
322   int rc;
323 
324   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
325   check_mysql_rc(rc, mysql);
326   rc= mysql_query(mysql, "CREATE TABLE t1("
327                          "id int primary key auto_increment, "
328                          "name varchar(20))");
329   check_mysql_rc(rc, mysql);
330   rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
331   FAIL_IF(!rc, "Error expected");
332   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
333   check_mysql_rc(rc, mysql);
334   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
335   check_mysql_rc(rc, mysql);
336   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
337   check_mysql_rc(rc, mysql);
338   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
339   check_mysql_rc(rc, mysql);
340   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
341   check_mysql_rc(rc, mysql);
342   rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
343                           "WHERE name= 'deleted'");
344   check_mysql_rc(rc, mysql);
345   rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
346   FAIL_IF(!rc, "Error expected");
347   rc= mysql_query(mysql, "drop table t1");
348   check_mysql_rc(rc, mysql);
349 
350   return OK;
351 }
352 
test_bug12001(MYSQL * mysql)353 static int test_bug12001(MYSQL *mysql)
354 {
355   MYSQL_RES *result;
356   const char *query= "DROP TABLE IF EXISTS test_table;"
357                      "CREATE TABLE test_table(id INT);"
358                      "INSERT INTO test_table VALUES(10);"
359                      "UPDATE test_table SET id=20 WHERE id=10;"
360                      "SELECT * FROM test_table;"
361                      "INSERT INTO non_existent_table VALUES(11);";
362   int rc, res;
363 
364 
365   rc= mysql_query(mysql, query);
366   check_mysql_rc(rc, mysql);
367 
368   do
369   {
370     if (mysql_field_count(mysql) &&
371         (result= mysql_use_result(mysql)))
372     {
373       mysql_free_result(result);
374     }
375   }
376   while (!(res= mysql_next_result(mysql)));
377 
378   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_table");
379   check_mysql_rc(rc, mysql);
380 
381   FAIL_UNLESS(res==1, "res != 1");
382 
383   return OK;
384 }
385 
386 
387 /* connection options */
388 struct my_option_st opt_utf8[] = {
389   {MYSQL_SET_CHARSET_NAME, (char *)"utf8"},
390   {0, NULL}
391 };
392 
test_bad_union(MYSQL * mysql)393 static int test_bad_union(MYSQL *mysql)
394 {
395   MYSQL_STMT *stmt;
396   int        rc;
397   const char *query= "SELECT 1, 2 union SELECT 1";
398 
399   stmt= mysql_stmt_init(mysql);
400   FAIL_IF(!stmt, mysql_error(mysql));
401   rc= mysql_stmt_prepare(stmt, SL(query));
402   FAIL_UNLESS(rc && mysql_errno(mysql) == 1222, "Error expected");
403 
404   mysql_stmt_close(stmt);
405   return OK;
406 }
407 
408 /*
409    Test that mysql_insert_id() behaves as documented in our manual
410 */
test_mysql_insert_id(MYSQL * mysql)411 static int test_mysql_insert_id(MYSQL *mysql)
412 {
413   unsigned long long res;
414   int rc;
415 
416   if (mysql_get_server_version(mysql) < 50100) {
417     diag("Test requires MySQL Server version 5.1 or above");
418     return SKIP;
419   }
420 
421   rc= mysql_query(mysql, "drop table if exists t1");
422   check_mysql_rc(rc, mysql);
423   rc= mysql_query(mysql, "drop table if exists t2");
424   check_mysql_rc(rc, mysql);
425   rc= mysql_query(mysql, "drop table if exists t3");
426   check_mysql_rc(rc, mysql);
427   rc= mysql_query(mysql, "drop table if exists t4");
428   check_mysql_rc(rc, mysql);
429   /* table without auto_increment column */
430   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
431   check_mysql_rc(rc, mysql);
432   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
433   check_mysql_rc(rc, mysql);
434   rc= mysql_query(mysql, "create table t3 (f1 int not null primary key auto_increment, f2 varchar(255)) engine=MyISAM");
435   check_mysql_rc(rc, mysql);
436   rc= mysql_query(mysql, "create table t4 (f1 int not null primary key "
437                   "auto_increment, f2 varchar(200), unique (f2)) engine=MyISAM");
438   check_mysql_rc(rc, mysql);
439 
440   rc= mysql_query(mysql, "FLUSH TABLES");
441   check_mysql_rc(rc, mysql);
442   rc= mysql_query(mysql, "START TRANSACTION");
443   check_mysql_rc(rc, mysql);
444 
445   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
446   check_mysql_rc(rc, mysql);
447   res= mysql_insert_id(mysql);
448   FAIL_UNLESS(res == 0, "");
449   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
450   check_mysql_rc(rc, mysql);
451   res= mysql_insert_id(mysql);
452   FAIL_UNLESS(res == 0, "");
453   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
454   check_mysql_rc(rc, mysql);
455   res= mysql_insert_id(mysql);
456   FAIL_UNLESS(res == 0, "");
457 
458   /*
459     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
460     sporadically
461   */
462   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
463   check_mysql_rc(rc, mysql);
464   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
465   check_mysql_rc(rc, mysql);
466   res= mysql_insert_id(mysql);
467   FAIL_UNLESS(res == 0, "");
468   rc= mysql_query(mysql, "insert into t1 select null,'d'");
469   check_mysql_rc(rc, mysql);
470   res= mysql_insert_id(mysql);
471   FAIL_UNLESS(res == 0, "");
472   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
473   check_mysql_rc(rc, mysql);
474   res= mysql_insert_id(mysql);
475   FAIL_UNLESS(res == 300, "");
476   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
477   check_mysql_rc(rc, mysql);
478   res= mysql_insert_id(mysql);
479   /*
480     Behaviour change: old code used to return 0; but 400 is consistent
481     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
482     say INSERT SELECT should be different.
483   */
484   FAIL_UNLESS(res == 400, "");
485 
486   /* table with auto_increment column */
487   rc= mysql_query(mysql, "insert into t3 values (1,'a')");
488   check_mysql_rc(rc, mysql);
489   res= mysql_insert_id(mysql);
490   FAIL_UNLESS(res == 1, "");
491   /* this should not influence next INSERT if it doesn't have auto_inc */
492   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
493   check_mysql_rc(rc, mysql);
494   res= mysql_insert_id(mysql);
495   FAIL_UNLESS(res == 0, "");
496 
497   rc= mysql_query(mysql, "insert into t3 values (null,'b')");
498   check_mysql_rc(rc, mysql);
499   res= mysql_insert_id(mysql);
500   FAIL_UNLESS(res == 2, "");
501   rc= mysql_query(mysql, "insert into t3 select 5,'c'");
502   check_mysql_rc(rc, mysql);
503   res= mysql_insert_id(mysql);
504   /*
505     Manual says that for multirow insert this should have been 5, but does not
506     say for INSERT SELECT. This is a behaviour change: old code used to return
507     0. We try to be consistent with INSERT VALUES.
508   */
509   FAIL_UNLESS(res == 5, "");
510   rc= mysql_query(mysql, "insert into t3 select null,'d'");
511   check_mysql_rc(rc, mysql);
512   res= mysql_insert_id(mysql);
513   FAIL_UNLESS(res == 6, "");
514   /* with more than one row */
515   rc= mysql_query(mysql, "insert into t3 values (10,'a'),(11,'b')");
516   check_mysql_rc(rc, mysql);
517   res= mysql_insert_id(mysql);
518   FAIL_UNLESS(res == 11, "");
519   rc= mysql_query(mysql, "insert into t3 select 12,'a' union select 13,'b'");
520   check_mysql_rc(rc, mysql);
521   res= mysql_insert_id(mysql);
522   /*
523     Manual says that for multirow insert this should have been 13, but does
524     not say for INSERT SELECT. This is a behaviour change: old code used to
525     return 0. We try to be consistent with INSERT VALUES.
526   */
527   FAIL_UNLESS(res == 13, "");
528   rc= mysql_query(mysql, "insert into t3 values (null,'a'),(null,'b')");
529   check_mysql_rc(rc, mysql);
530   res= mysql_insert_id(mysql);
531   FAIL_UNLESS(res == 14, "");
532   rc= mysql_query(mysql, "insert into t3 select null,'a' union select null,'b'");
533   check_mysql_rc(rc, mysql);
534   res= mysql_insert_id(mysql);
535   FAIL_UNLESS(res == 16, "");
536   rc= mysql_query(mysql, "insert into t3 select 12,'a' union select 13,'b'");
537   FAIL_IF(!rc, "Error expected");
538   rc= mysql_query(mysql, "insert ignore into t3 select 12,'a' union select 13,'b'");
539   check_mysql_rc(rc, mysql);
540   res= mysql_insert_id(mysql);
541   FAIL_UNLESS(res == 0, "");
542   rc= mysql_query(mysql, "insert into t3 values (12,'a'),(13,'b')");
543   FAIL_IF(!rc, "Error expected");
544   res= mysql_insert_id(mysql);
545   FAIL_UNLESS(res == 0, "");
546   rc= mysql_query(mysql, "insert ignore into t3 values (12,'a'),(13,'b')");
547   check_mysql_rc(rc, mysql);
548   res= mysql_insert_id(mysql);
549   FAIL_UNLESS(res == 0, "");
550   /* mixing autogenerated and explicit values */
551   rc= mysql_query(mysql, "insert into t3 values (null,'e'),(12,'a'),(13,'b')");
552   FAIL_IF(!rc, "Error expected");
553   rc= mysql_query(mysql, "insert into t3 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
554   FAIL_IF(!rc, "Error expected");
555   rc= mysql_query(mysql, "insert into t3 values (null,last_insert_id(300))");
556   check_mysql_rc(rc, mysql);
557   res= mysql_insert_id(mysql);
558   /*
559     according to the manual, this might be 20 or 300, but it looks like
560     auto_increment column takes priority over last_insert_id().
561   */
562   diag("res: %lld", res);
563   FAIL_UNLESS(res == 20, "");
564   /* If first autogenerated number fails and 2nd works: */
565   rc= mysql_query(mysql, "insert into t4 values (null,'e')");
566   res= mysql_insert_id(mysql);
567   FAIL_UNLESS(res == 1, "");
568   rc= mysql_query(mysql, "insert ignore into t4 values (null,'e'),(null,'a'),(null,'e')");
569   check_mysql_rc(rc, mysql);
570   res= mysql_insert_id(mysql);
571   FAIL_UNLESS(res == 2, "");
572   /* If autogenerated fails and explicit works: */
573   rc= mysql_query(mysql, "insert ignore into t4 values (null,'e'),(12,'c'),(null,'d')");
574   check_mysql_rc(rc, mysql);
575   res= mysql_insert_id(mysql);
576   /*
577     Behaviour change: old code returned 3 (first autogenerated, even if it
578     fails); we now return first successful autogenerated.
579   */
580   FAIL_UNLESS(res == 13, "");
581   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
582   rc= mysql_query(mysql, "update t4 set f1=14 where f1=12");
583   check_mysql_rc(rc, mysql);
584   res= mysql_insert_id(mysql);
585   FAIL_UNLESS(res == 0, "");
586   rc= mysql_query(mysql, "update t4 set f1=0 where f1=14");
587   check_mysql_rc(rc, mysql);
588   res= mysql_insert_id(mysql);
589   FAIL_UNLESS(res == 0, "");
590   rc= mysql_query(mysql, "update t4 set f2=last_insert_id(372) where f1=0");
591   check_mysql_rc(rc, mysql);
592   res= mysql_insert_id(mysql);
593   FAIL_UNLESS(res == 372, "");
594   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
595   rc= mysql_query(mysql, "insert into t4 values (null,'g')");
596   check_mysql_rc(rc, mysql);
597   res= mysql_insert_id(mysql);
598   FAIL_UNLESS(res == 15, "");
599   rc= mysql_query(mysql, "update t4 set f2=(@li:=last_insert_id()) where f1=15");
600   check_mysql_rc(rc, mysql);
601   res= mysql_insert_id(mysql);
602   FAIL_UNLESS(res == 0, "");
603   /*
604     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
605     mysql_insert_id() returns the id of the row, instead of not being
606     affected.
607   */
608   rc= mysql_query(mysql, "insert into t4 values (null,@li) on duplicate key "
609                   "update f2=concat('we updated ',f2)");
610   check_mysql_rc(rc, mysql);
611   res= mysql_insert_id(mysql);
612   FAIL_UNLESS(res == 15, "");
613 
614   rc= mysql_query(mysql, "drop table t1,t2,t3,t4");
615   check_mysql_rc(rc, mysql);
616   return OK;
617 }
618 
619 /* Test simple select to debug */
620 
test_select_direct(MYSQL * mysql)621 static int test_select_direct(MYSQL *mysql)
622 {
623   int        rc;
624   MYSQL_RES  *result;
625 
626 
627   rc= mysql_autocommit(mysql, TRUE);
628   check_mysql_rc(rc, mysql);
629 
630   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
631   check_mysql_rc(rc, mysql);
632 
633   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
634                                                  " id2 float, "
635                                                  " id3 double, "
636                                                  " name varchar(50))");
637   check_mysql_rc(rc, mysql);
638 
639   /* insert a row and commit the transaction */
640   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
641   check_mysql_rc(rc, mysql);
642 
643   rc= mysql_commit(mysql);
644   check_mysql_rc(rc, mysql);
645 
646   rc= mysql_query(mysql, "SELECT * FROM test_select");
647   check_mysql_rc(rc, mysql);
648 
649   /* get the result */
650   result= mysql_store_result(mysql);
651   FAIL_IF(!result, "Invalid result set");
652 
653   mysql_free_result(result);
654   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
655   check_mysql_rc(rc, mysql);
656   return OK;
657 }
658 
659 /*
660   Ensure we execute the status code while testing
661 */
662 
test_status(MYSQL * mysql)663 static int test_status(MYSQL *mysql)
664 {
665   mysql_stat(mysql);
666   check_mysql_rc(mysql_errno(mysql), mysql);
667   return OK;
668 }
669 
bug_conc1(MYSQL * mysql)670 static int bug_conc1(MYSQL *mysql)
671 {
672   my_test_connect(mysql, hostname, username, password, schema,
673                      port, socketname, 0);
674   diag("errno: %d", mysql_errno(mysql));
675   FAIL_IF(mysql_errno(mysql) != CR_ALREADY_CONNECTED,
676           "Expected errno=CR_ALREADY_CONNECTED");
677   return OK;
678 }
679 
test_options_initcmd(MYSQL * unused)680 static int test_options_initcmd(MYSQL *unused __attribute__((unused)))
681 {
682   MYSQL *mysql= mysql_init(NULL);
683   MYSQL_RES *res;
684   int rc;
685 
686   mysql_options(mysql, MYSQL_INIT_COMMAND, "DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a int)");
687   mysql_options(mysql, MYSQL_INIT_COMMAND, "INSERT INTO t1 VALUES (1),(2),(3)");
688   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
689                               port, socketname,
690                               CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
691 
692   rc= mysql_query(mysql, "SELECT a FROM t1");
693   check_mysql_rc(rc, mysql);
694 
695   res= mysql_store_result(mysql);
696   FAIL_IF(mysql_num_rows(res) != 3, "Expected 3 rows");
697 
698   mysql_free_result(res);
699 
700   rc= mysql_query(mysql, "DROP TABLE t1");
701   check_mysql_rc(rc, mysql);
702   mysql_close(mysql);
703   return OK;
704 }
705 
test_extended_init_values(MYSQL * unused)706 static int test_extended_init_values(MYSQL *unused __attribute__((unused)))
707 {
708   MYSQL *mysql= mysql_init(NULL);
709 
710   mysql_options(mysql, MYSQL_DEFAULT_AUTH, "unknown");
711   FAIL_IF(strcmp(mysql->options.extension->default_auth, "unknown"), "option not set");
712 
713   mysql_options(mysql, MYSQL_PLUGIN_DIR, "/tmp/foo");
714   FAIL_IF(strcmp(mysql->options.extension->plugin_dir, "/tmp/foo"), "option not set");
715 
716   mysql_close(mysql);
717   return OK;
718 }
719 
test_reconnect_maxpackage(MYSQL * unused)720 static int test_reconnect_maxpackage(MYSQL *unused __attribute__((unused)))
721 {
722   int rc;
723   ulong max_packet= 0;
724   MYSQL *mysql;
725   MYSQL_RES *res;
726   MYSQL_ROW row;
727   char *query;
728   my_bool reconnect= 1;
729 
730   SKIP_CONNECTION_HANDLER;
731 
732   mysql= mysql_init(NULL);
733 
734   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
735                               port, socketname,
736                               CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
737   mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
738 
739   rc= mysql_query(mysql, "SELECT @@max_allowed_packet");
740   check_mysql_rc(rc, mysql);
741   res= mysql_store_result(mysql);
742   row= mysql_fetch_row(res);
743   max_packet= atol(row[0]);
744   diag("max_allowed_packet=%lu", max_packet);
745   mysql_free_result(res);
746 
747   query= (char *)malloc(max_packet + 30);
748   memset(query, 0, max_packet + 30);
749 
750   strcpy(query, "SELECT '");
751   memset(query + 8, 'A', max_packet);
752   strcat(query, "' FROM DUAL");
753 
754   rc= mysql_query(mysql, query);
755   free(query);
756   if (!rc)
757   {
758     diag("expected error");
759     mysql_close(mysql);
760     return FAIL;
761   }
762   else
763     diag("Error (expected): %s", mysql_error(mysql));
764 
765   rc= mysql_ping(mysql);
766   /* if the server is under load, poll might not report closed
767      socket since FIN packet came too late */
768   if (rc)
769     rc= mysql_ping(mysql);
770   check_mysql_rc(rc, mysql);
771   rc= mysql_query(mysql, "SELECT @@max_allowed_packet");
772   check_mysql_rc(rc, mysql);
773    res= mysql_store_result(mysql);
774   row= mysql_fetch_row(res);
775   max_packet= atol(row[0]);
776   diag("max_allowed_packet=%lu", max_packet);
777   mysql_free_result(res);
778 
779 
780   mysql_close(mysql);
781   return OK;
782 }
783 
test_compressed(MYSQL * unused)784 static int test_compressed(MYSQL *unused __attribute__((unused)))
785 {
786   int rc;
787   MYSQL *mysql= mysql_init(NULL);
788   MYSQL_RES *res;
789   my_bool reconnect= 1;
790 
791   mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
792   FAIL_IF(!my_test_connect(mysql, hostname, username, password, schema,
793                               port, socketname,
794                               CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
795   mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
796 
797   rc= mysql_query(mysql, "SHOW VARIABLES");
798   check_mysql_rc(rc, mysql);
799 
800   if ((res= mysql_store_result(mysql)))
801     mysql_free_result(res);
802 
803   mysql_close(mysql);
804 
805   return OK;
806 }
807 
808 struct my_tests_st my_tests[] = {
809   {"test_conc75", test_conc75, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
810   {"test_conc74", test_conc74, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
811   {"test_conc71", test_conc71, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
812   {"test_conc70", test_conc70, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
813   {"test_conc68", test_conc68, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
814   {"test_compressed", test_compressed, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
815   {"test_reconnect_maxpackage", test_reconnect_maxpackage, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
816   {"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
817   {"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0,  opt_utf8,  NULL},
818   {"client_query", client_query, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
819   {"test_bad_union", test_bad_union, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
820   {"test_select_direct", test_select_direct, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
821   {"test_mysql_insert_id", test_mysql_insert_id, TEST_CONNECTION_DEFAULT, 0,  NULL,  NULL},
822   {"test_bug12001", test_bug12001, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS,  NULL,  NULL},
823   {"test_status", test_status, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS,  NULL,  NULL},
824   {"bug_conc1", bug_conc1, TEST_CONNECTION_NEW, 0, NULL, NULL},
825   {"test_options_initcmd", test_options_initcmd, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
826   {"test_extended_init_values", test_extended_init_values, TEST_CONNECTION_NONE, 0,  NULL,  NULL},
827   {NULL, NULL, 0, 0, NULL, NULL}
828 };
829 
830 
main(int argc,char ** argv)831 int main(int argc, char **argv)
832 {
833   if (argc > 1)
834     get_options(argc, argv);
835 
836   get_envvars();
837 
838   diag("user: %s", username);
839 
840   run_tests(my_tests);
841 
842   return(exit_status());
843 }
844