summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt7
-rw-r--r--tests/async_queries.c435
-rw-r--r--tests/bug25714.c2
-rw-r--r--tests/check_async_queries.pl73
-rwxr-xr-xtests/consistent_snapshot.pl107
-rw-r--r--tests/fork_big2.pl284
-rw-r--r--tests/mysql_client_fw.c1536
-rw-r--r--tests/mysql_client_test.c584
-rw-r--r--tests/nonblock-wrappers.h516
-rw-r--r--tests/thread_test.c3
10 files changed, 2548 insertions, 999 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8bd6320ba62..0acad6bf30b 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -28,3 +28,10 @@ IF(WITH_UNIT_TESTS)
ENDIF()
INSTALL(TARGETS mysql_client_test DESTINATION ${INSTALL_BINDIR} COMPONENT Test)
+
+CHECK_INCLUDE_FILE(event.h HAVE_EVENT_H)
+FIND_LIBRARY(EVENT_LIBRARY event)
+IF(HAVE_EVENT_H AND EVENT_LIBRARY)
+ ADD_EXECUTABLE(async_queries async_queries.c)
+ TARGET_LINK_LIBRARIES(async_queries mysqlclient ${EVENT_LIBRARY})
+ENDIF()
diff --git a/tests/async_queries.c b/tests/async_queries.c
new file mode 100644
index 00000000000..b9393ca76ab
--- /dev/null
+++ b/tests/async_queries.c
@@ -0,0 +1,435 @@
+/*
+ Copyright 2011 Kristian Nielsen and Monty Program Ab.
+
+ This file is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*
+ Run a set of queries in parallel against a server using the non-blocking
+ API, and compare to running same queries with the normal blocking API.
+*/
+
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <mysql.h>
+#include <my_getopt.h>
+
+#include <event.h>
+
+
+#define SL(s) (s), sizeof(s)
+static const char *my_groups[]= { "client", NULL };
+
+/* Maintaining a list of queries to run. */
+struct query_entry {
+ struct query_entry *next;
+ char *query;
+ int index;
+};
+static struct query_entry *query_list;
+static struct query_entry **tail_ptr= &query_list;
+static int query_counter= 0;
+
+
+/* State kept for each connection. */
+struct state_data {
+ int ST; /* State machine current state */
+ struct event ev_mysql;
+ MYSQL mysql;
+ MYSQL_RES *result;
+ MYSQL *ret;
+ int err;
+ MYSQL_ROW row;
+ struct query_entry *query_element;
+ int index;
+};
+
+
+static const char *opt_db= NULL;
+static const char *opt_user= NULL;
+static const char *opt_password= NULL;
+static int tty_password= 0;
+static const char *opt_host= NULL;
+static const char *opt_socket= NULL;
+static unsigned int opt_port= 0;
+static unsigned int opt_connections= 5;
+static const char *opt_query_file= NULL;
+
+static struct my_option options[] =
+{
+ {"database", 'D', "Database to use", &opt_db, &opt_db,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", &opt_host, &opt_host,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.",
+ &opt_port, &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection",
+ &opt_socket, &opt_socket, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", &opt_user,
+ &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"connections", 'n', "Number of simultaneous connections/queries.",
+ &opt_connections, &opt_connections, 0, GET_UINT, REQUIRED_ARG,
+ 5, 0, 0, 0, 0, 0},
+ {"queryfile", 'q', "Name of file containing extra queries to run",
+ &opt_query_file, &opt_query_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void
+fatal(struct state_data *sd, const char *msg)
+{
+ fprintf(stderr, "%s: %s\n", msg, (sd ? mysql_error(&sd->mysql) : ""));
+ exit(1);
+}
+
+
+static void state_machine_handler(int fd, short event, void *arg);
+
+static void
+next_event(int new_st, int status, struct state_data *sd)
+{
+ short wait_event= 0;
+ struct timeval tv, *ptv;
+ int fd;
+
+ if (status & MYSQL_WAIT_READ)
+ wait_event|= EV_READ;
+ if (status & MYSQL_WAIT_WRITE)
+ wait_event|= EV_WRITE;
+ if (wait_event)
+ fd= mysql_get_socket(&sd->mysql);
+ else
+ fd= -1;
+ if (status & MYSQL_WAIT_TIMEOUT)
+ {
+ tv.tv_sec= mysql_get_timeout_value(&sd->mysql);
+ tv.tv_usec= 0;
+ ptv= &tv;
+ }
+ else
+ ptv= NULL;
+ event_set(&sd->ev_mysql, fd, wait_event, state_machine_handler, sd);
+ event_add(&sd->ev_mysql, ptv);
+ sd->ST= new_st;
+}
+
+static int
+mysql_status(short event)
+{
+ int status= 0;
+ if (event & EV_READ)
+ status|= MYSQL_WAIT_READ;
+ if (event & EV_WRITE)
+ status|= MYSQL_WAIT_WRITE;
+ if (event & EV_TIMEOUT)
+ status|= MYSQL_WAIT_TIMEOUT;
+ return status;
+}
+
+
+static int num_active_connections;
+
+/* Shortcut for going to new state immediately without waiting. */
+#define NEXT_IMMEDIATE(sd_, new_st) do { sd_->ST= new_st; goto again; } while (0)
+
+static void
+state_machine_handler(int fd __attribute__((unused)), short event, void *arg)
+{
+ struct state_data *sd= arg;
+ int status;
+
+again:
+ switch(sd->ST)
+ {
+ case 0:
+ /* Initial state, start making the connection. */
+ status= mysql_real_connect_start(&sd->ret, &sd->mysql, opt_host, opt_user, opt_password, opt_db, opt_port, opt_socket, 0);
+ if (status)
+ /* Wait for connect to complete. */
+ next_event(1, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 9);
+ break;
+
+ case 1:
+ status= mysql_real_connect_cont(&sd->ret, &sd->mysql, mysql_status(event));
+ if (status)
+ next_event(1, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 9);
+ break;
+
+ case 9:
+ if (!sd->ret)
+ fatal(sd, "Failed to mysql_real_connect()");
+ NEXT_IMMEDIATE(sd, 10);
+ break;
+
+ case 10:
+ /* Now run the next query. */
+ sd->query_element= query_list;
+ if (!sd->query_element)
+ {
+ /* No more queries, end the connection. */
+ NEXT_IMMEDIATE(sd, 40);
+ }
+ query_list= query_list->next;
+
+ sd->index= sd->query_element->index;
+ printf("%d ! %s\n", sd->index, sd->query_element->query);
+ status= mysql_real_query_start(&sd->err, &sd->mysql, sd->query_element->query,
+ strlen(sd->query_element->query));
+ if (status)
+ next_event(11, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 20);
+ break;
+
+ case 11:
+ status= mysql_real_query_cont(&sd->err, &sd->mysql, mysql_status(event));
+ if (status)
+ next_event(11, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 20);
+ break;
+
+ case 20:
+ my_free(sd->query_element->query);
+ my_free(sd->query_element);
+ if (sd->err)
+ {
+ printf("%d | Error: %s\n", sd->index, mysql_error(&sd->mysql));
+ NEXT_IMMEDIATE(sd, 10);
+ }
+ else
+ {
+ sd->result= mysql_use_result(&sd->mysql);
+ if (!sd->result)
+ fatal(sd, "mysql_use_result() returns error");
+ NEXT_IMMEDIATE(sd, 30);
+ }
+ break;
+
+ case 30:
+ status= mysql_fetch_row_start(&sd->row, sd->result);
+ if (status)
+ next_event(31, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 39);
+ break;
+
+ case 31:
+ status= mysql_fetch_row_cont(&sd->row, sd->result, mysql_status(event));
+ if (status)
+ next_event(31, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 39);
+ break;
+
+ case 39:
+ if (sd->row)
+ {
+ /* Got a row. */
+ unsigned int i;
+ printf("%d - ", sd->index);
+ for (i= 0; i < mysql_num_fields(sd->result); i++)
+ printf("%s%s", (i ? "\t" : ""), (sd->row[i] ? sd->row[i] : "(null)"));
+ printf ("\n");
+ NEXT_IMMEDIATE(sd, 30);
+ }
+ else
+ {
+ if (mysql_errno(&sd->mysql))
+ {
+ /* An error occured. */
+ printf("%d | Error: %s\n", sd->index, mysql_error(&sd->mysql));
+ }
+ else
+ {
+ /* EOF. */
+ printf("%d | EOF\n", sd->index);
+ }
+ mysql_free_result(sd->result);
+ NEXT_IMMEDIATE(sd, 10);
+ }
+ break;
+
+ case 40:
+ status= mysql_close_start(&sd->mysql);
+ if (status)
+ next_event(41, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 50);
+ break;
+
+ case 41:
+ status= mysql_close_cont(&sd->mysql, mysql_status(event));
+ if (status)
+ next_event(41, status, sd);
+ else
+ NEXT_IMMEDIATE(sd, 50);
+ break;
+
+ case 50:
+ /* We are done! */
+ num_active_connections--;
+ if (num_active_connections == 0)
+ event_loopbreak();
+ break;
+
+ default:
+ abort();
+ }
+}
+
+
+void
+add_query(const char *q)
+{
+ struct query_entry *e;
+ char *q2;
+ size_t len;
+
+ e= my_malloc(sizeof(*e), MYF(0));
+ q2= my_strdup(q, MYF(0));
+ if (!e || !q2)
+ fatal(NULL, "Out of memory");
+
+ /* Remove any trailing newline. */
+ len= strlen(q2);
+ if (q2[len] == '\n')
+ q2[len--]= '\0';
+ if (q2[len] == '\r')
+ q2[len--]= '\0';
+
+ e->next= NULL;
+ e->query= q2;
+ e->index= query_counter++;
+ *tail_ptr= e;
+ tail_ptr= &e->next;
+}
+
+
+static my_bool
+handle_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *arg)
+{
+ switch (optid)
+ {
+ case '?':
+ printf("Usage: async_queries [OPTIONS] query ...\n");
+ my_print_help(options);
+ my_print_variables(options);
+ exit(0);
+ break;
+
+ case 'p':
+ if (arg)
+ opt_password= arg;
+ else
+ tty_password= 1;
+ break;
+ }
+
+ return 0;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ struct state_data *sds;
+ unsigned int i;
+ int err;
+ struct event_base *libevent_base;
+
+ err= handle_options(&argc, &argv, options, handle_option);
+ if (err)
+ exit(err);
+ if (tty_password)
+ opt_password= get_tty_password(NullS);
+
+ if (opt_query_file)
+ {
+ FILE *f= fopen(opt_query_file, "r");
+ char buf[65536];
+ if (!f)
+ fatal(NULL, "Cannot open query file");
+ while (!feof(f))
+ {
+ if (!fgets(buf, sizeof(buf), f))
+ break;
+ add_query(buf);
+ }
+ fclose(f);
+ }
+ /* Add extra queries directly on command line. */
+ while (argc > 0)
+ {
+ --argc;
+ add_query(*argv++);
+ }
+
+ sds= my_malloc(opt_connections * sizeof(*sds), MYF(0));
+ if (!sds)
+ fatal(NULL, "Out of memory");
+
+ libevent_base= event_init();
+
+ err= mysql_library_init(argc, argv, (char **)my_groups);
+ if (err)
+ {
+ fprintf(stderr, "Fatal: mysql_library_init() returns error: %d\n", err);
+ exit(1);
+ }
+
+ num_active_connections= 0;
+ for (i= 0; i < opt_connections; i++)
+ {
+ mysql_init(&sds[i].mysql);
+ mysql_options(&sds[i].mysql, MYSQL_OPT_NONBLOCK, 0);
+ mysql_options(&sds[i].mysql, MYSQL_READ_DEFAULT_GROUP, "async_queries");
+
+ /*
+ We put the initial connect call in the first state 0 of the state machine
+ and run that manually, just to have everything in one place.
+ */
+ sds[i].ST= 0;
+ num_active_connections++;
+ state_machine_handler(-1, -1, &sds[i]);
+ }
+
+ event_dispatch();
+
+ free(sds);
+
+ mysql_library_end();
+
+ event_base_free(libevent_base);
+
+ return 0;
+}
diff --git a/tests/bug25714.c b/tests/bug25714.c
index 40c631d76a5..7e6be13624b 100644
--- a/tests/bug25714.c
+++ b/tests/bug25714.c
@@ -23,7 +23,7 @@
int main (int argc, char **argv)
{
MYSQL conn;
- int OK;
+ int OK __attribute__((unused));
const char* query4= "INSERT INTO federated.t1 SET Value=54";
const char* query5= "INSERT INTO federated.t1 SET Value=55";
diff --git a/tests/check_async_queries.pl b/tests/check_async_queries.pl
new file mode 100644
index 00000000000..b599bc334d3
--- /dev/null
+++ b/tests/check_async_queries.pl
@@ -0,0 +1,73 @@
+#! /usr/bin/perl
+
+# Read the output of async_queries.c. Run the queries again serially, using
+# the normal (not asynchronous) API. Compare the two results for correctness.
+
+use strict;
+use warnings;
+
+use DBI;
+
+my $D= [];
+
+die "Usage: $0 <host> <user> <password> <database>\n"
+ unless @ARGV == 4;
+
+my $dbh= DBI->connect("DBI:mysql:database=$ARGV[3];host=$ARGV[0]",
+ $ARGV[1], $ARGV[2],
+ { RaiseError => 1, PrintError => 0 });
+
+while (<STDIN>) {
+ chomp;
+ if (/^([0-9]+) ! (.*);$/) {
+ my ($index, $query)= ($1, $2);
+ $D->[$index]= { QUERY => $query, OUTPUT => [] };
+ } elsif (/^([0-9]+) - (.*)$/) {
+ my ($index, $data)= ($1, $2);
+ push @{$D->[$index]{OUTPUT}}, $data;
+ } elsif (/^([0-9]+) \| Error: (.*)$/) {
+ my ($index, $errmsg)= ($1, $2);
+ my $rows;
+ my $res= eval {
+ my $stm= $dbh->prepare($D->[$index]{QUERY});
+ $stm->execute();
+ $rows= $stm->fetchall_arrayref();
+ 1;
+ };
+ if ($res) {
+ die "Query $index succeeded, but should have failed with error.\nquery=$D->[$index]{QUERY}\nerror=$errmsg\n";
+ }
+ my $errmsg2= $@;
+ if ($errmsg2 =~ /^DBD::.*failed: (.*) at .*$/s) {
+ $errmsg2= $1;
+ } else {
+ die "Unexpected DBD error message format: '$errmsg2'\n";
+ }
+ if ($errmsg2 ne $errmsg) {
+ die "Query $index failed with different error message\nquery=$D->[$index]{QUERY}\nerror1=$errmsg\nerror2=$errmsg2\n";
+ }
+ print "OK $index\n";
+ delete $D->[$index];
+ } elsif (/^([0-9]+) \| EOF$/) {
+ my $index= $1;
+ my $rows;
+ my $res= eval {
+ my $stm= $dbh->prepare($D->[$index]{QUERY});
+ $stm->execute();
+ $rows= $stm->fetchall_arrayref();
+ 1;
+ };
+ if (!$res) {
+ die "Query $index failed, but should have succeeded.\nquery=$D->[$index]{QUERY}\nerror=$@\n";
+ }
+ my $result_string= join("\n", sort @{$D->[$index]{OUTPUT}});
+ my $result_string2= join("\n", sort(map(join("\t", map((defined($_) ? $_ : "(null)"), @$_)), @$rows)));
+ if ($result_string ne $result_string2) {
+ die "Query $index result difference.\nquery=$D->[$index]{QUERY}\noutput1=\n$$result_string\noutput2=\n$result_string2\n";
+ }
+ delete $D->[$index];
+ } else {
+ die "Unexpected line: '$_'\n";
+ }
+}
+$dbh->disconnect();
diff --git a/tests/consistent_snapshot.pl b/tests/consistent_snapshot.pl
new file mode 100755
index 00000000000..9e53eaea6a1
--- /dev/null
+++ b/tests/consistent_snapshot.pl
@@ -0,0 +1,107 @@
+#! /usr/bin/perl
+
+# Test START TRANSACTION WITH CONSISTENT SNAPSHOT.
+# With MWL#116, this is implemented so it is actually consistent.
+
+use strict;
+use warnings;
+
+use DBI;
+
+my $UPDATERS= 10;
+my $READERS= 5;
+
+my $ROWS= 50;
+my $DURATION= 20;
+
+my $stop_time= time() + $DURATION;
+
+sub my_connect {
+ my $dbh= DBI->connect("dbi:mysql:mysql_socket=/tmp/mysql.sock;database=test",
+ "root", undef, { RaiseError=>1, PrintError=>0, AutoCommit=>0});
+ $dbh->do("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
+ $dbh->do("SET SESSION autocommit = 0");
+ return $dbh;
+}
+
+sub my_setup {
+ my $dbh= my_connect();
+
+ $dbh->do("DROP TABLE IF EXISTS test_consistent_snapshot1, test_consistent_snapshot2");
+ $dbh->do(<<TABLE);
+CREATE TABLE test_consistent_snapshot1 (
+ a INT PRIMARY KEY,
+ b INT NOT NULL
+) ENGINE=InnoDB
+TABLE
+ $dbh->do(<<TABLE);
+CREATE TABLE test_consistent_snapshot2(
+ a INT PRIMARY KEY,
+ b INT NOT NULL
+) ENGINE=PBXT
+TABLE
+
+ for (my $i= 0; $i < $ROWS; $i++) {
+ my $value= int(rand()*1000);
+ $dbh->do("INSERT INTO test_consistent_snapshot1 VALUES (?, ?)", undef,
+ $i, $value);
+ $dbh->do("INSERT INTO test_consistent_snapshot2 VALUES (?, ?)", undef,
+ $i, -$value);
+ }
+ $dbh->commit();
+ $dbh->disconnect();
+}
+
+sub my_updater {
+ my $dbh= my_connect();
+
+ while (time() < $stop_time) {
+ my $i1= int(rand()*$ROWS);
+ my $i2= int(rand()*$ROWS);
+ my $v= int(rand()*99)-49;
+ $dbh->do("UPDATE test_consistent_snapshot1 SET b = b + ? WHERE a = ?",
+ undef, $v, $i1);
+ $dbh->do("UPDATE test_consistent_snapshot2 SET b = b - ? WHERE a = ?",
+ undef, $v, $i2);
+ $dbh->commit();
+ }
+
+ $dbh->disconnect();
+ exit(0);
+}
+
+sub my_reader {
+ my $dbh= my_connect();
+
+ my $iteration= 0;
+ while (time() < $stop_time) {
+ $dbh->do("START TRANSACTION WITH CONSISTENT SNAPSHOT");
+ my $s1= $dbh->selectrow_arrayref("SELECT SUM(b) FROM test_consistent_snapshot1");
+ $s1= $s1->[0];
+ my $s2= $dbh->selectrow_arrayref("SELECT SUM(b) FROM test_consistent_snapshot2");
+ $s2= $s2->[0];
+ $dbh->commit();
+ if ($s1 + $s2 != 0) {
+ print STDERR "Found inconsistency, s1=$s1 s2=$s2 iteration=$iteration\n";
+ last;
+ }
+ ++$iteration;
+ }
+
+ $dbh->disconnect();
+ exit(0);
+}
+
+my_setup();
+
+for (1 .. $UPDATERS) {
+ fork() || my_updater();
+}
+
+for (1 .. $READERS) {
+ fork() || my_reader();
+}
+
+waitpid(-1, 0) for (1 .. ($UPDATERS + $READERS));
+
+print "All checks done\n";
diff --git a/tests/fork_big2.pl b/tests/fork_big2.pl
index a042f18ef2e..e92cf869e52 100644
--- a/tests/fork_big2.pl
+++ b/tests/fork_big2.pl
@@ -33,21 +33,21 @@ package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_drop=$opt_fast=$opt_force=0;
-$opt_thread_factor=1;
-$opt_insert=1;
-$opt_select=6;$opt_join=4;
-$opt_select_count=$opt_join_count=0;
-$opt_update=1;$opt_delete=0;
-$opt_flush=$opt_check=$opt_repair=$opt_alter=0;
-$opt_join_range=100;
+$opt_thread_factor=1;
+$opt_insert=1;
+$opt_select=6;$opt_join=4;
+$opt_select_count=$opt_join_count=0;
+$opt_update=1;$opt_delete=0;
+$opt_flush=$opt_check=$opt_repair=$opt_alter=0;
+$opt_join_range=100;
$opt_resize_interval=0;
$opt_time=0;
$opt_host=$opt_user=$opt_password=""; $opt_db="test";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
-GetOptions("host=s","db=s","user=s","password=s","loop-count=i","skip-create","skip-in","skip-drop",
- "verbose","fast-insert","lock-tables","debug","fast","force","thread-factor=i",
- "insert=i", "select=i", "join=i", "select-count=i", "join-count=i", "update=i", "delete=i",
+GetOptions("host=s","db=s","user=s","password=s","loop-count=i","skip-create","skip-in","skip-drop",
+ "verbose","fast-insert","lock-tables","debug","fast","force","thread-factor=i",
+ "insert=i", "select=i", "join=i", "select-count=i", "join-count=i", "update=i", "delete=i",
"flush=i", "check=i", "repair=i", "alter=i", "resize-interval=i", "max-join_range=i", "time=i") || die "Aborted";
print "Test of multiple connections that test the following things:\n";
@@ -65,20 +65,20 @@ srand 100; # Make random numbers repeatable
####
#### Start timeing and start test
-####
-
+####
+
$opt_insert*=$opt_thread_factor;
-$opt_select*=$opt_thread_factor;
-$opt_join*=$opt_thread_factor;
-$opt_select_count*=$opt_thread_factor;
-$opt_join_count*=$opt_thread_factor;
-$opt_update*=$opt_thread_factor;
-$opt_delete*=$opt_thread_factor;
-
-if ($opt_time == 0 && $opt_insert == 0)
-{
- $opt_insert=1;
-}
+$opt_select*=$opt_thread_factor;
+$opt_join*=$opt_thread_factor;
+$opt_select_count*=$opt_thread_factor;
+$opt_join_count*=$opt_thread_factor;
+$opt_update*=$opt_thread_factor;
+$opt_delete*=$opt_thread_factor;
+
+if ($opt_time == 0 && $opt_insert == 0)
+{
+ $opt_insert=1;
+}
$start_time=new Benchmark;
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
@@ -117,71 +117,71 @@ $|= 1; # Autoflush
####
#### Start the tests
####
-if ($opt_time != 0)
-{
- test_abort() if (($pid=fork()) == 0); $work{$pid}="abort";
+if ($opt_time != 0)
+{
+ test_abort() if (($pid=fork()) == 0); $work{$pid}="abort";
}
for ($i=0 ; $i < $opt_insert ; $i ++)
{
test_insert() if (($pid=fork()) == 0); $work{$pid}="insert";
-}
+}
$threads=$i;
-for ($i=0 ; $i < $opt_select ; $i ++)
-{
- test_select() if (($pid=fork()) == 0); $work{$pid}="select";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_join ; $i ++)
-{
- test_join() if (($pid=fork()) == 0); $work{$pid}="join";
-}
-$threads+=$i;
+for ($i=0 ; $i < $opt_select ; $i ++)
+{
+ test_select() if (($pid=fork()) == 0); $work{$pid}="select";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_join ; $i ++)
+{
+ test_join() if (($pid=fork()) == 0); $work{$pid}="join";
+}
+$threads+=$i;
for ($i=0 ; $i < $opt_select_count ; $i ++)
{
test_select_count() if (($pid=fork()) == 0); $work{$pid}="select_count";
}
-$threads+=$i;
-for ($i=0 ; $i < $opt_join_count ; $i ++)
-{
- test_join_count() if (($pid=fork()) == 0); $work{$pid}="join_count";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_update ; $i ++)
-{
- test_update() if (($pid=fork()) == 0); $work{$pid}="update";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_delete ; $i ++)
-{
- test_delete() if (($pid=fork()) == 0); $work{$pid}="delete";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_flush ; $i ++)
-{
- test_flush() if (($pid=fork()) == 0); $work{$pid}="flush";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_check ; $i ++)
-{
- test_check() if (($pid=fork()) == 0); $work{$pid}="check";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_repair ; $i ++)
-{
- test_repair() if (($pid=fork()) == 0); $work{$pid}="repair";
-}
-$threads+=$i;
-for ($i=0 ; $i < $opt_alter ; $i ++)
-{
- test_alter() if (($pid=fork()) == 0); $work{$pid}="alter";
-}
-$threads+=$i;
+$threads+=$i;
+for ($i=0 ; $i < $opt_join_count ; $i ++)
+{
+ test_join_count() if (($pid=fork()) == 0); $work{$pid}="join_count";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_update ; $i ++)
+{
+ test_update() if (($pid=fork()) == 0); $work{$pid}="update";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_delete ; $i ++)
+{
+ test_delete() if (($pid=fork()) == 0); $work{$pid}="delete";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_flush ; $i ++)
+{
+ test_flush() if (($pid=fork()) == 0); $work{$pid}="flush";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_check ; $i ++)
+{
+ test_check() if (($pid=fork()) == 0); $work{$pid}="check";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_repair ; $i ++)
+{
+ test_repair() if (($pid=fork()) == 0); $work{$pid}="repair";
+}
+$threads+=$i;
+for ($i=0 ; $i < $opt_alter ; $i ++)
+{
+ test_alter() if (($pid=fork()) == 0); $work{$pid}="alter";
+}
+$threads+=$i;
if ($opt_resize_interval != 0)
{
test_resize() if (($pid=fork()) == 0); $work{$pid}="resize";
$threads+=1;
}
-
+
print "Started $threads threads\n";
$errors=0;
@@ -189,17 +189,17 @@ $running_insert_threads=$opt_insert;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
- if ($opt_time == 0)
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
+ if ($opt_time == 0)
{
if ($work{$pid} =~ /^insert/)
{
if (!--$running_insert_threads)
- {
-
+ {
+
# Time to stop other threads
signal_abort();
- }
+ }
}
}
$errors++ if ($ret != 0);
@@ -231,17 +231,17 @@ print "Total time: " .
exit(0);
-#
-# Sleep and then abort other threads
-#
-
-sub test_abort
-{
- sleep($opt_time);
- signal_abort();
- exit(0);
-}
-
+#
+# Sleep and then abort other threads
+#
+
+sub test_abort
+{
+ sleep($opt_time);
+ signal_abort();
+ exit(0);
+}
+
#
# Insert records in the table
@@ -380,58 +380,58 @@ sub test_join
$dbh->disconnect; $dbh=0;
print "Test_join: Executed $count joins\n";
exit(0);
-}
-
-#
-# select records
-# Do continously joins between the first and second for range and count selected rows
-#
-
-sub test_join_count
-{
- my ($dbh, $i, $j, $count, $loop);
-
- $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
- $opt_user, $opt_password,
- { PrintError => 0}) || die $DBI::errstr;
-
- $count_query=make_count_query($numtables);
- $count=0;
- $loop=9999;
- $sum=0;
-
- srand();
-
- $i=0;
- while (($i++ % 10) || !test_if_abort($dbh))
- {
- if ($loop++ >= 10)
- {
- $loop=0;
- $row_counts=simple_query($dbh, $count_query);
- }
- for ($j=0 ; $j < $numtables-1 ; $j++)
- {
- my ($id1)= int rand $row_counts->[$j];
- my ($id2)= int rand $row_counts->[$j];
- if ($id1 > $id2)
- {
- my $id0=$id1; $id1=$id2; $id2=$id0;
- if ($id2-$id1 > $opt_join_range)
- {
- $id2=$id1+$opt_join_range;
- }
- }
- my ($t1,$t2)= ($testtables[$j]->[0],$testtables[$j+1]->[0]);
- $row=simple_query($dbh, "select count(*) from $t1, $t2 where $t1.id=$t2.id and $t1.id between $id1 and $id2");
- $sum+=$row->[0];
- $count++;
- }
- }
- $dbh->disconnect; $dbh=0;
- print "Test_join_count: Executed $count joins: total $sum rows\n";
- exit(0);
-}
+}
+
+#
+# select records
+# Do continously joins between the first and second for range and count selected rows
+#
+
+sub test_join_count
+{
+ my ($dbh, $i, $j, $count, $loop);
+
+ $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+
+ $count_query=make_count_query($numtables);
+ $count=0;
+ $loop=9999;
+ $sum=0;
+
+ srand();
+
+ $i=0;
+ while (($i++ % 10) || !test_if_abort($dbh))
+ {
+ if ($loop++ >= 10)
+ {
+ $loop=0;
+ $row_counts=simple_query($dbh, $count_query);
+ }
+ for ($j=0 ; $j < $numtables-1 ; $j++)
+ {
+ my ($id1)= int rand $row_counts->[$j];
+ my ($id2)= int rand $row_counts->[$j];
+ if ($id1 > $id2)
+ {
+ my $id0=$id1; $id1=$id2; $id2=$id0;
+ if ($id2-$id1 > $opt_join_range)
+ {
+ $id2=$id1+$opt_join_range;
+ }
+ }
+ my ($t1,$t2)= ($testtables[$j]->[0],$testtables[$j+1]->[0]);
+ $row=simple_query($dbh, "select count(*) from $t1, $t2 where $t1.id=$t2.id and $t1.id between $id1 and $id2");
+ $sum+=$row->[0];
+ $count++;
+ }
+ }
+ $dbh->disconnect; $dbh=0;
+ print "Test_join_count: Executed $count joins: total $sum rows\n";
+ exit(0);
+}
#
diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c
index 5d06722361b..90a1ea77a50 100644
--- a/tests/mysql_client_fw.c
+++ b/tests/mysql_client_fw.c
@@ -17,19 +17,33 @@
#include <my_sys.h>
#include <mysql.h>
#include <errmsg.h>
+#include <my_compare.h>
#include <my_getopt.h>
#include <m_string.h>
#include <mysqld_error.h>
#include <sql_common.h>
#include <mysql/client_plugin.h>
+/*
+ If non_blocking_api_enabled is true, we will re-define all the blocking
+ API functions as wrappers that call the corresponding non-blocking API
+ and use poll()/select() to wait for them to complete. This way we can get
+ a good coverage testing of the non-blocking API as well.
+*/
+#include <my_context.h>
+static my_bool non_blocking_api_enabled= 0;
+#if !defined(EMBEDDED_LIBRARY) && !defined(MY_CONTEXT_DISABLE)
+#define WRAP_NONBLOCK_ENABLED non_blocking_api_enabled
+#include "nonblock-wrappers.h"
+#endif
+
#define VER "2.1"
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
#define MAX_KEY MAX_INDEXES
#define MAX_SERVER_ARGS 64
/* set default options */
-static int opt_testcase = 0;
+static int opt_testcase __attribute__((unused)) = 0;
static char *opt_db= 0;
static char *opt_user= 0;
static char *opt_password= 0;
@@ -59,10 +73,10 @@ static int embedded_server_arg_count= 0;
static char *embedded_server_args[MAX_SERVER_ARGS];
static const char *embedded_server_groups[]= {
-"server",
-"embedded",
-"mysql_client_test_SERVER",
-NullS
+ "server",
+ "embedded",
+ "mysql_client_test_SERVER",
+ NullS
};
static time_t start_time, end_time;
@@ -72,8 +86,8 @@ const char *default_dbug_option= "d:t:o,/tmp/mysql_client_test.trace";
struct my_tests_st
{
-const char *name;
-void (*function)();
+ const char *name;
+ void (*function)();
};
#define myheader(str) \
@@ -101,29 +115,30 @@ static void client_disconnect(MYSQL* mysql);
/*
-Abort unless given experssion is non-zero.
+ Abort unless given experssion is non-zero.
-SYNOPSIS
-DIE_UNLESS(expr)
+ SYNOPSIS
+ DIE_UNLESS(expr)
-DESCRIPTION
-We can't use any kind of system assert as we need to
-preserve tested invariants in release builds as well.
+ DESCRIPTION
+ We can't use any kind of system assert as we need to
+ preserve tested invariants in release builds as well.
*/
-#define DIE_UNLESS(expr) \
-((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
-#define DIE_IF(expr) \
-((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0))
-#define DIE(expr) \
-die(__FILE__, __LINE__, #expr)
+#define DIE_UNLESS(expr) \
+ ((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
+#define DIE_IF(expr) \
+ ((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0))
+#define DIE(expr) \
+ die(__FILE__, __LINE__, #expr)
static void die(const char *file, int line, const char *expr)
{
- fflush(stdout);
- fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr);
- fflush(stderr);
- exit(1);
+ fflush(stdout);
+ fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr);
+ fprintf(stderr, "MySQL error %d: %s\n", mysql_errno(0), mysql_error(0));
+ fflush(stderr);
+ exit(1);
}
@@ -181,7 +196,7 @@ static void die(const char *file, int line, const char *expr)
static int cmp_double(double *a, double *b)
{
- return *a == *b;
+ return *a == *b;
}
@@ -189,62 +204,64 @@ static int cmp_double(double *a, double *b)
static void print_error(const char *msg)
{
- if (!opt_silent)
- {
- if (mysql && mysql_errno(mysql))
- {
- if (mysql->server_version)
- fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
- else
- fprintf(stdout, "\n [MySQL]");
- fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
- }
- else if (msg)
- fprintf(stderr, " [MySQL] %s\n", msg);
- }
+ if (!opt_silent)
+ {
+ if (mysql && mysql_errno(mysql))
+ {
+ if (mysql->server_version)
+ fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
+ else
+ fprintf(stdout, "\n [MySQL]");
+ fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
+ }
+ else if (msg)
+ fprintf(stderr, " [MySQL] %s\n", msg);
+ }
}
static void print_st_error(MYSQL_STMT *stmt, const char *msg)
{
- if (!opt_silent)
- {
- if (stmt && mysql_stmt_errno(stmt))
- {
- if (stmt->mysql && stmt->mysql->server_version)
- fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version);
- else
- fprintf(stdout, "\n [MySQL]");
-
- fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt),
- mysql_stmt_error(stmt));
- }
- else if (msg)
- fprintf(stderr, " [MySQL] %s\n", msg);
- }
+ if (!opt_silent)
+ {
+ if (stmt && mysql_stmt_errno(stmt))
+ {
+ if (stmt->mysql && stmt->mysql->server_version)
+ fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version);
+ else
+ fprintf(stdout, "\n [MySQL]");
+
+ fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt));
+ }
+ else if (msg)
+ fprintf(stderr, " [MySQL] %s\n", msg);
+ }
}
/*
-Enhanced version of mysql_client_init(), which may also set shared memory
-base on Windows.
+ Enhanced version of mysql_client_init(), which may also set shared memory
+ base on Windows.
*/
static MYSQL *mysql_client_init(MYSQL* con)
{
- MYSQL* res = mysql_init(con);
- #ifdef HAVE_SMEM
- if (res && shared_memory_base_name)
- mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
- #endif
- if (opt_plugin_dir && *opt_plugin_dir)
- mysql_options(res, MYSQL_PLUGIN_DIR, opt_plugin_dir);
-
- if (opt_default_auth && *opt_default_auth)
- mysql_options(res, MYSQL_DEFAULT_AUTH, opt_default_auth);
- return res;
+ MYSQL* res = mysql_init(con);
+#ifdef HAVE_SMEM
+ if (res && shared_memory_base_name)
+ mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
+#endif
+ if (res && non_blocking_api_enabled)
+ mysql_options(res, MYSQL_OPT_NONBLOCK, 0);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(res, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(res, MYSQL_DEFAULT_AUTH, opt_default_auth);
+ return res;
}
/*
-Disable direct calls of mysql_init, as it disregards shared memory base.
+ Disable direct calls of mysql_init, as it disregards shared memory base.
*/
#define mysql_init(A) Please use mysql_client_init instead of mysql_init
@@ -253,119 +270,119 @@ Disable direct calls of mysql_init, as it disregards shared memory base.
static my_bool check_have_innodb(MYSQL *conn)
{
- MYSQL_RES *res;
- MYSQL_ROW row;
- int rc;
- my_bool result;
-
- rc= mysql_query(conn, "show variables like 'have_innodb'");
- myquery(rc);
- res= mysql_use_result(conn);
- DIE_UNLESS(res);
-
- row= mysql_fetch_row(res);
- DIE_UNLESS(row);
-
- result= strcmp(row[1], "YES") == 0;
- mysql_free_result(res);
- return result;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int rc;
+ my_bool result;
+
+ rc= mysql_query(conn, "show variables like 'have_innodb'");
+ myquery(rc);
+ res= mysql_use_result(conn);
+ DIE_UNLESS(res);
+
+ row= mysql_fetch_row(res);
+ DIE_UNLESS(row);
+
+ result= strcmp(row[1], "YES") == 0;
+ mysql_free_result(res);
+ return result;
}
/*
-This is to be what mysql_query() is for mysql_real_query(), for
-mysql_simple_prepare(): a variant without the 'length' parameter.
+ This is to be what mysql_query() is for mysql_real_query(), for
+ mysql_simple_prepare(): a variant without the 'length' parameter.
*/
static MYSQL_STMT *STDCALL
mysql_simple_prepare(MYSQL *mysql_arg, const char *query)
{
- MYSQL_STMT *stmt= mysql_stmt_init(mysql_arg);
- if (stmt && mysql_stmt_prepare(stmt, query, (uint) strlen(query)))
- {
- mysql_stmt_close(stmt);
- return 0;
- }
- return stmt;
+ MYSQL_STMT *stmt= mysql_stmt_init(mysql_arg);
+ if (stmt && mysql_stmt_prepare(stmt, query, (uint) strlen(query)))
+ {
+ mysql_stmt_close(stmt);
+ return 0;
+ }
+ return stmt;
}
/**
-Connect to the server with options given by arguments to this application,
-stored in global variables opt_host, opt_user, opt_password, opt_db,
-opt_port and opt_unix_socket.
+ Connect to the server with options given by arguments to this application,
+ stored in global variables opt_host, opt_user, opt_password, opt_db,
+ opt_port and opt_unix_socket.
-@param flag[in] client_flag passed on to mysql_real_connect
-@param protocol[in] MYSQL_PROTOCOL_* to use for this connection
-@param auto_reconnect[in] set to 1 for auto reconnect
+ @param flag[in] client_flag passed on to mysql_real_connect
+ @param protocol[in] MYSQL_PROTOCOL_* to use for this connection
+ @param auto_reconnect[in] set to 1 for auto reconnect
-@return pointer to initialized and connected MYSQL object
+ @return pointer to initialized and connected MYSQL object
*/
static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
{
- MYSQL* mysql;
- int rc;
- static char query[MAX_TEST_QUERY_LENGTH];
- myheader_r("client_connect");
-
- if (!opt_silent)
- fprintf(stdout, "\n Establishing a connection to '%s' ...",
- opt_host ? opt_host : "");
-
- if (!(mysql= mysql_client_init(NULL)))
- {
- opt_silent= 0;
- myerror("mysql_client_init() failed");
- exit(1);
- }
- /* enable local infile, in non-binary builds often disabled by default */
- mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
- mysql_options(mysql, MYSQL_OPT_PROTOCOL, &protocol);
- if (opt_plugin_dir && *opt_plugin_dir)
- mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
-
- if (opt_default_auth && *opt_default_auth)
- mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
-
- if (!(mysql_real_connect(mysql, opt_host, opt_user,
- opt_password, opt_db ? opt_db:"test", opt_port,
- opt_unix_socket, flag)))
- {
- opt_silent= 0;
- myerror("connection failed");
- mysql_close(mysql);
- fprintf(stdout, "\n Check the connection options using --help or -?\n");
- exit(1);
- }
- mysql->reconnect= auto_reconnect;
-
- if (!opt_silent)
- fprintf(stdout, "OK");
-
- /* set AUTOCOMMIT to ON*/
- mysql_autocommit(mysql, TRUE);
-
- if (!opt_silent)
- {
- fprintf(stdout, "\nConnected to MySQL server version: %s (%lu)\n",
- mysql_get_server_info(mysql),
- (ulong) mysql_get_server_version(mysql));
- fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
- }
- strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
-
- rc= mysql_query(mysql, query);
- myquery(rc);
-
- strxmov(query, "USE ", current_db, NullS);
- rc= mysql_query(mysql, query);
- myquery(rc);
- have_innodb= check_have_innodb(mysql);
-
- if (!opt_silent)
- fprintf(stdout, "OK");
-
- return mysql;
+ MYSQL* mysql;
+ int rc;
+ static char query[MAX_TEST_QUERY_LENGTH];
+ myheader_r("client_connect");
+
+ if (!opt_silent)
+ fprintf(stdout, "\n Establishing a connection to '%s' ...",
+ opt_host ? opt_host : "");
+
+ if (!(mysql= mysql_client_init(NULL)))
+ {
+ opt_silent= 0;
+ myerror("mysql_client_init() failed");
+ exit(1);
+ }
+ /* enable local infile, in non-binary builds often disabled by default */
+ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
+ mysql_options(mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ if (!(mysql_real_connect(mysql, opt_host, opt_user,
+ opt_password, opt_db ? opt_db:"test", opt_port,
+ opt_unix_socket, flag)))
+ {
+ opt_silent= 0;
+ myerror("connection failed");
+ mysql_close(mysql);
+ fprintf(stdout, "\n Check the connection options using --help or -?\n");
+ exit(1);
+ }
+ mysql->reconnect= auto_reconnect;
+
+ if (!opt_silent)
+ fprintf(stdout, "OK");
+
+ /* set AUTOCOMMIT to ON*/
+ mysql_autocommit(mysql, TRUE);
+
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\nConnected to MySQL server version: %s (%lu)\n",
+ mysql_get_server_info(mysql),
+ (ulong) mysql_get_server_version(mysql));
+ fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
+ }
+ strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ strxmov(query, "USE ", current_db, NullS);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+ have_innodb= check_have_innodb(mysql);
+
+ if (!opt_silent)
+ fprintf(stdout, "OK\n");
+
+ return mysql;
}
@@ -403,21 +420,21 @@ static void client_disconnect(MYSQL* mysql)
static void my_print_dashes(MYSQL_RES *result)
{
- MYSQL_FIELD *field;
- unsigned int i, j;
-
- mysql_field_seek(result, 0);
- fputc('\t', stdout);
- fputc('+', stdout);
-
- for(i= 0; i< mysql_num_fields(result); i++)
- {
- field= mysql_fetch_field(result);
- for(j= 0; j < field->max_length+2; j++)
- fputc('-', stdout);
- fputc('+', stdout);
- }
- fputc('\n', stdout);
+ MYSQL_FIELD *field;
+ unsigned int i, j;
+
+ mysql_field_seek(result, 0);
+ fputc('\t', stdout);
+ fputc('+', stdout);
+
+ for(i= 0; i< mysql_num_fields(result); i++)
+ {
+ field= mysql_fetch_field(result);
+ for(j= 0; j < field->max_length+2; j++)
+ fputc('-', stdout);
+ fputc('+', stdout);
+ }
+ fputc('\n', stdout);
}
@@ -425,47 +442,47 @@ static void my_print_dashes(MYSQL_RES *result)
static void my_print_result_metadata(MYSQL_RES *result)
{
- MYSQL_FIELD *field;
- unsigned int i, j;
- unsigned int field_count;
-
- mysql_field_seek(result, 0);
- if (!opt_silent)
- {
- fputc('\n', stdout);
- fputc('\n', stdout);
- }
-
- field_count= mysql_num_fields(result);
- for(i= 0; i< field_count; i++)
- {
- field= mysql_fetch_field(result);
- j= strlen(field->name);
- if (j < field->max_length)
- j= field->max_length;
- if (j < 4 && !IS_NOT_NULL(field->flags))
- j= 4;
- field->max_length= j;
- }
- if (!opt_silent)
- {
- my_print_dashes(result);
- fputc('\t', stdout);
- fputc('|', stdout);
- }
-
- mysql_field_seek(result, 0);
- for(i= 0; i< field_count; i++)
- {
- field= mysql_fetch_field(result);
- if (!opt_silent)
- fprintf(stdout, " %-*s |", (int) field->max_length, field->name);
- }
- if (!opt_silent)
- {
- fputc('\n', stdout);
- my_print_dashes(result);
- }
+ MYSQL_FIELD *field;
+ unsigned int i, j;
+ unsigned int field_count;
+
+ mysql_field_seek(result, 0);
+ if (!opt_silent)
+ {
+ fputc('\n', stdout);
+ fputc('\n', stdout);
+ }
+
+ field_count= mysql_num_fields(result);
+ for(i= 0; i< field_count; i++)
+ {
+ field= mysql_fetch_field(result);
+ j= strlen(field->name);
+ if (j < field->max_length)
+ j= field->max_length;
+ if (j < 4 && !IS_NOT_NULL(field->flags))
+ j= 4;
+ field->max_length= j;
+ }
+ if (!opt_silent)
+ {
+ my_print_dashes(result);
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
+
+ mysql_field_seek(result, 0);
+ for(i= 0; i< field_count; i++)
+ {
+ field= mysql_fetch_field(result);
+ if (!opt_silent)
+ fprintf(stdout, " %-*s |", (int) field->max_length, field->name);
+ }
+ if (!opt_silent)
+ {
+ fputc('\n', stdout);
+ my_print_dashes(result);
+ }
}
@@ -473,72 +490,72 @@ static void my_print_result_metadata(MYSQL_RES *result)
static int my_process_result_set(MYSQL_RES *result)
{
- MYSQL_ROW row;
- MYSQL_FIELD *field;
- unsigned int i;
- unsigned int row_count= 0;
-
- if (!result)
- return 0;
-
- my_print_result_metadata(result);
-
- while ((row= mysql_fetch_row(result)) != NULL)
- {
- mysql_field_seek(result, 0);
- if (!opt_silent)
- {
- fputc('\t', stdout);
- fputc('|', stdout);
- }
-
- for(i= 0; i< mysql_num_fields(result); i++)
- {
- field= mysql_fetch_field(result);
- if (!opt_silent)
- {
- if (row[i] == NULL)
- fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
- else if (IS_NUM(field->type))
- fprintf(stdout, " %*s |", (int) field->max_length, row[i]);
- else
- fprintf(stdout, " %-*s |", (int) field->max_length, row[i]);
- }
- }
- if (!opt_silent)
- {
- fputc('\t', stdout);
- fputc('\n', stdout);
- }
- row_count++;
- }
- if (!opt_silent)
- {
- if (row_count)
- my_print_dashes(result);
-
- if (mysql_errno(mysql) != 0)
- fprintf(stderr, "\n\tmysql_fetch_row() failed\n");
- else
- fprintf(stdout, "\n\t%d %s returned\n", row_count,
- row_count == 1 ? "row" : "rows");
- }
- return row_count;
+ MYSQL_ROW row;
+ MYSQL_FIELD *field;
+ unsigned int i;
+ unsigned int row_count= 0;
+
+ if (!result)
+ return 0;
+
+ my_print_result_metadata(result);
+
+ while ((row= mysql_fetch_row(result)) != NULL)
+ {
+ mysql_field_seek(result, 0);
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
+
+ for(i= 0; i< mysql_num_fields(result); i++)
+ {
+ field= mysql_fetch_field(result);
+ if (!opt_silent)
+ {
+ if (row[i] == NULL)
+ fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
+ else if (IS_NUM(field->type))
+ fprintf(stdout, " %*s |", (int) field->max_length, row[i]);
+ else
+ fprintf(stdout, " %-*s |", (int) field->max_length, row[i]);
+ }
+ }
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('\n', stdout);
+ }
+ row_count++;
+ }
+ if (!opt_silent)
+ {
+ if (row_count)
+ my_print_dashes(result);
+
+ if (mysql_errno(mysql) != 0)
+ fprintf(stderr, "\n\tmysql_fetch_row() failed\n");
+ else
+ fprintf(stdout, "\n\t%d %s returned\n", row_count,
+ row_count == 1 ? "row" : "rows");
+ }
+ return row_count;
}
static int my_process_result(MYSQL *mysql_arg)
{
- MYSQL_RES *result;
- int row_count;
+ MYSQL_RES *result;
+ int row_count;
- if (!(result= mysql_store_result(mysql_arg)))
- return 0;
+ if (!(result= mysql_store_result(mysql_arg)))
+ return 0;
- row_count= my_process_result_set(result);
+ row_count= my_process_result_set(result);
- mysql_free_result(result);
- return row_count;
+ mysql_free_result(result);
+ return row_count;
}
@@ -549,91 +566,91 @@ static int my_process_result(MYSQL *mysql_arg)
static int my_process_stmt_result(MYSQL_STMT *stmt)
{
- int field_count;
- int row_count= 0;
- MYSQL_BIND buffer[MAX_RES_FIELDS];
- MYSQL_FIELD *field;
- MYSQL_RES *result;
- char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE];
- ulong length[MAX_RES_FIELDS];
- my_bool is_null[MAX_RES_FIELDS];
- int rc, i;
-
- if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */
- {
- while (!mysql_stmt_fetch(stmt))
- row_count++;
- return row_count;
- }
-
- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
-
- bzero((char*) buffer, sizeof(buffer));
- bzero((char*) length, sizeof(length));
- bzero((char*) is_null, sizeof(is_null));
-
- for(i= 0; i < field_count; i++)
- {
- buffer[i].buffer_type= MYSQL_TYPE_STRING;
- buffer[i].buffer_length= MAX_FIELD_DATA_SIZE;
- buffer[i].length= &length[i];
- buffer[i].buffer= (void *) data[i];
- buffer[i].is_null= &is_null[i];
- }
-
- rc= mysql_stmt_bind_result(stmt, buffer);
- check_execute(stmt, rc);
-
- rc= 1;
- mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc);
- rc= mysql_stmt_store_result(stmt);
- check_execute(stmt, rc);
- my_print_result_metadata(result);
-
- mysql_field_seek(result, 0);
- while ((rc= mysql_stmt_fetch(stmt)) == 0)
- {
- if (!opt_silent)
- {
- fputc('\t', stdout);
- fputc('|', stdout);
- }
- mysql_field_seek(result, 0);
- for (i= 0; i < field_count; i++)
- {
- field= mysql_fetch_field(result);
- if (!opt_silent)
- {
- if (is_null[i])
- fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
- else if (length[i] == 0)
- {
- data[i][0]= '\0'; /* unmodified buffer */
- fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
- }
- else if (IS_NUM(field->type))
- fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
- else
- fprintf(stdout, " %-*s |", (int) field->max_length, data[i]);
- }
- }
- if (!opt_silent)
- {
- fputc('\t', stdout);
- fputc('\n', stdout);
- }
- row_count++;
- }
- DIE_UNLESS(rc == MYSQL_NO_DATA);
- if (!opt_silent)
- {
- if (row_count)
- my_print_dashes(result);
- fprintf(stdout, "\n\t%d %s returned\n", row_count,
- row_count == 1 ? "row" : "rows");
- }
- mysql_free_result(result);
- return row_count;
+ int field_count;
+ int row_count= 0;
+ MYSQL_BIND buffer[MAX_RES_FIELDS];
+ MYSQL_FIELD *field;
+ MYSQL_RES *result;
+ char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE];
+ ulong length[MAX_RES_FIELDS];
+ my_bool is_null[MAX_RES_FIELDS];
+ int rc, i;
+
+ if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */
+ {
+ while (!mysql_stmt_fetch(stmt))
+ row_count++;
+ return row_count;
+ }
+
+ field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+ bzero((char*) is_null, sizeof(is_null));
+
+ for(i= 0; i < field_count; i++)
+ {
+ buffer[i].buffer_type= MYSQL_TYPE_STRING;
+ buffer[i].buffer_length= MAX_FIELD_DATA_SIZE;
+ buffer[i].length= &length[i];
+ buffer[i].buffer= (void *) data[i];
+ buffer[i].is_null= &is_null[i];
+ }
+
+ rc= mysql_stmt_bind_result(stmt, buffer);
+ check_execute(stmt, rc);
+
+ rc= 1;
+ mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc);
+ rc= mysql_stmt_store_result(stmt);
+ check_execute(stmt, rc);
+ my_print_result_metadata(result);
+
+ mysql_field_seek(result, 0);
+ while ((rc= mysql_stmt_fetch(stmt)) == 0)
+ {
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('|', stdout);
+ }
+ mysql_field_seek(result, 0);
+ for (i= 0; i < field_count; i++)
+ {
+ field= mysql_fetch_field(result);
+ if (!opt_silent)
+ {
+ if (is_null[i])
+ fprintf(stdout, " %-*s |", (int) field->max_length, "NULL");
+ else if (length[i] == 0)
+ {
+ data[i][0]= '\0'; /* unmodified buffer */
+ fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
+ }
+ else if (IS_NUM(field->type))
+ fprintf(stdout, " %*s |", (int) field->max_length, data[i]);
+ else
+ fprintf(stdout, " %-*s |", (int) field->max_length, data[i]);
+ }
+ }
+ if (!opt_silent)
+ {
+ fputc('\t', stdout);
+ fputc('\n', stdout);
+ }
+ row_count++;
+ }
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+ if (!opt_silent)
+ {
+ if (row_count)
+ my_print_dashes(result);
+ fprintf(stdout, "\n\t%d %s returned\n", row_count,
+ row_count == 1 ? "row" : "rows");
+ }
+ mysql_free_result(result);
+ return row_count;
}
@@ -641,176 +658,178 @@ static int my_process_stmt_result(MYSQL_STMT *stmt)
int my_stmt_result(const char *buff)
{
- MYSQL_STMT *stmt;
- int row_count;
- int rc;
+ MYSQL_STMT *stmt;
+ int row_count;
+ int rc;
- if (!opt_silent)
- fprintf(stdout, "\n\n %s", buff);
- stmt= mysql_simple_prepare(mysql, buff);
- check_stmt(stmt);
+ if (!opt_silent)
+ fprintf(stdout, "\n\n %s", buff);
+ stmt= mysql_simple_prepare(mysql, buff);
+ check_stmt(stmt);
- rc= mysql_stmt_execute(stmt);
- check_execute(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
- row_count= my_process_stmt_result(stmt);
- mysql_stmt_close(stmt);
+ row_count= my_process_stmt_result(stmt);
+ mysql_stmt_close(stmt);
- return row_count;
+ return row_count;
}
/* Print the total number of warnings and the warnings themselves. */
void my_process_warnings(MYSQL *conn, unsigned expected_warning_count)
{
- MYSQL_RES *result;
- int rc;
+ MYSQL_RES *result;
+ int rc;
- if (!opt_silent)
- fprintf(stdout, "\n total warnings: %u (expected: %u)\n",
- mysql_warning_count(conn), expected_warning_count);
+ if (!opt_silent)
+ fprintf(stdout, "\n total warnings: %u (expected: %u)\n",
+ mysql_warning_count(conn), expected_warning_count);
- DIE_UNLESS(mysql_warning_count(mysql) == expected_warning_count);
+ DIE_UNLESS(mysql_warning_count(mysql) == expected_warning_count);
- rc= mysql_query(conn, "SHOW WARNINGS");
- DIE_UNLESS(rc == 0);
+ rc= mysql_query(conn, "SHOW WARNINGS");
+ DIE_UNLESS(rc == 0);
- result= mysql_store_result(conn);
- mytest(result);
+ result= mysql_store_result(conn);
+ mytest(result);
- rc= my_process_result_set(result);
- mysql_free_result(result);
+ rc= my_process_result_set(result);
+ mysql_free_result(result);
}
/* Utility function to verify a particular column data */
static void verify_col_data(const char *table, const char *col,
-const char *exp_data)
+ const char *exp_data)
{
- static char query[MAX_TEST_QUERY_LENGTH];
- MYSQL_RES *result;
- MYSQL_ROW row;
- int rc, field= 1;
-
- if (table && col)
- {
- strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS);
- if (!opt_silent)
- fprintf(stdout, "\n %s", query);
- rc= mysql_query(mysql, query);
- myquery(rc);
-
- field= 0;
- }
-
- result= mysql_use_result(mysql);
- mytest(result);
-
- if (!(row= mysql_fetch_row(result)) || !row[field])
- {
- fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
- exit(1);
- }
- if (strcmp(row[field], exp_data))
- {
- fprintf(stdout, "\n obtained: `%s` (expected: `%s`)",
- row[field], exp_data);
- DIE_UNLESS(FALSE);
- }
- mysql_free_result(result);
+ static char query[MAX_TEST_QUERY_LENGTH];
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ int rc, field= 1;
+
+ if (table && col)
+ {
+ strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS);
+ if (!opt_silent)
+ fprintf(stdout, "\n %s", query);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ field= 0;
+ }
+
+ result= mysql_use_result(mysql);
+ mytest(result);
+
+ if (!(row= mysql_fetch_row(result)) || !row[field])
+ {
+ fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
+ exit(1);
+ }
+ if (strcmp(row[field], exp_data))
+ {
+ fprintf(stdout, "\n obtained: `%s` (expected: `%s`)",
+ row[field], exp_data);
+ DIE_UNLESS(FALSE);
+ }
+ mysql_free_result(result);
}
/* Utility function to verify the field members */
-#define verify_prepare_field(result,no,name,org_name,type,table, \
-org_table,db,length,def) \
-do_verify_prepare_field((result),(no),(name),(org_name),(type), \
-(table),(org_table),(db),(length),(def), \
-__FILE__, __LINE__)
+#define verify_prepare_field(result,no,name,org_name,type,table,\
+ org_table,db,length,def) \
+ do_verify_prepare_field((result),(no),(name),(org_name),(type), \
+ (table),(org_table),(db),(length),(def), \
+ __FILE__, __LINE__)
static void do_verify_prepare_field(MYSQL_RES *result,
-unsigned int no, const char *name,
-const char *org_name,
-enum enum_field_types type,
-const char *table,
-const char *org_table, const char *db,
-unsigned long length, const char *def,
-const char *file, int line)
+ unsigned int no, const char *name,
+ const char *org_name,
+ enum enum_field_types type,
+ const char *table,
+ const char *org_table, const char *db,
+ unsigned long length, const char *def,
+ const char *file, int line)
{
- MYSQL_FIELD *field;
- CHARSET_INFO *cs;
- ulonglong expected_field_length;
-
- if (!(field= mysql_fetch_field_direct(result, no)))
- {
- fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
- exit(1);
- }
- cs= get_charset(field->charsetnr, 0);
- DIE_UNLESS(cs);
- if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
- expected_field_length= UINT_MAX32;
- if (!opt_silent)
- {
- fprintf(stdout, "\n field[%d]:", no);
- fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name);
- fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)",
- field->org_name, org_name);
- fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type);
- if (table)
- fprintf(stdout, "\n table :`%s`\t(expected: `%s`)",
- field->table, table);
- if (org_table)
- fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
- field->org_table, org_table);
- fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
- fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)",
- field->length, expected_field_length);
- fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
- fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
- fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
- field->def ? field->def : "(null)", def ? def: "(null)");
- fprintf(stdout, "\n");
- }
- DIE_UNLESS(strcmp(field->name, name) == 0);
- DIE_UNLESS(strcmp(field->org_name, org_name) == 0);
- /*
- XXX: silent column specification change works based on number of
- bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even
- for CHAR(2) column if its character set is multibyte.
- VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would
- expect.
- */
- if (cs->mbmaxlen == 1)
- {
- if (field->type != type)
- {
- fprintf(stderr,
- "Expected field type: %d, got type: %d in file %s, line %d\n",
- (int) type, (int) field->type, file, line);
- DIE_UNLESS(field->type == type);
- }
- }
- if (table)
- DIE_UNLESS(strcmp(field->table, table) == 0);
- if (org_table)
- DIE_UNLESS(strcmp(field->org_table, org_table) == 0);
- DIE_UNLESS(strcmp(field->db, db) == 0);
- /*
- Character set should be taken into account for multibyte encodings, such
- as utf8. Field length is calculated as number of characters * maximum
- number of bytes a character can occupy.
- */
- if (length && (field->length != expected_field_length))
- {
- fprintf(stderr, "Expected field length: %llu, got length: %lu\n",
- expected_field_length, field->length);
- DIE_UNLESS(field->length == expected_field_length);
- }
- if (def)
- DIE_UNLESS(strcmp(field->def, def) == 0);
+ MYSQL_FIELD *field;
+ CHARSET_INFO *cs;
+ ulonglong expected_field_length;
+
+ if (!(field= mysql_fetch_field_direct(result, no)))
+ {
+ fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***");
+ exit(1);
+ }
+ cs= get_charset(field->charsetnr, 0);
+ DIE_UNLESS(cs);
+ if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
+ expected_field_length= UINT_MAX32;
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n field[%d]:", no);
+ fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name);
+ fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)",
+ field->org_name, org_name);
+ fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type);
+ if (table)
+ fprintf(stdout, "\n table :`%s`\t(expected: `%s`)",
+ field->table, table);
+ if (org_table)
+ fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
+ field->org_table, org_table);
+ fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
+ fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)",
+ field->length, expected_field_length);
+ fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
+ fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
+ fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
+ field->def ? field->def : "(null)", def ? def: "(null)");
+ fprintf(stdout, "\n");
+ }
+ DIE_UNLESS(strcmp(field->name, name) == 0);
+ DIE_UNLESS(strcmp(field->org_name, org_name) == 0);
+ /*
+ XXX: silent column specification change works based on number of
+ bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even
+ for CHAR(2) column if its character set is multibyte.
+ VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would
+ expect.
+ */
+ if (cs->mbmaxlen == 1)
+ {
+ if (field->type != type)
+ {
+ fprintf(stderr,
+ "Expected field type: %d, got type: %d in file %s, line %d\n",
+ (int) type, (int) field->type, file, line);
+ DIE_UNLESS(field->type == type);
+ }
+ }
+ if (table)
+ DIE_UNLESS(strcmp(field->table, table) == 0);
+ if (org_table)
+ DIE_UNLESS(strcmp(field->org_table, org_table) == 0);
+ DIE_UNLESS(strcmp(field->db, db) == 0);
+ /*
+ Character set should be taken into account for multibyte encodings, such
+ as utf8. Field length is calculated as number of characters * maximum
+ number of bytes a character can occupy.
+ */
+ if (length && (field->length != expected_field_length))
+ {
+ fflush(stdout);
+ fprintf(stderr, "Expected field length: %llu, got length: %lu\n",
+ expected_field_length, field->length);
+ fflush(stderr);
+ DIE_UNLESS(field->length == expected_field_length);
+ }
+ if (def)
+ DIE_UNLESS(strcmp(field->def, def) == 0);
}
@@ -818,11 +837,11 @@ const char *file, int line)
static void verify_param_count(MYSQL_STMT *stmt, long exp_count)
{
- long param_count= mysql_stmt_param_count(stmt);
- if (!opt_silent)
- fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)",
- param_count, exp_count);
- DIE_UNLESS(param_count == exp_count);
+ long param_count= mysql_stmt_param_count(stmt);
+ if (!opt_silent)
+ fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)",
+ param_count, exp_count);
+ DIE_UNLESS(param_count == exp_count);
}
@@ -830,11 +849,11 @@ static void verify_param_count(MYSQL_STMT *stmt, long exp_count)
static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count)
{
- ulonglong affected_rows= mysql_stmt_affected_rows(stmt);
- if (!opt_silent)
- fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
- (long) affected_rows, (long) exp_count);
- DIE_UNLESS(affected_rows == exp_count);
+ ulonglong affected_rows= mysql_stmt_affected_rows(stmt);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
+ (long) affected_rows, (long) exp_count);
+ DIE_UNLESS(affected_rows == exp_count);
}
@@ -842,11 +861,11 @@ static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count)
static void verify_affected_rows(ulonglong exp_count)
{
- ulonglong affected_rows= mysql_affected_rows(mysql);
- if (!opt_silent)
- fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
- (long) affected_rows, (long) exp_count);
- DIE_UNLESS(affected_rows == exp_count);
+ ulonglong affected_rows= mysql_affected_rows(mysql);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
+ (long) affected_rows, (long) exp_count);
+ DIE_UNLESS(affected_rows == exp_count);
}
@@ -854,11 +873,11 @@ static void verify_affected_rows(ulonglong exp_count)
static void verify_field_count(MYSQL_RES *result, uint exp_count)
{
- uint field_count= mysql_num_fields(result);
- if (!opt_silent)
- fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)",
- field_count, exp_count);
- DIE_UNLESS(field_count == exp_count);
+ uint field_count= mysql_num_fields(result);
+ if (!opt_silent)
+ fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)",
+ field_count, exp_count);
+ DIE_UNLESS(field_count == exp_count);
}
@@ -867,23 +886,23 @@ static void verify_field_count(MYSQL_RES *result, uint exp_count)
#ifndef EMBEDDED_LIBRARY
static void execute_prepare_query(const char *query, ulonglong exp_count)
{
- MYSQL_STMT *stmt;
- ulonglong affected_rows;
- int rc;
+ MYSQL_STMT *stmt;
+ ulonglong affected_rows;
+ int rc;
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
+ stmt= mysql_simple_prepare(mysql, query);
+ check_stmt(stmt);
- rc= mysql_stmt_execute(stmt);
- myquery(rc);
+ rc= mysql_stmt_execute(stmt);
+ myquery(rc);
- affected_rows= mysql_stmt_affected_rows(stmt);
- if (!opt_silent)
- fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
- (long) affected_rows, (long) exp_count);
+ affected_rows= mysql_stmt_affected_rows(stmt);
+ if (!opt_silent)
+ fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
+ (long) affected_rows, (long) exp_count);
- DIE_UNLESS(affected_rows == exp_count);
- mysql_stmt_close(stmt);
+ DIE_UNLESS(affected_rows == exp_count);
+ mysql_stmt_close(stmt);
}
#endif
@@ -1149,89 +1168,94 @@ static my_bool thread_query(const char *query)
/*
-Read and parse arguments and MySQL options from my.cnf
+ Read and parse arguments and MySQL options from my.cnf
*/
-static const char *client_test_load_default_groups[]= { "client", 0 };
+static const char *client_test_load_default_groups[]=
+{ "client", "client-server", "client-mariadb", 0 };
static char **defaults_argv;
static struct my_option client_test_long_options[] =
{
-{"basedir", 'b', "Basedir for tests.", &opt_basedir,
- &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"count", 't', "Number of times test to be executed", &opt_count,
- &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
-{"database", 'D', "Database to use", &opt_db, &opt_db,
- 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"do-not-drop-database", 'd', "Do not drop database while disconnecting",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-{"debug", '#', "Output debug log", &default_dbug_option,
- &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-{"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
- 0, 0, 0, 0, 0},
-{"host", 'h', "Connect to host", &opt_host, &opt_host,
- 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"password", 'p',
- "Password to use when connecting to server. If password is not given it's asked from the tty.",
- 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-{"port", 'P', "Port number to use for connection or 0 for default to, in "
- "order of preference, my.cnf, $MYSQL_TCP_PORT, "
- #if MYSQL_PORT_DEFAULT == 0
- "/etc/services, "
- #endif
- "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
- &opt_port, &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"server-arg", 'A', "Send embedded server this as a parameter.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
-{"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
- 0},
+ {"basedir", 'b', "Basedir for tests.", &opt_basedir,
+ &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"count", 't', "Number of times test to be executed", &opt_count,
+ &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
+ {"database", 'D', "Database to use", &opt_db, &opt_db,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"do-not-drop-database", 'd', "Do not drop database while disconnecting",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log", &default_dbug_option,
+ &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", &opt_host, &opt_host,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection or 0 for default to, in "
+ "order of preference, my.cnf, $MYSQL_TCP_PORT, "
+#if MYSQL_PORT_DEFAULT == 0
+ "/etc/services, "
+#endif
+ "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
+ &opt_port, &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-arg", 'A', "Send embedded server this as a parameter.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
#ifdef HAVE_SMEM
-{"shared-memory-base-name", 'm', "Base name of shared memory.",
- &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"shared-memory-base-name", 'm', "Base name of shared memory.",
+ &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
-{"socket", 'S', "Socket file to use for connection",
- &opt_unix_socket, &opt_unix_socket, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"testcase", 'c',
- "May disable some code when runs as mysql-test-run testcase.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection",
+ &opt_unix_socket, &opt_unix_socket, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"testcase", 'c',
+ "May disable some code when runs as mysql-test-run testcase.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
-{"user", 'u', "User for login if not current user", &opt_user,
- &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", &opt_user,
+ &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
-{"vardir", 'v', "Data dir for tests.", &opt_vardir,
- &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"getopt-ll-test", 'g', "Option for testing bug in getopt library",
- &opt_getopt_ll_test, &opt_getopt_ll_test, 0,
- GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0},
-{"plugin_dir", 0, "Directory for client-side plugins.",
- &opt_plugin_dir, &opt_plugin_dir, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{"default_auth", 0, "Default authentication client-side plugin to use.",
- &opt_default_auth, &opt_default_auth, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+ {"vardir", 'v', "Data dir for tests.", &opt_vardir,
+ &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"non-blocking-api", 'n',
+ "Use the non-blocking client API for communication.",
+ &non_blocking_api_enabled, &non_blocking_api_enabled, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"getopt-ll-test", 'g', "Option for testing bug in getopt library",
+ &opt_getopt_ll_test, &opt_getopt_ll_test, 0,
+ GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0},
+ {"plugin_dir", 0, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", 0, "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void usage(void)
{
-/* show the usage string when the user asks for this */
- putc('\n', stdout);
- printf("%s Ver %s Distrib %s, for %s (%s)\n",
- my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
- puts("By Monty, Venu, Kent and others\n");
- printf("\
+ /* show the usage string when the user asks for this */
+ putc('\n', stdout);
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",
+ my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+ puts("By Monty, Venu, Kent and others\n");
+ printf("\
Copyright (C) 2002-2004 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n");
- printf("Usage: %s [OPTIONS] [TESTNAME1 TESTNAME2...]\n", my_progname);
- my_print_help(client_test_long_options);
- print_defaults("my", client_test_load_default_groups);
- my_print_variables(client_test_long_options);
+ printf("Usage: %s [OPTIONS] [TESTNAME1 TESTNAME2...]\n", my_progname);
+ my_print_help(client_test_long_options);
+ print_defaults("my", client_test_load_default_groups);
+ my_print_variables(client_test_long_options);
}
static struct my_tests_st *get_my_tests(); /* To be defined in main .c file */
@@ -1240,185 +1264,185 @@ static struct my_tests_st *my_testlist= 0;
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
-char *argument)
+ char *argument)
{
- switch (optid) {
- case '#':
- DBUG_PUSH(argument ? argument : default_dbug_option);
- break;
- case 'c':
- opt_testcase = 1;
- break;
- case 'p':
- if (argument)
- {
- char *start=argument;
- my_free(opt_password);
- opt_password= my_strdup(argument, MYF(MY_FAE));
- while (*argument) *argument++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0;
- }
- else
- tty_password= 1;
- break;
- case 's':
- if (argument == disabled_my_option)
- opt_silent= 0;
- else
- opt_silent++;
- break;
- case 'd':
- opt_drop_db= 0;
- break;
- case 'A':
- /*
- When the embedded server is being tested, the test suite needs to be
- able to pass command-line arguments to the embedded server so it can
- locate the language files and data directory. The test suite
- (mysql-test-run) never uses config files, just command-line options.
- */
- if (!embedded_server_arg_count)
- {
- embedded_server_arg_count= 1;
- embedded_server_args[0]= (char*) "";
- }
- if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
- !(embedded_server_args[embedded_server_arg_count++]=
- my_strdup(argument, MYF(MY_FAE))))
- {
- DIE("Can't use server argument");
- }
- break;
- case 'T':
- {
- struct my_tests_st *fptr;
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ break;
+ case 'c':
+ opt_testcase = 1;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password);
+ opt_password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0;
+ }
+ else
+ tty_password= 1;
+ break;
+ case 's':
+ if (argument == disabled_my_option)
+ opt_silent= 0;
+ else
+ opt_silent++;
+ break;
+ case 'd':
+ opt_drop_db= 0;
+ break;
+ case 'A':
+ /*
+ When the embedded server is being tested, the test suite needs to be
+ able to pass command-line arguments to the embedded server so it can
+ locate the language files and data directory. The test suite
+ (mysql-test-run) never uses config files, just command-line options.
+ */
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count= 1;
+ embedded_server_args[0]= (char*) "";
+ }
+ if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
+ !(embedded_server_args[embedded_server_arg_count++]=
+ my_strdup(argument, MYF(MY_FAE))))
+ {
+ DIE("Can't use server argument");
+ }
+ break;
+ case 'T':
+ {
+ struct my_tests_st *fptr;
- printf("All possible test names:\n\n");
- for (fptr= my_testlist; fptr->name; fptr++)
- printf("%s\n", fptr->name);
- exit(0);
- break;
- }
- case '?':
- case 'I': /* Info */
- usage();
- exit(0);
- break;
- }
- return 0;
+ printf("All possible test names:\n\n");
+ for (fptr= my_testlist; fptr->name; fptr++)
+ printf("%s\n", fptr->name);
+ exit(0);
+ break;
+ }
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(0);
+ break;
+ }
+ return 0;
}
static void get_options(int *argc, char ***argv)
{
- int ho_error;
+ int ho_error;
- if ((ho_error= handle_options(argc, argv, client_test_long_options,
- get_one_option)))
- exit(ho_error);
+ if ((ho_error= handle_options(argc, argv, client_test_long_options,
+ get_one_option)))
+ exit(ho_error);
- if (tty_password)
- opt_password= get_tty_password(NullS);
- return;
+ if (tty_password)
+ opt_password= get_tty_password(NullS);
+ return;
}
/*
-Print the test output on successful execution before exiting
+ Print the test output on successful execution before exiting
*/
static void print_test_output()
{
- if (opt_silent < 3)
- {
- fprintf(stdout, "\n\n");
- fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)",
- test_count-1, opt_count);
- fprintf(stdout, "\n Total execution time: %g SECS", total_time);
- if (opt_count > 1)
- fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
-
- fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
- }
+ if (opt_silent < 3)
+ {
+ fprintf(stdout, "\n\n");
+ fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)",
+ test_count-1, opt_count);
+ fprintf(stdout, "\n Total execution time: %g SECS", total_time);
+ if (opt_count > 1)
+ fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
+
+ fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
+ }
}
/***************************************************************************
-main routine
+ main routine
***************************************************************************/
int main(int argc, char **argv)
{
- struct my_tests_st *fptr;
- my_testlist= get_my_tests();
-
- MY_INIT(argv[0]);
-
- if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
- exit(1);
-
- defaults_argv= argv;
- get_options(&argc, &argv);
-
- if (mysql_server_init(embedded_server_arg_count,
- embedded_server_args,
- (char**) embedded_server_groups))
- DIE("Can't initialize MySQL server");
-
- /* connect to server with no flags, default protocol, auto reconnect true */
- mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
-
- total_time= 0;
- for (iter_count= 1; iter_count <= opt_count; iter_count++)
- {
- /* Start of tests */
- test_count= 1;
- start_time= time((time_t *)0);
- if (!argc)
- {
- for (fptr= my_testlist; fptr->name; fptr++)
- (*fptr->function)();
- }
- else
- {
- for ( ; *argv ; argv++)
- {
- for (fptr= my_testlist; fptr->name; fptr++)
- {
- if (!strcmp(fptr->name, *argv))
- {
- (*fptr->function)();
- break;
- }
- }
- if (!fptr->name)
- {
- fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv);
- fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n",
- my_progname);
- client_disconnect(mysql);
- free_defaults(defaults_argv);
- exit(1);
- }
- }
- }
-
- end_time= time((time_t *)0);
- total_time+= difftime(end_time, start_time);
-
- /* End of tests */
- }
-
- client_disconnect(mysql); /* disconnect from server */
-
- free_defaults(defaults_argv);
- print_test_output();
-
- while (embedded_server_arg_count > 1)
- my_free(embedded_server_args[--embedded_server_arg_count]);
-
- mysql_server_end();
-
- my_end(0);
-
- exit(0);
+ struct my_tests_st *fptr;
+ my_testlist= get_my_tests();
+
+ MY_INIT(argv[0]);
+
+ if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
+ exit(1);
+
+ defaults_argv= argv;
+ get_options(&argc, &argv);
+
+ if (mysql_server_init(embedded_server_arg_count,
+ embedded_server_args,
+ (char**) embedded_server_groups))
+ DIE("Can't initialize MySQL server");
+
+ /* connect to server with no flags, default protocol, auto reconnect true */
+ mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
+
+ total_time= 0;
+ for (iter_count= 1; iter_count <= opt_count; iter_count++)
+ {
+ /* Start of tests */
+ test_count= 1;
+ start_time= time((time_t *)0);
+ if (!argc)
+ {
+ for (fptr= my_testlist; fptr->name; fptr++)
+ (*fptr->function)();
+ }
+ else
+ {
+ for ( ; *argv ; argv++)
+ {
+ for (fptr= my_testlist; fptr->name; fptr++)
+ {
+ if (!strcmp(fptr->name, *argv))
+ {
+ (*fptr->function)();
+ break;
+ }
+ }
+ if (!fptr->name)
+ {
+ fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv);
+ fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n",
+ my_progname);
+ client_disconnect(mysql);
+ free_defaults(defaults_argv);
+ exit(1);
+ }
+ }
+ }
+
+ end_time= time((time_t *)0);
+ total_time+= difftime(end_time, start_time);
+
+ /* End of tests */
+ }
+
+ client_disconnect(mysql); /* disconnect from server */
+
+ free_defaults(defaults_argv);
+ print_test_output();
+
+ while (embedded_server_arg_count > 1)
+ my_free(embedded_server_args[--embedded_server_arg_count]);
+
+ mysql_server_end();
+
+ my_end(0);
+
+ exit(0);
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index e600d82ae0f..446018e6906 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2012, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -356,6 +357,7 @@ static void test_prepare_insert_update()
myquery(rc);
}
+
/* Test simple prepares of all DML statements */
static void test_prepare_simple()
@@ -1062,6 +1064,7 @@ static void test_wl4435_3()
puts("");
+ /*
// The following types are not supported:
// - ENUM
// - SET
@@ -1078,6 +1081,7 @@ static void test_wl4435_3()
// - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
// - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
// (use MYSQL_TYPE_BLOB instead);
+ */
WL4435_TEST("TINYINT", "127",
MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
@@ -2180,6 +2184,34 @@ static uint query_cache_hits(MYSQL *conn)
/*
+ Check that query cache is available in server.
+*/
+static my_bool is_query_cache_available()
+{
+ int rc;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ int res= -1;
+
+ rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'have_query_cache'");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ DIE_UNLESS(result);
+
+ row= mysql_fetch_row(result);
+ DIE_UNLESS(row != NULL);
+ if (strcmp(row[1], "YES") == 0)
+ res= 1;
+ else if (strcmp(row[1], "NO") == 0)
+ res= 0;
+ mysql_free_result(result);
+
+ DIE_UNLESS(res == 0 || res == 1);
+ return res;
+}
+
+/*
Test that prepared statements make use of the query cache just as normal
statements (BUG#735).
*/
@@ -2223,6 +2255,12 @@ static void test_ps_query_cache()
myheader("test_ps_query_cache");
+ if (! is_query_cache_available())
+ {
+ fprintf(stdout, "Skipping test_ps_query_cache: Query cache not available.\n");
+ return;
+ }
+
rc= mysql_query(mysql, "SET SQL_MODE=''");
myquery(rc);
@@ -2273,6 +2311,7 @@ static void test_ps_query_cache()
if (!opt_silent)
fprintf(stdout, "OK");
+ break;
}
strmov(query, "select id1, value1 from t1 where id1= ? or "
@@ -6167,7 +6206,7 @@ static void test_date_dt()
static void test_pure_coverage()
{
MYSQL_STMT *stmt;
- MYSQL_BIND my_bind[1];
+ MYSQL_BIND my_bind[2];
int rc;
ulong length;
@@ -7370,8 +7409,9 @@ static void test_explain_bug()
"", "", NAME_CHAR_LEN*MAX_KEY, 0);
}
+ /* The length of this may verify between MariaDB versions (1024 / 2048) */
verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
- "", "", "", NAME_CHAR_LEN*16, 0);
+ "", "", "", NAME_CHAR_LEN * HA_MAX_KEY_SEG, 0);
verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_LONGLONG,
"", "", "", 10, 0);
@@ -8593,7 +8633,7 @@ static void test_ts()
char name;
char query[MAX_TEST_QUERY_LENGTH];
const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
- "SELECT a, b, c FROM test_ts WHERE %c=?",
+ "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)",
"SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
myheader("test_ts");
@@ -8842,7 +8882,7 @@ static void test_parse_error_and_bad_length()
DIE_UNLESS(rc);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
- rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
+ rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
DIE_UNLESS(rc);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
@@ -8853,7 +8893,7 @@ static void test_parse_error_and_bad_length()
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
stmt= mysql_stmt_init(mysql);
DIE_UNLESS(stmt);
- rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
+ rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
DIE_UNLESS(rc != 0);
if (!opt_silent)
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
@@ -12012,7 +12052,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- my_process_warnings(mysql, 12);
+ my_process_warnings(mysql, 6);
verify_col_data("t1", "year", "0000-00-00 00:00:00");
verify_col_data("t1", "month", "0000-00-00 00:00:00");
@@ -12043,7 +12083,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- my_process_warnings(mysql, 6);
+ my_process_warnings(mysql, 3);
verify_col_data("t1", "year", "0000-00-00 00:00:00");
verify_col_data("t1", "month", "0000-00-00 00:00:00");
@@ -12169,7 +12209,7 @@ static void test_conversion()
const char *stmt_text;
int rc;
MYSQL_BIND my_bind[1];
- char buff[4];
+ uchar buff[4];
ulong length;
myheader("test_conversion");
@@ -12192,7 +12232,7 @@ static void test_conversion()
check_execute(stmt, rc);
bzero((char*) my_bind, sizeof(my_bind));
- my_bind[0].buffer= buff;
+ my_bind[0].buffer= (char*) buff;
my_bind[0].length= &length;
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
@@ -12217,7 +12257,7 @@ static void test_conversion()
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == 0);
DIE_UNLESS(length == 1);
- DIE_UNLESS((uchar) buff[0] == 0xE0);
+ DIE_UNLESS(buff[0] == 0xE0);
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc == MYSQL_NO_DATA);
@@ -12988,6 +13028,49 @@ static void test_bug8880()
mysql_stmt_close(*stmt);
}
+/*
+ Test executing a query with prepared statements while query cache is active
+*/
+
+static void test_open_cursor_prepared_statement_query_cache()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+ MYSQL_RES *result;
+
+ myheader("test_open_cursor_prepared_statement_query_cache");
+ if (! is_query_cache_available())
+ {
+ fprintf(stdout, "Skipping test_open_cursor_prepared_statement_query_cache: Query cache not available.\n");
+ return;
+ }
+
+ rc= mysql_query(mysql, "set global query_cache_size=1000000");
+ myquery(rc);
+
+ mysql_query(mysql, "drop table if exists t1");
+ mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
+ rc= mysql_query(mysql, "insert into t1 values (1,1)");
+ myquery(rc); /* one check is enough */
+
+ /* Store query in query cache */
+ rc= mysql_query(mysql, "SELECT * FROM t1");
+ myquery(rc);
+ result= mysql_store_result(mysql);
+ mytest(result);
+ (void) my_process_result_set(result);
+ mysql_free_result(result);
+
+ /* Test using a cursor */
+ stmt= open_cursor("select a from t1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "set global query_cache_size=1000000");
+ myquery(rc);
+}
+
static void test_bug9159()
{
@@ -15466,11 +15549,10 @@ static void test_bug21206()
static void test_status()
{
- const char *status;
DBUG_ENTER("test_status");
myheader("test_status");
- if (!(status= mysql_stat(mysql)))
+ if (!mysql_stat(mysql))
{
myerror("mysql_stat failed"); /* purecov: inspected */
die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
@@ -15887,6 +15969,7 @@ static void test_bug27876()
rc= mysql_query(mysql, "set names default");
myquery(rc);
+
DBUG_VOID_RETURN;
}
@@ -15959,6 +16042,7 @@ static void test_change_user()
const char *pw= "password";
const char *db= "mysqltest_user_test_database";
int rc;
+ MYSQL* conn;
DBUG_ENTER("test_change_user");
myheader("test_change_user");
@@ -16002,149 +16086,173 @@ static void test_change_user()
rc= mysql_query(mysql, buff);
myquery(rc);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
/* Try some combinations */
- rc= mysql_change_user(mysql, NULL, NULL, NULL);
+ rc= mysql_change_user(conn, NULL, NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, "", NULL, NULL);
+ rc= mysql_change_user(conn, "", NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, "", "", NULL);
+ rc= mysql_change_user(conn, "", "", NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, "", "", "");
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+
+ rc= mysql_change_user(conn, "", "", "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, NULL, "", "");
+ rc= mysql_change_user(conn, NULL, "", "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, NULL, NULL, "");
+ rc= mysql_change_user(conn, NULL, NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
+
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
- rc= mysql_change_user(mysql, "", NULL, "");
+ rc= mysql_change_user(conn, "", NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, NULL, "");
+ rc= mysql_change_user(conn, user_pw, NULL, "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, "", "");
+ rc= mysql_change_user(conn, user_pw, "", "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
+
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
- rc= mysql_change_user(mysql, user_pw, "", NULL);
+ rc= mysql_change_user(conn, user_pw, "", NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, NULL, NULL);
+ rc= mysql_change_user(conn, user_pw, NULL, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, "", db);
+ rc= mysql_change_user(conn, user_pw, "", db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, NULL, db);
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+
+ rc= mysql_change_user(conn, user_pw, NULL, db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_pw, pw, db);
+ rc= mysql_change_user(conn, user_pw, pw, db);
myquery(rc);
- rc= mysql_change_user(mysql, user_pw, pw, NULL);
+ rc= mysql_change_user(conn, user_pw, pw, NULL);
myquery(rc);
- rc= mysql_change_user(mysql, user_pw, pw, "");
+ rc= mysql_change_user(conn, user_pw, pw, "");
myquery(rc);
- rc= mysql_change_user(mysql, user_no_pw, pw, db);
+ rc= mysql_change_user(conn, user_no_pw, pw, db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_no_pw, pw, "");
+ rc= mysql_change_user(conn, user_no_pw, pw, "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
+
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
- rc= mysql_change_user(mysql, user_no_pw, pw, NULL);
+ rc= mysql_change_user(conn, user_no_pw, pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, user_no_pw, "", NULL);
+ rc= mysql_change_user(conn, user_no_pw, "", NULL);
myquery(rc);
- rc= mysql_change_user(mysql, user_no_pw, "", "");
+ rc= mysql_change_user(conn, user_no_pw, "", "");
myquery(rc);
- rc= mysql_change_user(mysql, user_no_pw, "", db);
+ rc= mysql_change_user(conn, user_no_pw, "", db);
myquery(rc);
- rc= mysql_change_user(mysql, user_no_pw, NULL, db);
+ rc= mysql_change_user(conn, user_no_pw, NULL, db);
myquery(rc);
- rc= mysql_change_user(mysql, "", pw, db);
+ rc= mysql_change_user(conn, "", pw, db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, "", pw, "");
+ rc= mysql_change_user(conn, "", pw, "");
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
+
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
- rc= mysql_change_user(mysql, "", pw, NULL);
+ rc= mysql_change_user(conn, "", pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, NULL, pw, NULL);
+ rc= mysql_change_user(conn, NULL, pw, NULL);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, NULL, NULL, db);
+ rc= mysql_change_user(conn, NULL, NULL, db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, NULL, "", db);
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+
+ rc= mysql_change_user(conn, NULL, "", db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
- rc= mysql_change_user(mysql, "", "", db);
+ rc= mysql_change_user(conn, "", "", db);
DIE_UNLESS(rc);
if (! opt_silent)
- printf("Got error (as expected): %s\n", mysql_error(mysql));
+ printf("Got error (as expected): %s\n", mysql_error(conn));
/* Cleanup the environment */
- mysql_change_user(mysql, opt_user, opt_password, current_db);
+ mysql_change_user(conn, opt_user, opt_password, current_db);
+
+ mysql_close(conn);
sprintf(buff, "drop database %s", db);
rc= mysql_query(mysql, buff);
@@ -16797,95 +16905,108 @@ static void test_bug31418()
*/
#define LARGE_BUFFER_SIZE 2048
+#define OLD_USERNAME_CHAR_LENGTH 16
static void test_bug31669()
{
int rc;
static char buff[LARGE_BUFFER_SIZE+1];
#ifndef EMBEDDED_LIBRARY
- static char user[USERNAME_CHAR_LENGTH+1];
+ static char user[OLD_USERNAME_CHAR_LENGTH+1];
static char db[NAME_CHAR_LEN+1];
static char query[LARGE_BUFFER_SIZE*2];
#endif
+ MYSQL* conn;
DBUG_ENTER("test_bug31669");
myheader("test_bug31669");
- rc= mysql_change_user(mysql, NULL, NULL, NULL);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+
+ rc= mysql_change_user(conn, NULL, NULL, NULL);
DIE_UNLESS(rc);
- rc= mysql_change_user(mysql, "", "", "");
+ rc= mysql_change_user(conn, "", "", "");
DIE_UNLESS(rc);
- memset(buff, 'a', sizeof(buff));
+ memset(buff, 'a', sizeof(buff) - 1);
+ buff[sizeof(buff) - 1]= 0;
+
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
- rc= mysql_change_user(mysql, buff, buff, buff);
+ rc= mysql_change_user(conn, buff, buff, buff);
DIE_UNLESS(rc);
- rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
+ rc = mysql_change_user(conn, opt_user, opt_password, current_db);
DIE_UNLESS(!rc);
#ifndef EMBEDDED_LIBRARY
memset(db, 'a', sizeof(db));
db[NAME_CHAR_LEN]= 0;
strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
- rc= mysql_query(mysql, query);
+ rc= mysql_query(conn, query);
myquery(rc);
memset(user, 'b', sizeof(user));
- user[USERNAME_CHAR_LENGTH]= 0;
+ user[OLD_USERNAME_CHAR_LENGTH]= 0;
memset(buff, 'c', sizeof(buff));
buff[LARGE_BUFFER_SIZE]= 0;
strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
"'", buff, "' WITH GRANT OPTION", NullS);
- rc= mysql_query(mysql, query);
+ rc= mysql_query(conn, query);
myquery(rc);
strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
"'", buff, "' WITH GRANT OPTION", NullS);
- rc= mysql_query(mysql, query);
+ rc= mysql_query(conn, query);
myquery(rc);
- rc= mysql_query(mysql, "FLUSH PRIVILEGES");
+ rc= mysql_query(conn, "FLUSH PRIVILEGES");
myquery(rc);
- rc= mysql_change_user(mysql, user, buff, db);
+ rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(!rc);
- user[USERNAME_CHAR_LENGTH-1]= 'a';
- rc= mysql_change_user(mysql, user, buff, db);
+ user[OLD_USERNAME_CHAR_LENGTH-1]= 'a';
+ rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(rc);
- user[USERNAME_CHAR_LENGTH-1]= 'b';
+ user[OLD_USERNAME_CHAR_LENGTH-1]= 'b';
buff[LARGE_BUFFER_SIZE-1]= 'd';
- rc= mysql_change_user(mysql, user, buff, db);
+ rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(rc);
buff[LARGE_BUFFER_SIZE-1]= 'c';
db[NAME_CHAR_LEN-1]= 'e';
- rc= mysql_change_user(mysql, user, buff, db);
+ rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(rc);
+ mysql_close(conn);
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+
db[NAME_CHAR_LEN-1]= 'a';
- rc= mysql_change_user(mysql, user, buff, db);
+ rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(!rc);
- rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1);
+ rc= mysql_change_user(conn, user + 1, buff + 1, db + 1);
DIE_UNLESS(rc);
- rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
+ rc = mysql_change_user(conn, opt_user, opt_password, current_db);
DIE_UNLESS(!rc);
strxmov(query, "DROP DATABASE ", db, NullS);
- rc= mysql_query(mysql, query);
+ rc= mysql_query(conn, query);
myquery(rc);
strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
- rc= mysql_query(mysql, query);
+ rc= mysql_query(conn, query);
myquery(rc);
- DIE_UNLESS(mysql_affected_rows(mysql) == 2);
+ DIE_UNLESS(mysql_affected_rows(conn) == 2);
#endif
+ mysql_close(conn);
+
DBUG_VOID_RETURN;
}
@@ -17621,7 +17742,11 @@ static void test_bug43560(void)
fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
DBUG_VOID_RETURN;
}
-
+ if (opt_unix_socket)
+ {
+ fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n");
+ DBUG_VOID_RETURN;
+ }
/*
Set up a separate connection for this test to avoid messing up the
general MYSQL object used in other subtests. Use TCP protocol to avoid
@@ -17690,8 +17815,6 @@ static void test_bug43560(void)
Bug#36326: nested transaction and select
*/
-#ifdef HAVE_QUERY_CACHE
-
static void test_bug36326()
{
int rc;
@@ -17699,6 +17822,12 @@ static void test_bug36326()
DBUG_ENTER("test_bug36326");
myheader("test_bug36326");
+ if (! is_query_cache_available())
+ {
+ fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n");
+ DBUG_VOID_RETURN;
+ }
+
rc= mysql_autocommit(mysql, TRUE);
myquery(rc);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
@@ -17738,8 +17867,6 @@ static void test_bug36326()
DBUG_VOID_RETURN;
}
-#endif
-
/**
Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
string value.
@@ -18186,7 +18313,7 @@ static void test_bug47485()
static void test_bug58036()
{
MYSQL *conn;
- DBUG_ENTER("test_bug47485");
+ DBUG_ENTER("test_bug58036");
myheader("test_bug58036");
/* Part1: try to connect with ucs2 client character set */
@@ -18205,7 +18332,8 @@ static void test_bug58036()
if (!opt_silent)
printf("Got mysql_real_connect() error (expected): %s (%d)\n",
mysql_error(conn), mysql_errno(conn));
- DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
+ DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR ||
+ mysql_errno(conn)== CR_CANT_READ_CHARSET);
mysql_close(conn);
@@ -18405,6 +18533,87 @@ static void test_bug56976()
DBUG_VOID_RETURN;
}
+/*
+ Test that CLIENT_PROGRESS works.
+*/
+
+uint progress_stage, progress_max_stage, progress_count;
+
+static void report_progress(const MYSQL *mysql __attribute__((unused)),
+ uint stage, uint max_stage,
+ double progress __attribute__((unused)),
+ const char *proc_info __attribute__((unused)),
+ uint proc_info_length __attribute__((unused)))
+{
+ progress_stage= stage;
+ progress_max_stage= max_stage;
+ progress_count++;
+}
+
+
+static void test_progress_reporting()
+{
+ int rc, i;
+ MYSQL* conn;
+
+ /* Progress reporting doesn't work yet with embedded server */
+ if (embedded_server_arg_count)
+ return;
+
+ myheader("test_progress_reporting");
+
+ conn= client_connect(CLIENT_PROGRESS, MYSQL_PROTOCOL_TCP, 0);
+ DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS);
+
+ mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
+ rc= mysql_query(conn, "set @save=@@global.progress_report_time");
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=1");
+ myquery(rc);
+
+ rc= mysql_query(conn, "drop table if exists t1,t2");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t2 like t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) values (repeat('a',100)),(repeat('b',200)),(repeat('c',202)),(repeat('d',202)),(repeat('e',202)),(repeat('f',202)),(repeat('g',23))");
+ myquery(rc);
+ for (i= 0 ; i < 5 ; i++)
+ {
+ rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
+ myquery(rc);
+ }
+ rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, add key (f2), order by f2");
+ myquery(rc);
+ if (!opt_silent)
+ printf("Got progress_count: %u stage: %u max_stage: %u\n",
+ progress_count, progress_stage, progress_max_stage);
+ DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=@save");
+ myquery(rc);
+ mysql_close(conn);
+}
+
+/**
+ MDEV-3885 - connection suicide via mysql_kill() causes assertion in server
+*/
+
+static void test_mdev3885()
+{
+ int rc;
+ MYSQL *conn;
+
+ myheader("test_mdev3885");
+ conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
+ rc= mysql_kill(conn, mysql_thread_id(conn));
+ DIE_UNLESS(rc);
+ mysql_close(conn);
+}
+
/**
Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
@@ -18568,6 +18777,76 @@ static void test_bug11754979()
DBUG_VOID_RETURN;
}
+static void test_ps_sp_out_params()
+{
+ MYSQL *my;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[1];
+ char buffer[20];
+ int status, rc;
+
+ myheader("test_ps_sp_out_params");
+ my= mysql_client_init(NULL);
+
+ if (!mysql_real_connect(my, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket, CLIENT_MULTI_RESULTS))
+ DIE("mysql_real_connect failed");
+
+ rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(my,
+ "CREATE PROCEDURE p1(OUT out_param VARCHAR(19)) "
+ "BEGIN"
+ " SELECT 'foo' FROM DUAL;"
+ " SET out_param='foo';"
+ " SELECT 'foo' FROM DUAL;"
+ "END");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(my);
+
+ rc= mysql_stmt_prepare(stmt, "CALL P1(?)", 10);
+ DIE_UNLESS(rc==0);
+
+ DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
+
+ memset(bind, 0, sizeof(MYSQL_BIND));
+ bind[0].buffer= buffer;
+ bind[0].buffer_length= sizeof(buffer);
+ bind[0].buffer_type= MYSQL_TYPE_STRING;
+
+ mysql_stmt_bind_param(stmt, bind);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ do {
+ if (mysql_stmt_field_count(stmt))
+ {
+ /* since server sends a status packet at the end,
+ there must follow at least one additional packet */
+ DIE_UNLESS(mysql_more_results(stmt->mysql));
+
+ mysql_stmt_bind_result(stmt, bind);
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc== 0);
+
+ DIE_UNLESS(strcmp(buffer, "foo") == 0);
+ }
+ status= mysql_stmt_next_result(stmt);
+ } while (status == 0);
+
+ rc= mysql_stmt_reset(stmt);
+ DIE_UNLESS(rc== 0);
+
+ mysql_stmt_close(stmt);
+ mysql_close(my);
+
+ printf("end\n");
+}
/*
Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
@@ -18648,6 +18927,109 @@ static void test_bug13001491()
myquery(rc);
}
+static void test_mdev4326()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind;
+ char query[]= "SELECT * FROM mysql.user LIMIT ?";
+ char str_data[]= "1";
+ unsigned long length= 0;
+ int int_data= 1;
+ int rc, count;
+ my_bool is_null= 0;
+ my_bool error= 0;
+ myheader("test_mdev4326");
+
+ rc= mysql_change_user(mysql, opt_user, opt_password, "mysql");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "SET GLOBAL general_log = 1");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ /* Numeric parameter test */
+
+ rc= mysql_stmt_prepare(stmt, query, strlen(query));
+ check_execute(stmt, rc);
+ check_stmt(stmt);
+ verify_param_count(stmt, 1);
+
+ memset((char *)&bind, 0, sizeof(bind));
+ bind.buffer_type= MYSQL_TYPE_LONG;
+ bind.buffer= (char *)&int_data;
+ bind.is_null= &is_null;
+ bind.length= &length;
+ bind.error= &error;
+
+ rc= mysql_stmt_bind_param(stmt, &bind);
+ check_execute(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 1);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 1);
+ int_data= 0;
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 0);
+ rc= mysql_stmt_close(stmt);
+ check_execute(stmt, rc);
+
+ /* String parameter test */
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(stmt, query, strlen(query));
+ check_execute(stmt, rc);
+ check_stmt(stmt);
+ verify_param_count(stmt, 1);
+
+ memset((char *)&bind, 0, sizeof(bind));
+ bind.buffer_type= MYSQL_TYPE_STRING;
+ bind.buffer= (char *)str_data;
+ length= bind.buffer_length= sizeof(str_data);
+ bind.is_null= &is_null;
+ bind.length= &length;
+ bind.error= &error;
+
+ rc= mysql_stmt_bind_param(stmt, &bind);
+ check_execute(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 1);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 1);
+ str_data[0]= '0';
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ count= 0;
+ while (!(rc= mysql_stmt_fetch(stmt)))
+ count++;
+ DIE_UNLESS(count == 0);
+ rc= mysql_stmt_close(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
+ myquery(rc);
+}
static struct my_tests_st my_tests[]= {
{ "disable_query_logs", disable_query_logs },
@@ -18816,6 +19198,8 @@ static struct my_tests_st my_tests[]= {
{ "test_bug8378", test_bug8378 },
{ "test_bug8722", test_bug8722 },
{ "test_bug8880", test_bug8880 },
+ { "test_open_cursor_prepared_statement_query_cache",
+ test_open_cursor_prepared_statement_query_cache },
{ "test_bug9159", test_bug9159 },
{ "test_bug9520", test_bug9520 },
{ "test_bug9478", test_bug9478 },
@@ -18895,9 +19279,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug33831", test_bug33831 },
{ "test_bug40365", test_bug40365 },
{ "test_bug43560", test_bug43560 },
-#ifdef HAVE_QUERY_CACHE
{ "test_bug36326", test_bug36326 },
-#endif
{ "test_bug41078", test_bug41078 },
{ "test_bug44495", test_bug44495 },
{ "test_bug49972", test_bug49972 },
@@ -18907,10 +19289,14 @@ static struct my_tests_st my_tests[]= {
{ "test_bug58036", test_bug58036 },
{ "test_bug57058", test_bug57058 },
{ "test_bug56976", test_bug56976 },
+ { "test_mdev3885", test_mdev3885 },
{ "test_bug11766854", test_bug11766854 },
{ "test_bug12337762", test_bug12337762 },
+ { "test_progress_reporting", test_progress_reporting },
{ "test_bug11754979", test_bug11754979 },
{ "test_bug13001491", test_bug13001491 },
+ { "test_mdev4326", test_mdev4326 },
+ { "test_ps_sp_out_params", test_ps_sp_out_params },
{ 0, 0 }
};
diff --git a/tests/nonblock-wrappers.h b/tests/nonblock-wrappers.h
new file mode 100644
index 00000000000..3ed470b3400
--- /dev/null
+++ b/tests/nonblock-wrappers.h
@@ -0,0 +1,516 @@
+/*
+ Copyright 2011 Kristian Nielsen and Monty Program Ab
+
+ This file is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ Wrappers that re-implement the normal blocking libmysql API calls in terms
+ of the non-blocking API calls and explicit waiting.
+
+ Used to test the non-blocking calls using mysql_client_test.
+*/
+
+#ifndef __WIN__
+#include <poll.h>
+#else
+#include <WinSock2.h>
+#endif
+
+/*
+ Run the appropriate poll() syscall to wait for the event that libmysql
+ requested. Return which event(s) occured.
+*/
+static int
+wait_for_mysql(MYSQL *mysql, int status)
+{
+#ifdef __WIN__
+ fd_set rs, ws, es;
+ int res;
+ struct timeval tv, *timeout;
+ my_socket s= mysql_get_socket(mysql);
+ FD_ZERO(&rs);
+ FD_ZERO(&ws);
+ FD_ZERO(&es);
+ if (status & MYSQL_WAIT_READ)
+ FD_SET(s, &rs);
+ if (status & MYSQL_WAIT_WRITE)
+ FD_SET(s, &ws);
+ if (status & MYSQL_WAIT_EXCEPT)
+ FD_SET(s, &es);
+ if (status & MYSQL_WAIT_TIMEOUT)
+ {
+ tv.tv_sec= mysql_get_timeout_value(mysql);
+ tv.tv_usec= 0;
+ timeout= &tv;
+ }
+ else
+ timeout= NULL;
+ res= select(1, &rs, &ws, &es, timeout);
+ if (res == 0)
+ return MYSQL_WAIT_TIMEOUT;
+ else if (res == SOCKET_ERROR)
+ return MYSQL_WAIT_TIMEOUT;
+ else
+ {
+ int status= 0;
+ if (FD_ISSET(s, &rs))
+ status|= MYSQL_WAIT_READ;
+ if (FD_ISSET(s, &ws))
+ status|= MYSQL_WAIT_WRITE;
+ if (FD_ISSET(s, &es))
+ status|= MYSQL_WAIT_EXCEPT;
+ return status;
+ }
+#else
+ struct pollfd pfd;
+ int timeout;
+ int res;
+
+ pfd.fd= mysql_get_socket(mysql);
+ pfd.events=
+ (status & MYSQL_WAIT_READ ? POLLIN : 0) |
+ (status & MYSQL_WAIT_WRITE ? POLLOUT : 0) |
+ (status & MYSQL_WAIT_EXCEPT ? POLLPRI : 0);
+ if (status & MYSQL_WAIT_TIMEOUT)
+ timeout= 1000*mysql_get_timeout_value(mysql);
+ else
+ timeout= -1;
+ do {
+ res= poll(&pfd, 1, timeout);
+ /*
+ In a real event framework, we should re-compute the timeout on getting
+ EINTR to account for the time elapsed before the interruption.
+ */
+ } while (res < 0 && errno == EINTR);
+ if (res == 0)
+ return MYSQL_WAIT_TIMEOUT;
+ else if (res < 0)
+ return MYSQL_WAIT_TIMEOUT;
+ else
+ {
+ int status= 0;
+ if (pfd.revents & POLLIN)
+ status|= MYSQL_WAIT_READ;
+ if (pfd.revents & POLLOUT)
+ status|= MYSQL_WAIT_WRITE;
+ if (pfd.revents & POLLPRI)
+ status|= MYSQL_WAIT_EXCEPT;
+ return status;
+ }
+#endif
+}
+
+
+/*
+ If WRAP_NONBLOCK_ENABLED is defined, it is a variable that can be used to
+ enable or disable the use of non-blocking API wrappers. If true the
+ non-blocking API will be used, if false the normal blocking API will be
+ called directly.
+*/
+#ifdef WRAP_NONBLOCK_ENABLED
+#define USE_BLOCKING(name__, invoke_blocking__) \
+ if (!(WRAP_NONBLOCK_ENABLED)) return name__ invoke_blocking__;
+#define USE_BLOCKING_VOID_RETURN(name__, invoke__) \
+ if (!(WRAP_NONBLOCK_ENABLED)) { name__ invoke__; return; }
+#else
+#define USE_BLOCKING(name__, invoke_blocking__)
+#define USE_BLOCKING_VOID_RETURN(name__, invoke__)
+#endif
+
+/*
+ I would preferably have declared the wrappers static.
+ However, if we do so, compilers will warn about definitions not used, and
+ with -Werror this breaks compilation :-(
+*/
+#define MK_WRAPPER(ret_type__, name__, decl__, invoke__, invoke_blocking__, cont_arg__, mysql__) \
+ret_type__ wrap_ ## name__ decl__ \
+{ \
+ ret_type__ res; \
+ int status; \
+ USE_BLOCKING(name__, invoke_blocking__) \
+ status= name__ ## _start invoke__; \
+ while (status) \
+ { \
+ status= wait_for_mysql(mysql__, status); \
+ status= name__ ## _cont(&res, cont_arg__, status); \
+ } \
+ return res; \
+}
+
+#define MK_WRAPPER_VOID_RETURN(name__, decl__, invoke__, cont_arg__, mysql__) \
+void wrap_ ## name__ decl__ \
+{ \
+ int status; \
+ USE_BLOCKING_VOID_RETURN(name__, invoke__) \
+ status= name__ ## _start invoke__; \
+ while (status) \
+ { \
+ status= wait_for_mysql(mysql__, status); \
+ status= name__ ## _cont(cont_arg__, status); \
+ } \
+}
+
+MK_WRAPPER(
+ MYSQL *,
+ mysql_real_connect,
+ (MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag),
+ (&res, mysql, host, user, passwd, db, port, unix_socket, clientflag),
+ (mysql, host, user, passwd, db, port, unix_socket, clientflag),
+ mysql,
+ mysql)
+
+
+MK_WRAPPER(
+ int,
+ mysql_real_query,
+ (MYSQL *mysql, const char *stmt_str, unsigned long length),
+ (&res, mysql, stmt_str, length),
+ (mysql, stmt_str, length),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_ROW,
+ mysql_fetch_row,
+ (MYSQL_RES *result),
+ (&res, result),
+ (result),
+ result,
+ result->handle)
+
+MK_WRAPPER(
+ int,
+ mysql_set_character_set,
+ (MYSQL *mysql, const char *csname),
+ (&res, mysql, csname),
+ (mysql, csname),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_select_db,
+ (MYSQL *mysql, const char *db),
+ (&res, mysql, db),
+ (mysql, db),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_send_query,
+ (MYSQL *mysql, const char *q, unsigned long length),
+ (&res, mysql, q, length),
+ (mysql, q, length),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_RES *,
+ mysql_store_result,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER_VOID_RETURN(
+ mysql_free_result,
+ (MYSQL_RES *result),
+ (result),
+ result,
+ result->handle)
+
+MK_WRAPPER_VOID_RETURN(
+ mysql_close,
+ (MYSQL *sock),
+ (sock),
+ sock,
+ sock)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_change_user,
+ (MYSQL *mysql, const char *user, const char *passwd, const char *db),
+ (&res, mysql, user, passwd, db),
+ (mysql, user, passwd, db),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_query,
+ (MYSQL *mysql, const char *q),
+ (&res, mysql, q),
+ (mysql, q),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_shutdown,
+ (MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level),
+ (&res, mysql, shutdown_level),
+ (mysql, shutdown_level),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_dump_debug_info,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_refresh,
+ (MYSQL *mysql, unsigned int refresh_options),
+ (&res, mysql, refresh_options),
+ (mysql, refresh_options),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_kill,
+ (MYSQL *mysql, unsigned long pid),
+ (&res, mysql, pid),
+ (mysql, pid),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_set_server_option,
+ (MYSQL *mysql, enum enum_mysql_set_option option),
+ (&res, mysql, option),
+ (mysql, option),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_ping,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ const char *,
+ mysql_stat,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_RES *,
+ mysql_list_dbs,
+ (MYSQL *mysql, const char *wild),
+ (&res, mysql, wild),
+ (mysql, wild),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_RES *,
+ mysql_list_tables,
+ (MYSQL *mysql, const char *wild),
+ (&res, mysql, wild),
+ (mysql, wild),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_RES *,
+ mysql_list_processes,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ MYSQL_RES *,
+ mysql_list_fields,
+ (MYSQL *mysql, const char *table, const char *wild),
+ (&res, mysql, table, wild),
+ (mysql, table, wild),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_read_query_result,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_stmt_prepare,
+ (MYSQL_STMT *stmt, const char *query, unsigned long length),
+ (&res, stmt, query, length),
+ (stmt, query, length),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_stmt_execute,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_stmt_fetch,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_stmt_store_result,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_stmt_close,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_stmt_reset,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_stmt_free_result,
+ (MYSQL_STMT *stmt),
+ (&res, stmt),
+ (stmt),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_stmt_send_long_data,
+ (MYSQL_STMT *stmt, unsigned int param_number, const char *data, unsigned long length),
+ (&res, stmt, param_number, data, length),
+ (stmt, param_number, data, length),
+ stmt,
+ stmt->mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_commit,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_rollback,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ my_bool,
+ mysql_autocommit,
+ (MYSQL *mysql, my_bool auto_mode),
+ (&res, mysql, auto_mode),
+ (mysql, auto_mode),
+ mysql,
+ mysql)
+
+MK_WRAPPER(
+ int,
+ mysql_next_result,
+ (MYSQL *mysql),
+ (&res, mysql),
+ (mysql),
+ mysql,
+ mysql)
+
+#undef USE_BLOCKING
+#undef MK_WRAPPER
+#undef MK_WRAPPER_VOID_RETURN
+
+
+#define mysql_real_connect wrap_mysql_real_connect
+#define mysql_real_query wrap_mysql_real_query
+#define mysql_fetch_row wrap_mysql_fetch_row
+#define mysql_set_character_set wrap_mysql_set_character_set
+#define mysql_select_db wrap_mysql_select_db
+#define mysql_send_query wrap_mysql_send_query
+#define mysql_store_result wrap_mysql_store_result
+#define mysql_free_result wrap_mysql_free_result
+#define mysql_close wrap_mysql_close
+#define mysql_change_user wrap_mysql_change_user
+#define mysql_query wrap_mysql_query
+#define mysql_shutdown wrap_mysql_shutdown
+#define mysql_dump_debug_info wrap_mysql_dump_debug_info
+#define mysql_refresh wrap_mysql_refresh
+#define mysql_kill wrap_mysql_kill
+#define mysql_set_server_option wrap_mysql_set_server_option
+#define mysql_ping wrap_mysql_ping
+#define mysql_stat wrap_mysql_stat
+#define mysql_list_dbs wrap_mysql_list_dbs
+#define mysql_list_tables wrap_mysql_list_tables
+#define mysql_list_processes wrap_mysql_list_processes
+#define mysql_list_fields wrap_mysql_list_fields
+#define mysql_read_query_result wrap_mysql_read_query_result
+#define mysql_stmt_prepare wrap_mysql_stmt_prepare
+#define mysql_stmt_execute wrap_mysql_stmt_execute
+#define mysql_stmt_fetch wrap_mysql_stmt_fetch
+#define mysql_stmt_store_result wrap_mysql_stmt_store_result
+#define mysql_stmt_close wrap_mysql_stmt_close
+#define mysql_stmt_reset wrap_mysql_stmt_reset
+#define mysql_stmt_free_result wrap_mysql_stmt_free_result
+#define mysql_stmt_send_long_data wrap_mysql_stmt_send_long_data
+#define mysql_commit wrap_mysql_commit
+#define mysql_rollback wrap_mysql_rollback
+#define mysql_autocommit wrap_mysql_autocommit
+#define mysql_next_result wrap_mysql_next_result
diff --git a/tests/thread_test.c b/tests/thread_test.c
index 5d79fb17c08..bf0fb8ea2c0 100644
--- a/tests/thread_test.c
+++ b/tests/thread_test.c
@@ -114,7 +114,8 @@ static struct my_option my_long_options[] =
};
-static const char *load_default_groups[]= { "client",0 };
+static const char *load_default_groups[]=
+{ "client", "client-server", "client-mariadb", 0 };
static void usage()
{