summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.cvsignore2
-rw-r--r--[-rwxr-xr-x]tests/CMakeLists.txt27
-rw-r--r--tests/Makefile.am65
-rw-r--r--tests/async_queries.c435
-rwxr-xr-xtests/big_record.pl17
-rw-r--r--tests/bug25714.c6
-rw-r--r--tests/check_async_queries.pl73
-rwxr-xr-xtests/drop_test.pl16
-rwxr-xr-xtests/export.pl15
-rwxr-xr-xtests/fork2_test.pl15
-rwxr-xr-xtests/fork_big.pl16
-rw-r--r--tests/fork_big2.pl16
-rwxr-xr-xtests/grant.pl1
-rwxr-xr-xtests/index_corrupt.pl16
-rwxr-xr-xtests/insert_and_repair.pl16
-rwxr-xr-xtests/lock_test.pl15
-rw-r--r--tests/myisam-big-rows.tst2
-rw-r--r--tests/mysql_client_fw.c1516
-rw-r--r--tests/mysql_client_test.c1876
-rw-r--r--tests/nonblock-wrappers.h516
-rwxr-xr-xtests/pmail.pl16
-rwxr-xr-xtests/rename_test.pl16
-rwxr-xr-xtests/table_types.pl16
-rwxr-xr-xtests/test_delayed_insert.pl15
-rw-r--r--tests/thread_test.c51
-rwxr-xr-xtests/truncate.pl16
26 files changed, 3661 insertions, 1130 deletions
diff --git a/tests/.cvsignore b/tests/.cvsignore
deleted file mode 100644
index 282522db034..00000000000
--- a/tests/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 967ebae2e22..0acad6bf30b 100755..100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 MySQL AB
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -11,18 +11,27 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-# About "mysqlclient_notls", see note in "client/CMakeLists.txt"
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
ADD_DEFINITIONS("-DMYSQL_CLIENT")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-ADD_EXECUTABLE(mysql_client_test mysql_client_test.c ../mysys/my_memmem.c)
-TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient wsock32)
+ADD_EXECUTABLE(mysql_client_test mysql_client_test.c)
+TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient)
+SET_TARGET_PROPERTIES(mysql_client_test PROPERTIES LINKER_LANGUAGE CXX)
+
+IF(WITH_UNIT_TESTS)
+ ADD_EXECUTABLE(bug25714 bug25714.c)
+ TARGET_LINK_LIBRARIES(bug25714 mysqlclient)
+ SET_TARGET_PROPERTIES(bug25714 PROPERTIES LINKER_LANGUAGE CXX)
+ENDIF()
-ADD_EXECUTABLE(bug25714 bug25714.c)
-TARGET_LINK_LIBRARIES(bug25714 mysqlclient wsock32)
+INSTALL(TARGETS mysql_client_test DESTINATION ${INSTALL_BINDIR} COMPONENT Test)
-INSTALL(TARGETS mysql_client_test DESTINATION bin 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/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index 48ac873fcd0..00000000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; version 2
-# of the License.
-#
-# This program 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
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public
-# License along with this library; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-# MA 02110-1301, USA
-
-## Process this file with automake to create Makefile.in
-
-
-if THREAD_SAFE_CLIENT
-LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql_r/libmysqlclient_r.la
-else
-LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql/libmysqlclient.la
-endif
-
-EXTRA_DIST = auto_increment.res auto_increment.tst \
- function.res function.tst lock_test.pl lock_test.res \
- export.pl big_record.pl \
- fork2_test.pl fork_big.pl \
- insert_and_repair.pl \
- grant.pl grant.res test_delayed_insert.pl \
- pmail.pl mail_to_db.pl table_types.pl \
- myisam-big-rows.tst \
- mysql_client_fw.c \
- CMakeLists.txt
-
-bin_PROGRAMS = mysql_client_test
-noinst_PROGRAMS = insert_test select_test thread_test bug25714
-
-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
- $(openssl_includes)
-LIBS = @CLIENT_LIBS@
-LDADD = @CLIENT_EXTRA_LDFLAGS@ \
- $(LIBMYSQLCLIENT_LA)
-
-mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS)
-mysql_client_test_SOURCES= mysql_client_test.c\
- $(top_srcdir)/mysys/my_memmem.c
-mysql_client_test.o: mysql_client_fw.c
-
-insert_test_SOURCES= insert_test.c
-select_test_SOURCES= select_test.c
-insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
-select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
-
-bug25714_SOURCES= bug25714.c
-bug25714_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
-
-# Fix for mit-threads
-DEFS = -DMYSQL_CLIENT_NO_THREADS
-
-thread_test.o: thread_test.c
- $(COMPILE) -c $(INCLUDES) $<
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/big_record.pl b/tests/big_record.pl
index fbe94e3540f..0d5766e5f5d 100755
--- a/tests/big_record.pl
+++ b/tests/big_record.pl
@@ -1,8 +1,23 @@
#!/usr/bin/perl
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
# This is a test with stores big records in a blob.
# Note that for the default test the mysql server should have been
-# started with at least 'mysqld -O max_allowed_packet=30M' and you should have
+# started with at least 'mysqld --max_allowed_packet=30M' and you should have
# at least 256M memory in your computer.
use DBI;
diff --git a/tests/bug25714.c b/tests/bug25714.c
index ad3b863dd75..40c631d76a5 100644
--- a/tests/bug25714.c
+++ b/tests/bug25714.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2007 MySQL AB, 2009 Sun Microsystems, Inc.
+/* Copyright (c) 2007 MySQL AB, 2009 Sun Microsystems, Inc.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
@@ -13,8 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
#include <my_sys.h>
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/drop_test.pl b/tests/drop_test.pl
index 9dcadf45c2e..272c4029e0f 100755
--- a/tests/drop_test.pl
+++ b/tests/drop_test.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2000 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test with uses processes to insert, select and drop tables.
#
diff --git a/tests/export.pl b/tests/export.pl
index 29f0d1af8ff..d543ede8697 100755
--- a/tests/export.pl
+++ b/tests/export.pl
@@ -1,5 +1,20 @@
#!/usr/bin/perl
+# Copyright (C) 2000, 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
# This is a test with uses two processes to a database.
# The other inserts records in two tables, the other does a lot of joins
# on these.
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index 19fab5a67d6..64e3e060b09 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -1,5 +1,20 @@
#!/usr/bin/perl -w
+# Copyright (C) 2000, 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
# This is a test with uses 5 processes to insert, update and select from
# two tables.
# One inserts records in the tables, one updates some record in it and
diff --git a/tests/fork_big.pl b/tests/fork_big.pl
index 5c4f11b00e2..a674f7f7164 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test with uses many processes to test a MySQL server.
#
diff --git a/tests/fork_big2.pl b/tests/fork_big2.pl
index f22aeaa6713..77b6f305ef5 100644
--- a/tests/fork_big2.pl
+++ b/tests/fork_big2.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2002, 2005 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test with uses many processes to test a MySQL server.
#
diff --git a/tests/grant.pl b/tests/grant.pl
index a2465d19bb1..23a7d2110fb 100755
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -1,4 +1,5 @@
#!/usr/bin/perl
+
# Copyright (c) 2000, 2005 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/tests/index_corrupt.pl b/tests/index_corrupt.pl
index 19bf54f5d11..fa4c8151277 100755
--- a/tests/index_corrupt.pl
+++ b/tests/index_corrupt.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2005 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test for a key cache bug (bug #10167)
# To expose the bug mysqld should be started with --key-buffer-size=64K
diff --git a/tests/insert_and_repair.pl b/tests/insert_and_repair.pl
index 1c7186bb651..00ab20f051b 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2000, 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test of insert and repair/check.
#
diff --git a/tests/lock_test.pl b/tests/lock_test.pl
index 5daeeddad8e..a40bec681f6 100755
--- a/tests/lock_test.pl
+++ b/tests/lock_test.pl
@@ -1,5 +1,20 @@
#!/usr/bin/perl
+# Copyright (C) 2000 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
# This is a test with uses two processes to a database.
# The other inserts records in two tables, the other does a lot of joins
# on these.
diff --git a/tests/myisam-big-rows.tst b/tests/myisam-big-rows.tst
index 56c06f4820f..97147999f87 100644
--- a/tests/myisam-big-rows.tst
+++ b/tests/myisam-big-rows.tst
@@ -1,7 +1,7 @@
#
# Test rows with length above > 16M
# Note that for this to work, you should start mysqld with
-# -O max_allowed_packet=32M
+# --max_allowed_packet=32M
#
drop table if exists t1;
diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c
index 222e5a75055..9ce4737d874 100644
--- a/tests/mysql_client_fw.c
+++ b/tests/mysql_client_fw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
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
@@ -17,11 +17,25 @@
#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 <my_handler.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 */
@@ -47,6 +61,8 @@ static unsigned int test_count= 0;
static unsigned int opt_count= 0;
static unsigned int iter_count= 0;
static my_bool have_innodb= FALSE;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+static unsigned int opt_drop_db= 1;
static const char *opt_basedir= "./";
static const char *opt_vardir= "mysql-test/var";
@@ -57,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;
@@ -70,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) \
@@ -95,33 +111,34 @@ DBUG_PRINT("test", ("name: %s", str)); \
static void print_error(const char *msg);
static void print_st_error(MYSQL_STMT *stmt, const char *msg);
-static void client_disconnect(MYSQL* mysql, my_bool drop_db);
+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);
}
@@ -179,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;
}
@@ -187,57 +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
- 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
@@ -246,120 +270,125 @@ 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 (!(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;
+ 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;
}
/* Close the connection */
-static void client_disconnect(MYSQL* mysql, my_bool drop_db)
+static void client_disconnect(MYSQL* mysql)
{
static char query[MAX_TEST_QUERY_LENGTH];
@@ -367,7 +396,7 @@ static void client_disconnect(MYSQL* mysql, my_bool drop_db)
if (mysql)
{
- if (drop_db)
+ if (opt_drop_db)
{
if (!opt_silent)
fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
@@ -391,21 +420,21 @@ static void client_disconnect(MYSQL* mysql, my_bool drop_db)
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);
}
@@ -413,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);
+ }
}
@@ -461,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;
}
@@ -537,247 +566,270 @@ 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;
- }
+ 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;
+}
- 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));
+/* Prepare statement, execute, and process result set for given query */
- 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];
- }
+int my_stmt_result(const char *buff)
+{
+ MYSQL_STMT *stmt;
+ int row_count;
+ int rc;
- rc= mysql_stmt_bind_result(stmt, buffer);
- check_execute(stmt, rc);
+ if (!opt_silent)
+ fprintf(stdout, "\n\n %s", buff);
+ stmt= mysql_simple_prepare(mysql, buff);
+ check_stmt(stmt);
- 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);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
- 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;
-}
+ row_count= my_process_stmt_result(stmt);
+ mysql_stmt_close(stmt);
+ return row_count;
+}
-/* Prepare statement, execute, and process result set for given query */
+/* Print the total number of warnings and the warnings themselves. */
-int my_stmt_result(const char *buff)
+void my_process_warnings(MYSQL *conn, unsigned expected_warning_count)
{
- MYSQL_STMT *stmt;
- int row_count;
- int rc;
+ MYSQL_RES *result;
+ 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 total warnings: %u (expected: %u)\n",
+ mysql_warning_count(conn), expected_warning_count);
+
+ DIE_UNLESS(mysql_warning_count(mysql) == expected_warning_count);
- rc= mysql_stmt_execute(stmt);
- check_execute(stmt, rc);
+ rc= mysql_query(conn, "SHOW WARNINGS");
+ DIE_UNLESS(rc == 0);
- row_count= my_process_stmt_result(stmt);
- mysql_stmt_close(stmt);
+ result= mysql_store_result(conn);
+ mytest(result);
- return row_count;
+ 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))
- {
- 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);
+ 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);
}
@@ -785,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);
}
@@ -797,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);
}
@@ -809,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);
}
@@ -821,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);
}
@@ -834,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
@@ -1116,7 +1168,7 @@ 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[]=
@@ -1125,256 +1177,272 @@ 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},
-{"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},
-{ 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 */
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, MYF(MY_ALLOW_ZERO_PTR));
- 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 '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]);
-
- load_defaults("my", client_test_load_default_groups, &argc, &argv);
- 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, 1);
- 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, 1); /* 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],MYF(0));
-
- 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 650c8858bb9..7ec91636d26 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -26,6 +26,7 @@
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
*/
+
/*
The fw.c file includes all the mysql_client_test framework; this file
contains only the actual tests, plus the list of test functions to call.
@@ -356,6 +357,7 @@ static void test_prepare_insert_update()
myquery(rc);
}
+
/* Test simple prepares of all DML statements */
static void test_prepare_simple()
@@ -425,6 +427,817 @@ static void test_prepare_simple()
myquery(rc);
}
+/************************************************************************/
+
+#define FILE_PATH_SIZE 4096
+
+char mct_log_file_path[FILE_PATH_SIZE];
+FILE *mct_log_file= NULL;
+
+void mct_start_logging(const char *test_case_name)
+{
+ const char *tmp_dir= getenv("MYSQL_TMP_DIR");
+
+ if (!tmp_dir)
+ {
+ printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n");
+ return;
+ }
+
+ if (mct_log_file)
+ {
+ printf("Warning: can not start logging for test case '%s' "
+ "because log is already open\n",
+ (const char *) test_case_name);
+ return;
+ }
+
+ /*
+ Path is: <tmp_dir>/<test_case_name>.out.log
+ 10 is length of '/' + '.out.log' + \0
+ */
+
+ if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE)
+ {
+ printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n");
+ return;
+ }
+
+ my_snprintf(mct_log_file_path, FILE_PATH_SIZE,
+ "%s/%s.out.log",
+ (const char *) tmp_dir,
+ (const char *) test_case_name);
+
+ mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME));
+
+ if (!mct_log_file)
+ {
+ printf("Warning: can not open log file (%s): %s. Logging is disabled.\n",
+ (const char *) mct_log_file_path,
+ (const char *) strerror(errno));
+ return;
+ }
+}
+
+void mct_log(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+
+ if (mct_log_file)
+ {
+ va_list args;
+ va_start(args, format);
+ vfprintf(mct_log_file, format, args);
+ va_end(args);
+ }
+}
+
+void mct_close_log()
+{
+ if (!mct_log_file)
+ return;
+
+ my_fclose(mct_log_file, MYF(0));
+ mct_log_file= NULL;
+}
+
+#define WL4435_NUM_PARAMS 10
+#define WL4435_STRING_SIZE 30
+
+static void test_wl4435()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+ char query[MAX_TEST_QUERY_LENGTH];
+
+ char str_data[20][WL4435_STRING_SIZE];
+ double dbl_data[20];
+ char dec_data[20][WL4435_STRING_SIZE];
+ int int_data[20];
+ ulong str_length= WL4435_STRING_SIZE;
+ my_bool is_null;
+ MYSQL_BIND ps_params[WL4435_NUM_PARAMS];
+
+ int exec_counter;
+
+ myheader("test_wl4435");
+ mct_start_logging("test_wl4435");
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
+ " a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
+ " b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
+ "(1, '11', 12.34, 56.7), "
+ "(2, '12', 56.78, 90.1), "
+ "(3, '13', 23.45, 67.8)");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
+ "(100, 10, '110', 70.70, 10.1), "
+ "(200, 20, '120', 80.80, 20.2), "
+ "(300, 30, '130', 90.90, 30.3)");
+ myquery(rc);
+
+ rc= mysql_query(mysql,
+ "CREATE PROCEDURE p1("
+ " IN v0 INT, "
+ " OUT v_str_1 CHAR(32), "
+ " OUT v_dbl_1 DOUBLE(4, 2), "
+ " OUT v_dec_1 DECIMAL(6, 3), "
+ " OUT v_int_1 INT, "
+ " IN v1 INT, "
+ " INOUT v_str_2 CHAR(64), "
+ " INOUT v_dbl_2 DOUBLE(5, 3), "
+ " INOUT v_dec_2 DECIMAL(7, 4), "
+ " INOUT v_int_2 INT)"
+ "BEGIN "
+ " SET v0 = -1; "
+ " SET v1 = -1; "
+ " SET v_str_1 = 'test_1'; "
+ " SET v_dbl_1 = 12.34; "
+ " SET v_dec_1 = 567.891; "
+ " SET v_int_1 = 2345; "
+ " SET v_str_2 = 'test_2'; "
+ " SET v_dbl_2 = 67.891; "
+ " SET v_dec_2 = 234.6789; "
+ " SET v_int_2 = 6789; "
+ " SELECT * FROM t1; "
+ " SELECT * FROM t2; "
+ "END");
+ myquery(rc);
+
+ rc= mysql_query(mysql,
+ "CREATE PROCEDURE p2("
+ " IN i1 VARCHAR(255) CHARACTER SET koi8r, "
+ " OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
+ " OUT o2 VARBINARY(255)) "
+ "BEGIN "
+ " SET o1 = i1; "
+ " SET o2 = i1; "
+ "END");
+ myquery(rc);
+
+ strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+ stmt= mysql_simple_prepare(mysql, query);
+ check_stmt(stmt);
+
+ /* Init PS-parameters. */
+
+ bzero((char *) ps_params, sizeof (ps_params));
+
+ /* - v0 -- INT */
+
+ ps_params[0].buffer_type= MYSQL_TYPE_LONG;
+ ps_params[0].buffer= (char *) &int_data[0];
+ ps_params[0].length= 0;
+ ps_params[0].is_null= 0;
+
+ /* - v_str_1 -- CHAR(32) */
+
+ ps_params[1].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[1].buffer= (char *) str_data[0];
+ ps_params[1].buffer_length= WL4435_STRING_SIZE;
+ ps_params[1].length= &str_length;
+ ps_params[1].is_null= 0;
+
+ /* - v_dbl_1 -- DOUBLE */
+
+ ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
+ ps_params[2].buffer= (char *) &dbl_data[0];
+ ps_params[2].length= 0;
+ ps_params[2].is_null= 0;
+
+ /* - v_dec_1 -- DECIMAL */
+
+ ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
+ ps_params[3].buffer= (char *) dec_data[0];
+ ps_params[3].buffer_length= WL4435_STRING_SIZE;
+ ps_params[3].length= 0;
+ ps_params[3].is_null= 0;
+
+ /* - v_int_1 -- INT */
+
+ ps_params[4].buffer_type= MYSQL_TYPE_LONG;
+ ps_params[4].buffer= (char *) &int_data[0];
+ ps_params[4].length= 0;
+ ps_params[4].is_null= 0;
+
+ /* - v1 -- INT */
+
+ ps_params[5].buffer_type= MYSQL_TYPE_LONG;
+ ps_params[5].buffer= (char *) &int_data[0];
+ ps_params[5].length= 0;
+ ps_params[5].is_null= 0;
+
+ /* - v_str_2 -- CHAR(32) */
+
+ ps_params[6].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[6].buffer= (char *) str_data[0];
+ ps_params[6].buffer_length= WL4435_STRING_SIZE;
+ ps_params[6].length= &str_length;
+ ps_params[6].is_null= 0;
+
+ /* - v_dbl_2 -- DOUBLE */
+
+ ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
+ ps_params[7].buffer= (char *) &dbl_data[0];
+ ps_params[7].length= 0;
+ ps_params[7].is_null= 0;
+
+ /* - v_dec_2 -- DECIMAL */
+
+ ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
+ ps_params[8].buffer= (char *) dec_data[0];
+ ps_params[8].buffer_length= WL4435_STRING_SIZE;
+ ps_params[8].length= 0;
+ ps_params[8].is_null= 0;
+
+ /* - v_int_2 -- INT */
+
+ ps_params[9].buffer_type= MYSQL_TYPE_LONG;
+ ps_params[9].buffer= (char *) &int_data[0];
+ ps_params[9].length= 0;
+ ps_params[9].is_null= 0;
+
+ /* Bind parameters. */
+
+ rc= mysql_stmt_bind_param(stmt, ps_params);
+
+ /* Execute! */
+
+ for (exec_counter= 0; exec_counter < 3; ++exec_counter)
+ {
+ int i;
+ int num_fields;
+ MYSQL_BIND *rs_bind;
+
+ mct_log("\nexec_counter: %d\n", (int) exec_counter);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ while (1)
+ {
+ MYSQL_FIELD *fields;
+
+ MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
+
+ num_fields= mysql_stmt_field_count(stmt);
+ fields= mysql_fetch_fields(rs_metadata);
+
+ rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
+ bzero(rs_bind, sizeof (MYSQL_BIND) * num_fields);
+
+ mct_log("num_fields: %d\n", (int) num_fields);
+
+ for (i = 0; i < num_fields; ++i)
+ {
+ mct_log(" - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
+ "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
+ "type: %d; decimals: %d\n",
+ (int) i,
+ (const char *) fields[i].name,
+ (const char *) fields[i].org_name,
+ (const char *) fields[i].table,
+ (const char *) fields[i].org_table,
+ (const char *) fields[i].db,
+ (const char *) fields[i].catalog,
+ (int) fields[i].length,
+ (int) fields[i].max_length,
+ (int) fields[i].type,
+ (int) fields[i].decimals);
+
+ rs_bind[i].buffer_type= fields[i].type;
+ rs_bind[i].is_null= &is_null;
+
+ switch (fields[i].type)
+ {
+ case MYSQL_TYPE_LONG:
+ rs_bind[i].buffer= (char *) &(int_data[i]);
+ rs_bind[i].buffer_length= sizeof (int_data);
+ break;
+
+ case MYSQL_TYPE_STRING:
+ rs_bind[i].buffer= (char *) str_data[i];
+ rs_bind[i].buffer_length= WL4435_STRING_SIZE;
+ rs_bind[i].length= &str_length;
+ break;
+
+ case MYSQL_TYPE_DOUBLE:
+ rs_bind[i].buffer= (char *) &dbl_data[i];
+ rs_bind[i].buffer_length= sizeof (dbl_data);
+ break;
+
+ case MYSQL_TYPE_NEWDECIMAL:
+ rs_bind[i].buffer= (char *) dec_data[i];
+ rs_bind[i].buffer_length= WL4435_STRING_SIZE;
+ rs_bind[i].length= &str_length;
+ break;
+
+ default:
+ fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
+ exit(1);
+ }
+ }
+
+ rc= mysql_stmt_bind_result(stmt, rs_bind);
+ check_execute(stmt, rc);
+
+ mct_log("Data:\n");
+
+ while (1)
+ {
+ int rc= mysql_stmt_fetch(stmt);
+
+ if (rc == 1 || rc == MYSQL_NO_DATA)
+ break;
+
+ mct_log(" ");
+
+ for (i = 0; i < num_fields; ++i)
+ {
+ switch (rs_bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_LONG:
+ mct_log(" int: %ld;",
+ (long) *((int *) rs_bind[i].buffer));
+ break;
+
+ case MYSQL_TYPE_STRING:
+ mct_log(" str: '%s';",
+ (char *) rs_bind[i].buffer);
+ break;
+
+ case MYSQL_TYPE_DOUBLE:
+ mct_log(" dbl: %lf;",
+ (double) *((double *) rs_bind[i].buffer));
+ break;
+
+ case MYSQL_TYPE_NEWDECIMAL:
+ mct_log(" dec: '%s';",
+ (char *) rs_bind[i].buffer);
+ break;
+
+ default:
+ printf(" unexpected type (%d)\n",
+ rs_bind[i].buffer_type);
+ }
+ }
+ mct_log("\n");
+ }
+
+ mct_log("EOF\n");
+
+ rc= mysql_stmt_next_result(stmt);
+ mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
+ (int) rc, (int) mysql->field_count);
+
+ free(rs_bind);
+ mysql_free_result(rs_metadata);
+
+ if (rc > 0)
+ {
+ printf("Error: %s (errno: %d)\n",
+ mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
+ DIE(rc > 0);
+ }
+
+ if (rc)
+ break;
+
+ if (!mysql->field_count)
+ {
+ /* This is the last OK-packet. No more resultsets. */
+ break;
+ }
+ }
+
+ }
+
+ mysql_stmt_close(stmt);
+
+ mct_close_log();
+
+ rc= mysql_commit(mysql);
+ myquery(rc);
+
+ /* i18n part of test case. */
+
+ {
+ const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
+ const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
+ char o1_buffer[255];
+ ulong o1_length;
+ char o2_buffer[255];
+ ulong o2_length;
+
+ MYSQL_BIND rs_bind[2];
+
+ strmov(query, "CALL p2(?, ?, ?)");
+ stmt= mysql_simple_prepare(mysql, query);
+ check_stmt(stmt);
+
+ /* Init PS-parameters. */
+
+ bzero((char *) ps_params, sizeof (ps_params));
+
+ ps_params[0].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[0].buffer= (char *) str_koi8r;
+ ps_params[0].buffer_length= strlen(str_koi8r);
+
+ ps_params[1].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[1].buffer= o1_buffer;
+ ps_params[1].buffer_length= 0;
+
+ ps_params[2].buffer_type= MYSQL_TYPE_STRING;
+ ps_params[2].buffer= o2_buffer;
+ ps_params[2].buffer_length= 0;
+
+ /* Bind parameters. */
+
+ rc= mysql_stmt_bind_param(stmt, ps_params);
+ check_execute(stmt, rc);
+
+ /* Prevent converting to character_set_results. */
+
+ rc= mysql_query(mysql, "SET NAMES binary");
+ myquery(rc);
+
+ /* Execute statement. */
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ /* Bind result. */
+
+ bzero(rs_bind, sizeof (rs_bind));
+
+ rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
+ rs_bind[0].buffer= o1_buffer;
+ rs_bind[0].buffer_length= sizeof (o1_buffer);
+ rs_bind[0].length= &o1_length;
+
+ rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
+ rs_bind[1].buffer= o2_buffer;
+ rs_bind[1].buffer_length= sizeof (o2_buffer);
+ rs_bind[1].length= &o2_length;
+
+ rc= mysql_stmt_bind_result(stmt, rs_bind);
+ check_execute(stmt, rc);
+
+ /* Fetch result. */
+
+ rc= mysql_stmt_fetch(stmt);
+ check_execute(stmt, rc);
+
+ /* Check result. */
+
+ DIE_UNLESS(o1_length == strlen(str_cp1251));
+ DIE_UNLESS(o2_length == strlen(str_koi8r));
+ DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
+ DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+
+ rc= mysql_stmt_next_result(stmt);
+ DIE_UNLESS(rc == 0 && mysql->field_count == 0);
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_commit(mysql);
+ myquery(rc);
+ }
+}
+
+static void test_wl4435_2()
+{
+ MYSQL_STMT *stmt;
+ int i;
+ int rc;
+ char query[MAX_TEST_QUERY_LENGTH];
+
+ myheader("test_wl4435_2");
+ mct_start_logging("test_wl4435_2");
+
+ /*
+ Do a few iterations so that we catch any problem with incorrect
+ handling/flushing prepared statement results.
+ */
+
+ for (i= 0; i < 10; ++i)
+ {
+ /*
+ Prepare a procedure. That can be moved out of the loop, but it was
+ left in the loop for the sake of having as many statements as
+ possible.
+ */
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(mysql,
+ "CREATE PROCEDURE p1()"
+ "BEGIN "
+ " SELECT 1; "
+ " SELECT 2, 3 UNION SELECT 4, 5; "
+ " SELECT 6, 7, 8; "
+ "END");
+ myquery(rc);
+
+ /* Invoke a procedure, that returns several result sets. */
+
+ strmov(query, "CALL p1()");
+ stmt= mysql_simple_prepare(mysql, query);
+ check_stmt(stmt);
+
+ /* Execute! */
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ /* Flush all the results. */
+
+ mysql_stmt_close(stmt);
+
+ /* Clean up. */
+ rc= mysql_commit(mysql);
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE p1");
+ myquery(rc);
+ }
+}
+
+
+#define WL4435_TEST(sql_type, sql_value, \
+ c_api_in_type, c_api_out_type, \
+ c_type, c_type_ext, \
+ printf_args, assert_condition) \
+\
+ do { \
+ int rc; \
+ MYSQL_STMT *ps; \
+ MYSQL_BIND psp; \
+ MYSQL_RES *rs_metadata; \
+ MYSQL_FIELD *fields; \
+ c_type pspv c_type_ext; \
+ my_bool psp_null; \
+ \
+ bzero(&pspv, sizeof (pspv)); \
+ \
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
+ myquery(rc); \
+ \
+ rc= mysql_query(mysql, \
+ "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
+ myquery(rc); \
+ \
+ ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
+ check_stmt(ps); \
+ \
+ bzero(&psp, sizeof (psp)); \
+ psp.buffer_type= c_api_in_type; \
+ psp.is_null= &psp_null; \
+ psp.buffer= (char *) &pspv; \
+ psp.buffer_length= sizeof (psp); \
+ \
+ rc= mysql_stmt_bind_param(ps, &psp); \
+ check_execute(ps, rc); \
+ \
+ rc= mysql_stmt_execute(ps); \
+ check_execute(ps, rc); \
+ \
+ DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
+ DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
+ \
+ rs_metadata= mysql_stmt_result_metadata(ps); \
+ fields= mysql_fetch_fields(rs_metadata); \
+ \
+ rc= mysql_stmt_bind_result(ps, &psp); \
+ check_execute(ps, rc); \
+ \
+ rc= mysql_stmt_fetch(ps); \
+ DIE_UNLESS(rc == 0); \
+ \
+ DIE_UNLESS(fields[0].type == c_api_out_type); \
+ printf printf_args; \
+ printf("; in type: %d; out type: %d\n", \
+ (int) c_api_in_type, (int) c_api_out_type); \
+ \
+ rc= mysql_stmt_fetch(ps); \
+ DIE_UNLESS(rc == MYSQL_NO_DATA); \
+ \
+ rc= mysql_stmt_next_result(ps); \
+ DIE_UNLESS(rc == 0); \
+ \
+ mysql_stmt_free_result(ps); \
+ mysql_stmt_close(ps); \
+ \
+ DIE_UNLESS(assert_condition); \
+ \
+ } while (0)
+
+static void test_wl4435_3()
+{
+ char tmp[255];
+
+ puts("");
+
+ // The following types are not supported:
+ // - ENUM
+ // - SET
+ //
+ // The following types are supported but can not be used for
+ // OUT-parameters:
+ // - MEDIUMINT;
+ // - BIT(..);
+ //
+ // The problem is that those types are not supported for IN-parameters,
+ // and OUT-parameters should be bound as IN-parameters before execution.
+ //
+ // The following types should not be used:
+ // - 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,
+ char, ,
+ (" - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
+ pspv == 127);
+
+ WL4435_TEST("SMALLINT", "32767",
+ MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
+ short, ,
+ (" - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
+ pspv == 32767);
+
+ WL4435_TEST("INT", "2147483647",
+ MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
+ int, ,
+ (" - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
+ pspv == 2147483647l);
+
+ WL4435_TEST("BIGINT", "9223372036854775807",
+ MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
+ long long, ,
+ (" - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
+ pspv == 9223372036854775807ll);
+
+ WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
+ MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
+ MYSQL_TIME, ,
+ (" - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
+ "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
+ (int) pspv.year, (int) pspv.month, (int) pspv.day,
+ (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
+ pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
+ pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
+
+ WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
+ MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
+ MYSQL_TIME, ,
+ (" - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
+ "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
+ (int) pspv.year, (int) pspv.month, (int) pspv.day,
+ (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
+ pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
+ pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
+
+ WL4435_TEST("TIME", "'123:45:01'",
+ MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
+ MYSQL_TIME, ,
+ (" - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
+ "%.3d:%.2d:%.2d",
+ (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
+ pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
+
+ WL4435_TEST("DATE", "'1234-11-12'",
+ MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
+ MYSQL_TIME, ,
+ (" - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
+ "%.4d-%.2d-%.2d",
+ (int) pspv.year, (int) pspv.month, (int) pspv.day),
+ pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
+
+ WL4435_TEST("YEAR", "'2010'",
+ MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
+ short, ,
+ (" - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
+ pspv == 2010);
+
+ WL4435_TEST("FLOAT(7, 4)", "123.4567",
+ MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
+ float, ,
+ (" - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
+ pspv - 123.4567 < 0.0001);
+
+ WL4435_TEST("DOUBLE(8, 5)", "123.45678",
+ MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
+ double, ,
+ (" - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
+ pspv - 123.45678 < 0.00001);
+
+ WL4435_TEST("DECIMAL(9, 6)", "123.456789",
+ MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
+ char, [255],
+ (" - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
+ !strcmp(pspv, "123.456789"));
+
+ WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
+ MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
+ char, [255],
+ (" - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
+ !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
+
+ WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
+ MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
+ char, [255],
+ (" - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
+ !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
+
+ WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
+ MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
+ !strcmp(pspv, "tttttttttttttttt"));
+
+ WL4435_TEST("TEXT", "REPEAT('t', 16)",
+ MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
+ !strcmp(pspv, "tttttttttttttttt"));
+
+ WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
+ MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
+ !strcmp(pspv, "tttttttttttttttt"));
+
+ WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
+ MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
+ !strcmp(pspv, "tttttttttttttttt"));
+
+ WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
+ MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
+ char, [255],
+ (" - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
+ memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
+
+ WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
+ MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
+ char, [255],
+ (" - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
+ memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
+
+ WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
+ MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
+ memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
+
+ WL4435_TEST("BLOB", "REPEAT('\2', 16)",
+ MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
+ memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
+
+ WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
+ MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
+ memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
+
+ WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
+ MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
+ char, [255],
+ (" - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
+ memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
+}
+
/* Test simple prepare field results */
@@ -594,7 +1407,7 @@ static void test_prepare()
/* now, execute the prepared statement to insert 10 records.. */
for (tiny_data= 0; tiny_data < 100; tiny_data++)
{
- length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data));
+ length[1]= sprintf(str_data, "MySQL%d", int_data);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
int_data += 25;
@@ -633,7 +1446,7 @@ static void test_prepare()
/* now, execute the prepared statement to insert 10 records.. */
for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
{
- len= my_sprintf(data, (data, "MySQL%d", o_int_data));
+ len= sprintf(data, "MySQL%d", o_int_data);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
@@ -1496,6 +2309,7 @@ static void test_ps_query_cache()
if (!opt_silent)
fprintf(stdout, "OK");
+ break;
}
strmov(query, "select id1, value1 from t1 where id1= ? or "
@@ -2033,7 +2847,7 @@ static void test_simple_update()
my_bind[0].buffer= szData; /* string data */
my_bind[0].buffer_length= sizeof(szData);
my_bind[0].length= &length[0];
- length[0]= my_sprintf(szData, (szData, "updated-data"));
+ length[0]= sprintf(szData, "updated-data");
my_bind[1].buffer= (void *) &nData;
my_bind[1].buffer_type= MYSQL_TYPE_LONG;
@@ -2287,7 +3101,7 @@ static void test_long_data_str1()
rc= mysql_stmt_bind_param(stmt, my_bind);
check_execute(stmt, rc);
- length= my_sprintf(data, (data, "MySQL AB"));
+ length= sprintf(data, "MySQL AB");
/* supply data in pieces */
for (i= 0; i < 3; i++)
@@ -2602,7 +3416,7 @@ static void test_update()
my_bind[0].buffer= szData;
my_bind[0].buffer_length= sizeof(szData);
my_bind[0].length= &length[0];
- length[0]= my_sprintf(szData, (szData, "inserted-data"));
+ length[0]= sprintf(szData, "inserted-data");
my_bind[1].buffer= (void *)&nData;
my_bind[1].buffer_type= MYSQL_TYPE_LONG;
@@ -2631,7 +3445,7 @@ static void test_update()
my_bind[0].buffer= szData;
my_bind[0].buffer_length= sizeof(szData);
my_bind[0].length= &length[0];
- length[0]= my_sprintf(szData, (szData, "updated-data"));
+ length[0]= sprintf(szData, "updated-data");
my_bind[1].buffer= (void *)&nData;
my_bind[1].buffer_type= MYSQL_TYPE_LONG;
@@ -3200,7 +4014,7 @@ static void bind_fetch(int row_count)
/* CHAR */
{
char buff[20];
- long len= my_sprintf(buff, (buff, "%d", rc));
+ long len= sprintf(buff, "%d", rc);
DIE_UNLESS(strcmp(s_data, buff) == 0);
DIE_UNLESS(length[6] == (ulong) len);
}
@@ -3793,7 +4607,7 @@ static void test_insert()
/* now, execute the prepared statement to insert 10 records.. */
for (tiny_data= 0; tiny_data < 3; tiny_data++)
{
- length= my_sprintf(str_data, (str_data, "MySQL%d", tiny_data));
+ length= sprintf(str_data, "MySQL%d", tiny_data);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
}
@@ -4031,7 +4845,7 @@ static void test_stmt_close()
}
-/* Test simple set-variable prepare */
+/* Test simple set variable prepare */
static void test_set_variable()
{
@@ -4133,215 +4947,6 @@ static void test_set_variable()
mysql_stmt_close(stmt1);
}
-#if NOT_USED
-
-/* Insert meta info .. */
-
-static void test_insert_meta()
-{
- MYSQL_STMT *stmt;
- int rc;
- MYSQL_RES *result;
- MYSQL_FIELD *field;
-
- myheader("test_insert_meta");
-
- rc= mysql_autocommit(mysql, TRUE);
- myquery(rc);
-
- rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
- myquery(rc);
-
- rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
- col2 varchar(50), col3 varchar(30))");
- myquery(rc);
-
- strmov(query, "INSERT INTO test_prep_insert VALUES(10, 'venu1', 'test')");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 0);
-
- result= mysql_param_result(stmt);
- mytest_r(result);
-
- mysql_stmt_close(stmt);
-
- strmov(query, "INSERT INTO test_prep_insert VALUES(?, 'venu', ?)");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 2);
-
- result= mysql_param_result(stmt);
- mytest(result);
-
- my_print_result_metadata(result);
-
- mysql_field_seek(result, 0);
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col1");
- DIE_UNLESS(strcmp(field->name, "col1") == 0);
-
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", field->name, "col3");
- DIE_UNLESS(strcmp(field->name, "col3") == 0);
-
- field= mysql_fetch_field(result);
- mytest_r(field);
-
- mysql_free_result(result);
- mysql_stmt_close(stmt);
-}
-
-
-/* Update meta info .. */
-
-static void test_update_meta()
-{
- MYSQL_STMT *stmt;
- int rc;
- MYSQL_RES *result;
- MYSQL_FIELD *field;
-
- myheader("test_update_meta");
-
- rc= mysql_autocommit(mysql, TRUE);
- myquery(rc);
-
- rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_update");
- myquery(rc);
-
- rc= mysql_query(mysql, "CREATE TABLE test_prep_update(col1 tinyint, \
- col2 varchar(50), col3 varchar(30))");
- myquery(rc);
-
- strmov(query, "UPDATE test_prep_update SET col1=10, col2='venu1' WHERE col3='test'");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 0);
-
- result= mysql_param_result(stmt);
- mytest_r(result);
-
- mysql_stmt_close(stmt);
-
- strmov(query, "UPDATE test_prep_update SET col1=?, col2='venu' WHERE col3=?");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 2);
-
- result= mysql_param_result(stmt);
- mytest(result);
-
- my_print_result_metadata(result);
-
- mysql_field_seek(result, 0);
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- {
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
- }
- DIE_UNLESS(strcmp(field->name, "col1") == 0);
- DIE_UNLESS(strcmp(field->table, "test_prep_update") == 0);
-
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- {
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col3");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_update");
- }
- DIE_UNLESS(strcmp(field->name, "col3") == 0);
- DIE_UNLESS(strcmp(field->table, "test_prep_update") == 0);
-
- field= mysql_fetch_field(result);
- mytest_r(field);
-
- mysql_free_result(result);
- mysql_stmt_close(stmt);
-}
-
-
-/* Select meta info .. */
-
-static void test_select_meta()
-{
- MYSQL_STMT *stmt;
- int rc;
- MYSQL_RES *result;
- MYSQL_FIELD *field;
-
- myheader("test_select_meta");
-
- rc= mysql_autocommit(mysql, TRUE);
- myquery(rc);
-
- rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_select");
- myquery(rc);
-
- rc= mysql_query(mysql, "CREATE TABLE test_prep_select(col1 tinyint, \
- col2 varchar(50), col3 varchar(30))");
- myquery(rc);
-
- strmov(query, "SELECT * FROM test_prep_select WHERE col1=10");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 0);
-
- result= mysql_param_result(stmt);
- mytest_r(result);
-
- strmov(query, "SELECT col1, col3 from test_prep_select WHERE col1=? AND col3='test' AND col2= ?");
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- verify_param_count(stmt, 2);
-
- result= mysql_param_result(stmt);
- mytest(result);
-
- my_print_result_metadata(result);
-
- mysql_field_seek(result, 0);
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- {
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col1");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
- }
- DIE_UNLESS(strcmp(field->name, "col1") == 0);
- DIE_UNLESS(strcmp(field->table, "test_prep_select") == 0);
-
- field= mysql_fetch_field(result);
- mytest(field);
- if (!opt_silent)
- {
- fprintf(stdout, "\n col obtained: `%s` (expected: `%s`)", field->name, "col2");
- fprintf(stdout, "\n tab obtained: `%s` (expected: `%s`)", field->table, "test_prep_select");
- }
- DIE_UNLESS(strcmp(field->name, "col2") == 0);
- DIE_UNLESS(strcmp(field->table, "test_prep_select") == 0);
-
- field= mysql_fetch_field(result);
- mytest_r(field);
-
- mysql_free_result(result);
- mysql_stmt_close(stmt);
-}
-#endif
-
-
/* Test FUNCTION field info / DATE_FORMAT() table_name . */
static void test_func_fields()
@@ -6716,26 +7321,26 @@ static void test_explain_bug()
verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 64, 0);
+ 0, 0, "information_schema", 64, 0);
verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
- 0, 0, "", 0, 0);
+ 0, 0, "information_schema", 0, 0);
verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 3, 0);
+ 0, 0, "information_schema", 3, 0);
verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 3, 0);
+ 0, 0, "information_schema", 3, 0);
if ( mysql_get_server_version(mysql) >= 50027 )
{
/* The patch for bug#23037 changes column type of DEAULT to blob */
verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
- MYSQL_TYPE_BLOB, 0, 0, "", 0, 0);
+ MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
}
else
{
@@ -6744,14 +7349,14 @@ static void test_explain_bug()
MYSQL_TYPE_BLOB :
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "",
+ 0, 0, "information_schema",
mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
}
verify_prepare_field(result, 5, "Extra", "EXTRA",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 27, 0);
+ 0, 0, "information_schema", 27, 0);
mysql_free_result(result);
mysql_stmt_close(stmt);
@@ -11445,7 +12050,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- DIE_UNLESS(mysql_warning_count(mysql) == 6);
+ 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");
@@ -11476,7 +12081,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- DIE_UNLESS(mysql_warning_count(mysql) == 3);
+ 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");
@@ -11515,7 +12120,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- DIE_UNLESS(mysql_warning_count(mysql) == 2);
+ my_process_warnings(mysql, 2);
verify_col_data("t1", "day_ovfl", "838:59:59");
verify_col_data("t1", "day", "828:30:30");
@@ -11751,7 +12356,10 @@ static void test_truncation()
")";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
- stmt_text= "insert into t1 VALUES ("
+
+ {
+ const char insert_text[]=
+ "insert into t1 VALUES ("
"-10, " /* i8 */
"200, " /* ui8 */
"32000, " /* i16 */
@@ -11767,8 +12375,9 @@ static void test_truncation()
"'12345.67 ', " /* tx_1 */
"'12345.67abc'" /* ch_2 */
")";
- rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
- myquery(rc);
+ rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
+ myquery(rc);
+ }
stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
" i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
@@ -12417,6 +13026,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()
{
@@ -13435,9 +14087,8 @@ static void test_bug12001()
/* Create connection that supports multi statements */
if (!mysql_real_connect(mysql_local, opt_host, opt_user,
- opt_password, current_db, opt_port,
- opt_unix_socket, CLIENT_MULTI_STATEMENTS |
- CLIENT_MULTI_RESULTS))
+ opt_password, current_db, opt_port,
+ opt_unix_socket, CLIENT_MULTI_STATEMENTS))
{
fprintf(stdout, "\n mysql_real_connect() failed");
exit(1);
@@ -14001,8 +14652,11 @@ static void test_bug13488()
check_execute(stmt1, rc);
if (!opt_silent)
- printf("data is: %s", (f1 == 1 && f2 == 1 && f3 == 2)?"OK":
- "wrong");
+ {
+ printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
+ printf("data is: %s\n",
+ (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
+ }
DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
rc= mysql_query(mysql, "drop table t1, t2");
myquery(rc);
@@ -14805,7 +15459,7 @@ static void test_bug15752()
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket,
- CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS))
+ CLIENT_MULTI_STATEMENTS))
{
printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
DIE_UNLESS(0);
@@ -16093,9 +16747,9 @@ static void test_bug20023()
SQL_BIG_SELECTS will be 1.
***********************************************************************/
- /* Set MAX_JOIN_SIZE to the default value (-1). */
+ /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
- DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 18446744073709551615"));
+ DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */
@@ -16126,7 +16780,7 @@ static void test_bug20023()
DIE_IF(mysql_query(&con, query_buffer));
- DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 18446744073709551615"));
+ DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */
@@ -16249,13 +16903,14 @@ 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
@@ -16292,7 +16947,7 @@ static void test_bug31669()
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 "
@@ -16311,11 +16966,11 @@ static void test_bug31669()
rc= mysql_change_user(conn, user, buff, db);
DIE_UNLESS(!rc);
- user[USERNAME_CHAR_LENGTH-1]= 'a';
+ 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(conn, user, buff, db);
DIE_UNLESS(rc);
@@ -16431,6 +17086,7 @@ static void test_bug28386()
DBUG_VOID_RETURN;
}
+
static void test_wl4166_1()
{
MYSQL_STMT *stmt;
@@ -16509,7 +17165,7 @@ static void test_wl4166_1()
/* now, execute the prepared statement to insert 10 records.. */
for (tiny_data= 0; tiny_data < 10; tiny_data++)
{
- length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data));
+ length[1]= sprintf(str_data, "MySQL%d", int_data);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
int_data += 25;
@@ -16532,7 +17188,7 @@ static void test_wl4166_1()
for (tiny_data= 50; tiny_data < 60; tiny_data++)
{
- length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data));
+ length[1]= sprintf(str_data, "MySQL%d", int_data);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
int_data += 25;
@@ -16642,10 +17298,266 @@ static void test_wl4166_2()
}
+
+/**
+ Test how warnings generated during assignment of parameters
+ are (currently not) preserve in case of reprepare.
+*/
+
+static void test_wl4166_3()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND my_bind[1];
+ MYSQL_TIME tm[1];
+
+ myheader("test_wl4166_3");
+
+ rc= mysql_query(mysql, "drop table if exists t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "create table t1 (year datetime)");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
+ check_stmt(stmt);
+ verify_param_count(stmt, 1);
+
+ bzero((char*) my_bind, sizeof(my_bind));
+ my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
+ my_bind[0].buffer= &tm[0];
+
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ tm[0].year= 10000;
+ tm[0].month= 1; tm[0].day= 1;
+ tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
+ tm[0].second_part= 0; tm[0].neg= 0;
+
+ /* Cause a statement reprepare */
+ rc= mysql_query(mysql, "alter table t1 add column c int");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ /*
+ Sic: only one warning, instead of two. The warning
+ about data truncation when assigning a parameter is lost.
+ This is a bug.
+ */
+ my_process_warnings(mysql, 1);
+
+ verify_col_data("t1", "year", "0000-00-00 00:00:00");
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+}
+
+
+/**
+ Test that long data parameters, as well as parameters
+ that were originally in a different character set, are
+ preserved in case of reprepare.
+*/
+
+static void test_wl4166_4()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+ const char *stmt_text;
+ MYSQL_BIND bind_array[2];
+
+ /* Represented as numbers to keep UTF8 tools from clobbering them. */
+ const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
+ const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
+ char buf1[16], buf2[16];
+ ulong buf1_len, buf2_len;
+
+ myheader("test_wl4166_4");
+
+ rc= mysql_query(mysql, "drop table if exists t1");
+ myquery(rc);
+
+ /*
+ Create table with binary columns, set session character set to cp1251,
+ client character set to koi8, and make sure that there is conversion
+ on insert and no conversion on select
+ */
+ rc= mysql_query(mysql,
+ "create table t1 (c1 varbinary(255), c2 varbinary(255))");
+ myquery(rc);
+ rc= mysql_query(mysql, "set character_set_client=koi8r, "
+ "character_set_connection=cp1251, "
+ "character_set_results=koi8r");
+ myquery(rc);
+
+ bzero((char*) bind_array, sizeof(bind_array));
+
+ bind_array[0].buffer_type= MYSQL_TYPE_STRING;
+
+ bind_array[1].buffer_type= MYSQL_TYPE_STRING;
+ bind_array[1].buffer= (void *) koi8;
+ bind_array[1].buffer_length= strlen(koi8);
+
+ stmt= mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ stmt_text= "insert into t1 (c1, c2) values (?, ?)";
+
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ check_execute(stmt, rc);
+
+ mysql_stmt_bind_param(stmt, bind_array);
+
+ mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
+
+ /* Cause a reprepare at statement execute */
+ rc= mysql_query(mysql, "alter table t1 add column d int");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ stmt_text= "select c1, c2 from t1";
+
+ /* c1 and c2 are binary so no conversion will be done on select */
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ bind_array[0].buffer= buf1;
+ bind_array[0].buffer_length= sizeof(buf1);
+ bind_array[0].length= &buf1_len;
+
+ bind_array[1].buffer= buf2;
+ bind_array[1].buffer_length= sizeof(buf2);
+ bind_array[1].length= &buf2_len;
+
+ mysql_stmt_bind_result(stmt, bind_array);
+
+ rc= mysql_stmt_fetch(stmt);
+ check_execute(stmt, rc);
+
+ DIE_UNLESS(buf1_len == strlen(cp1251));
+ DIE_UNLESS(buf2_len == strlen(cp1251));
+ DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
+ DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "set names default");
+ myquery(rc);
+}
+
+/**
+ Bug#36004 mysql_stmt_prepare resets the list of warnings
+*/
+
+static void test_bug36004()
+{
+ int rc, warning_count= 0;
+ MYSQL_STMT *stmt;
+
+ DBUG_ENTER("test_bug36004");
+ myheader("test_bug36004");
+
+ rc= mysql_query(mysql, "drop table if exists inexistant");
+ myquery(rc);
+
+ DIE_UNLESS(mysql_warning_count(mysql) == 1);
+ query_int_variable(mysql, "@@warning_count", &warning_count);
+ DIE_UNLESS(warning_count);
+
+ stmt= mysql_simple_prepare(mysql, "select 1");
+ check_stmt(stmt);
+
+ DIE_UNLESS(mysql_warning_count(mysql) == 0);
+ query_int_variable(mysql, "@@warning_count", &warning_count);
+ DIE_UNLESS(warning_count);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ DIE_UNLESS(mysql_warning_count(mysql) == 0);
+ mysql_stmt_close(stmt);
+
+ query_int_variable(mysql, "@@warning_count", &warning_count);
+ DIE_UNLESS(warning_count);
+
+ stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
+ check_stmt(stmt);
+
+ query_int_variable(mysql, "@@warning_count", &warning_count);
+ DIE_UNLESS(warning_count == 0);
+ mysql_stmt_close(stmt);
+
+ DBUG_VOID_RETURN;
+}
+
/**
- Bug#38486 Crash when using cursor protocol
+ Test that COM_REFRESH issues a implicit commit.
*/
+static void test_wl4284_1()
+{
+ int rc;
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+
+ DBUG_ENTER("test_wl4284_1");
+ myheader("test_wl4284_1");
+
+ /* set AUTOCOMMIT to OFF */
+ rc= mysql_autocommit(mysql, FALSE);
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
+ myquery(rc);
+
+ rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
+ myquery(rc);
+
+ rc= mysql_rollback(mysql);
+ myquery(rc);
+
+ rc= mysql_query(mysql, "SELECT * FROM trans");
+ myquery(rc);
+
+ result= mysql_use_result(mysql);
+ mytest(result);
+
+ row= mysql_fetch_row(result);
+ mytest(row);
+
+ mysql_free_result(result);
+
+ /* set AUTOCOMMIT to ON */
+ rc= mysql_autocommit(mysql, TRUE);
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP TABLE trans");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
+
static void test_bug38486(void)
{
MYSQL_STMT *stmt;
@@ -16672,6 +17584,45 @@ static void test_bug38486(void)
DBUG_VOID_RETURN;
}
+
+/**
+ Bug# 33831 mysql_real_connect() should fail if
+ given an already connected MYSQL handle.
+*/
+
+static void test_bug33831(void)
+{
+ MYSQL *l_mysql;
+
+ DBUG_ENTER("test_bug33831");
+
+ if (!(l_mysql= mysql_client_init(NULL)))
+ {
+ myerror("mysql_client_init() failed");
+ DIE_UNLESS(0);
+ }
+ if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket, 0)))
+ {
+ myerror("connection failed");
+ DIE_UNLESS(0);
+ }
+
+ if (mysql_real_connect(l_mysql, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket, 0))
+ {
+ myerror("connection should have failed");
+ DIE_UNLESS(0);
+ }
+
+ mysql_close(l_mysql);
+
+ DBUG_VOID_RETURN;
+}
+
+
static void test_bug40365(void)
{
uint rc, i;
@@ -16750,6 +17701,8 @@ static void test_bug40365(void)
DIE_UNLESS(tm[i].day == 0);
}
mysql_stmt_close(stmt);
+ rc= mysql_commit(mysql);
+ myquery(rc);
DBUG_VOID_RETURN;
}
@@ -16776,7 +17729,8 @@ static void test_bug43560(void)
const char* values[] = {"eins", "zwei", "drei", "viele", NULL};
const char insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
unsigned long length;
-
+ const unsigned int drop_db= opt_drop_db;
+
DBUG_ENTER("test_bug43560");
myheader("test_bug43560");
@@ -16845,9 +17799,11 @@ static void test_bug43560(void)
rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
- client_disconnect(conn, 0);
+ opt_drop_db= 0;
+ client_disconnect(conn);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
+ opt_drop_db= drop_db;
DBUG_VOID_RETURN;
}
@@ -17096,43 +18052,6 @@ static void test_bug53371()
}
-static void test_bug53907()
-{
- int rc;
- uchar buf[] = "\x4test\x14../client_test_db/t1";
-
- myheader("test_bug53907");
-
- rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
- myquery(rc);
- rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53907");
- myquery(rc);
- rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
-
- rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
- myquery(rc);
- rc= mysql_query(mysql, "CREATE DATABASE bug53907");
- myquery(rc);
- rc= mysql_query(mysql, "GRANT SELECT ON bug53907.* to 'testbug'@localhost");
- myquery(rc);
-
- rc= mysql_change_user(mysql, "testbug", NULL, "bug53907");
- myquery(rc);
-
- rc= simple_command(mysql, COM_TABLE_DUMP, buf, sizeof(buf), 0);
- fprintf(stderr, ">>>>>>>>> %d\n", mysql_errno(mysql));
- DIE_UNLESS(mysql_errno(mysql) == 1103); /* ER_WRONG_TABLE_NAME */
-
- rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
- myquery(rc);
- rc= mysql_query(mysql, "DROP TABLE t1");
- myquery(rc);
- rc= mysql_query(mysql, "DROP DATABASE bug53907");
- myquery(rc);
- rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
- myquery(rc);
-}
-
/**
Bug#42373: libmysql can mess a connection at connect
@@ -17392,7 +18311,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 */
@@ -17454,6 +18373,116 @@ static void test_bug58036()
/*
+ Bug#49972: Crash in prepared statements.
+
+ The following case lead to a server crash:
+ - Use binary protocol;
+ - Prepare a statement with OUT-parameter;
+ - Execute the statement;
+ - Cause re-prepare of the statement (change dependencies);
+ - Execute the statement again -- crash here.
+*/
+
+static void test_bug49972()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+
+ MYSQL_BIND in_param_bind;
+ MYSQL_BIND out_param_bind;
+ int int_data;
+ my_bool is_null;
+
+ DBUG_ENTER("test_bug49972");
+ myheader("test_bug49972");
+
+ rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
+ check_stmt(stmt);
+
+ bzero((char *) &in_param_bind, sizeof (in_param_bind));
+
+ in_param_bind.buffer_type= MYSQL_TYPE_LONG;
+ in_param_bind.buffer= (char *) &int_data;
+ in_param_bind.length= 0;
+ in_param_bind.is_null= 0;
+
+ rc= mysql_stmt_bind_param(stmt, &in_param_bind);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ {
+ bzero(&out_param_bind, sizeof (out_param_bind));
+
+ out_param_bind.buffer_type= MYSQL_TYPE_LONG;
+ out_param_bind.is_null= &is_null;
+ out_param_bind.buffer= &int_data;
+ out_param_bind.buffer_length= sizeof (int_data);
+
+ rc= mysql_stmt_bind_result(stmt, &out_param_bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_fetch(stmt);
+ rc= mysql_stmt_fetch(stmt);
+ DBUG_ASSERT(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_next_result(stmt);
+ mysql_stmt_fetch(stmt);
+ }
+
+ rc= mysql_query(mysql, "DROP FUNCTION f1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ {
+ bzero(&out_param_bind, sizeof (out_param_bind));
+
+ out_param_bind.buffer_type= MYSQL_TYPE_LONG;
+ out_param_bind.is_null= &is_null;
+ out_param_bind.buffer= &int_data;
+ out_param_bind.buffer_length= sizeof (int_data);
+
+ rc= mysql_stmt_bind_result(stmt, &out_param_bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_fetch(stmt);
+ rc= mysql_stmt_fetch(stmt);
+ DBUG_ASSERT(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_next_result(stmt);
+ mysql_stmt_fetch(stmt);
+ }
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE p1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP FUNCTION f1");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Bug #56976: Severe Denial Of Service in prepared statements
*/
static void test_bug56976()
@@ -17492,7 +18521,7 @@ static void test_bug56976()
check_execute(stmt, rc);
}
- my_free(long_buffer, MYF(0));
+ my_free(long_buffer);
rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
@@ -17564,15 +18593,262 @@ static void test_progress_reporting()
myquery(rc);
rc= mysql_query(conn, "set @@global.progress_report_time=@save");
myquery(rc);
- client_disconnect(conn, 0);
+ 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.
+*/
+
+static void test_bug57058()
+{
+ MYSQL_RES *res;
+ int rc;
+
+ DBUG_ENTER("test_bug57058");
+ myheader("test_bug57058");
+
+ rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
+ myquery(rc);
+
+ DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
+
+ rc= mysql_query(mysql, "select sleep(1)");
+ myquery(rc);
+
+ /*
+ Important: the flag is sent in the last EOF packet of
+ the query, the one which ends the result. Read the
+ result to see the "slow" status.
+ */
+ res= mysql_store_result(mysql);
+
+ DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
+
+ mysql_free_result(res);
+
+ rc= mysql_query(mysql, "set @@session.long_query_time=default");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
+*/
+
+static void test_bug11766854()
+{
+ struct st_mysql_client_plugin *plugin;
+
+ DBUG_ENTER("test_bug11766854");
+ myheader("test_bug11766854");
+
+ plugin= mysql_load_plugin(mysql, "foo", -1, 0);
+ DIE_UNLESS(plugin == 0);
+
+ plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
+ DIE_UNLESS(plugin != 0);
+ DIE_IF(mysql_errno(mysql));
+
+ DBUG_VOID_RETURN;
+}
+
+/**
+ Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
+ CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
+*/
+static void test_bug12337762()
+{
+ int rc,i=0;
+ MYSQL_RES *result;
+ MYSQL_FIELD *field;
+ unsigned int tab_charsetnr[3]= {0};
+
+ DBUG_ENTER("test_bug12337762");
+ myheader("test_bug12337762");
+
+ /*
+ Creating table with specific charset.
+ */
+ rc= mysql_query(mysql, "drop table if exists charset_tab");
+ rc= mysql_query(mysql, "create table charset_tab("\
+ "txt1 varchar(32) character set Latin1,"\
+ "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
+ "txt3 varchar(32) character set utf8 collate utf8_bin"\
+ ")");
+
+ DIE_UNLESS(rc == 0);
+ DIE_IF(mysql_errno(mysql));
+
+ /*
+ Creating view from table created earlier.
+ */
+ rc= mysql_query(mysql, "drop view if exists charset_view");
+ rc= mysql_query(mysql, "create view charset_view as "\
+ "select * from charset_tab;");
+ DIE_UNLESS(rc == 0);
+ DIE_IF(mysql_errno(mysql));
+
+ /*
+ Checking field information for table.
+ */
+ result= mysql_list_fields(mysql, "charset_tab", NULL);
+ DIE_IF(mysql_errno(mysql));
+ i=0;
+ while((field= mysql_fetch_field(result)))
+ {
+ printf("field name %s\n", field->name);
+ printf("field table %s\n", field->table);
+ printf("field type %d\n", field->type);
+ printf("field charset %d\n", field->charsetnr);
+ tab_charsetnr[i++]= field->charsetnr;
+ printf("\n");
+ }
+ mysql_free_result(result);
+
+ /*
+ Checking field information for view.
+ */
+ result= mysql_list_fields(mysql, "charset_view", NULL);
+ DIE_IF(mysql_errno(mysql));
+ i=0;
+ while((field= mysql_fetch_field(result)))
+ {
+ printf("field name %s\n", field->name);
+ printf("field table %s\n", field->table);
+ printf("field type %d\n", field->type);
+ printf("field charset %d\n", field->charsetnr);
+ printf("\n");
+ /*
+ charset value for field must be same for both, view and table.
+ */
+ DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
+ }
+ mysql_free_result(result);
+
+ DBUG_VOID_RETURN;
}
/*
- Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN
- CONCURRENTLY.
+ BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
*/
+static void test_bug11754979()
+{
+ MYSQL* conn;
+ DBUG_ENTER("test_bug11754979");
+
+ myheader("test_bug11754979");
+ DIE_UNLESS((conn= mysql_client_init(NULL)));
+ DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
+ opt_password, opt_db ? opt_db:"test", opt_port,
+ opt_unix_socket, CLIENT_FOUND_ROWS));
+ myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
+ myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
+ myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
+ myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
+ "ON DUPLICATE KEY UPDATE id = 4"));
+ DIE_UNLESS(mysql_affected_rows(conn) == 2);
+ myquery(mysql_query(conn, "DROP TABLE t1"));
+ mysql_close(conn);
+
+ 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.
+*/
static void test_bug13001491()
{
int rc;
@@ -17920,6 +19196,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 },
@@ -17983,26 +19261,40 @@ static struct my_tests_st my_tests[]= {
{ "test_bug20023", test_bug20023 },
{ "test_bug45010", test_bug45010 },
{ "test_bug53371", test_bug53371 },
- { "test_bug53907", test_bug53907 },
{ "test_bug31418", test_bug31418 },
{ "test_bug31669", test_bug31669 },
{ "test_bug28386", test_bug28386 },
{ "test_wl4166_1", test_wl4166_1 },
{ "test_wl4166_2", test_wl4166_2 },
+ { "test_wl4166_3", test_wl4166_3 },
+ { "test_wl4166_4", test_wl4166_4 },
+ { "test_bug36004", test_bug36004 },
+ { "test_wl4284_1", test_wl4284_1 },
+ { "test_wl4435", test_wl4435 },
+ { "test_wl4435_2", test_wl4435_2 },
+ { "test_wl4435_3", test_wl4435_3 },
{ "test_bug38486", test_bug38486 },
+ { "test_bug33831", test_bug33831 },
{ "test_bug40365", test_bug40365 },
{ "test_bug43560", test_bug43560 },
{ "test_bug36326", test_bug36326 },
{ "test_bug41078", test_bug41078 },
{ "test_bug44495", test_bug44495 },
+ { "test_bug49972", test_bug49972 },
{ "test_bug42373", test_bug42373 },
{ "test_bug54041", test_bug54041 },
{ "test_bug47485", test_bug47485 },
{ "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/pmail.pl b/tests/pmail.pl
index 02d5d60ac0f..38905832069 100755
--- a/tests/pmail.pl
+++ b/tests/pmail.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2000, 2005 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# Prints mails to standard output
#
diff --git a/tests/rename_test.pl b/tests/rename_test.pl
index edf3216a62f..23fc33c9095 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2000, 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test with uses processes to insert, select and drop tables.
#
diff --git a/tests/table_types.pl b/tests/table_types.pl
index 4dbcdcb975c..23d26215abe 100755
--- a/tests/table_types.pl
+++ b/tests/table_types.pl
@@ -1,5 +1,19 @@
#!/usr/bin/perl
-#
+
+# Copyright (C) 2000, 2003 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
use DBI;
use Benchmark;
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index c7a8f0ca4b7..5046c4fb580 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -1,5 +1,20 @@
#!/usr/bin/perl -w
+# Copyright (C) 2000, 2001 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
# This is a test for INSERT DELAYED
#
diff --git a/tests/thread_test.c b/tests/thread_test.c
index 0944cbc0970..bf0fb8ea2c0 100644
--- a/tests/thread_test.c
+++ b/tests/thread_test.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
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
@@ -11,19 +11,10 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <my_global.h>
-#ifndef THREAD
-
-int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
-{
- printf("This test must be compiled with multithread support to work\n");
- exit(1);
-}
-#else
-
#include <my_sys.h>
#include <my_pthread.h>
#include "mysql.h"
@@ -77,7 +68,7 @@ end:
mysql_close(mysql);
pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
- VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
+ pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
pthread_mutex_unlock(&LOCK_thread_count);
pthread_exit(0);
return 0;
@@ -88,36 +79,36 @@ static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
- {"database", 'D', "Database to use", (uchar**) &database, (uchar**) &database,
+ {"database", 'D', "Database to use", &database, &database,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"host", 'h', "Connect to host", (uchar**) &host, (uchar**) &host, 0, GET_STR,
+ {"host", 'h', "Connect to host", &host, &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},
- {"user", 'u', "User for login if not current user", (uchar**) &user,
- (uchar**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", &user,
+ &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"verbose", 'v', "Write some progress indicators", (uchar**) &verbose,
- (uchar**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"query", 'Q', "Query to execute in each threads", (uchar**) &query,
- (uchar**) &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write some progress indicators", &verbose,
+ &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"query", 'Q', "Query to execute in each threads", &query,
+ &query, 0, GET_STR, REQUIRED_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) ").",
- (uchar**) &tcp_port,
- (uchar**) &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
- {"socket", 'S', "Socket file to use for connection", (uchar**) &unix_socket,
- (uchar**) &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ &tcp_port,
+ &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection", &unix_socket,
+ &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"test-count", 'c', "Run test count times (default %d)",
- (uchar**) &number_of_tests, (uchar**) &number_of_tests, 0, GET_UINT,
+ &number_of_tests, &number_of_tests, 0, GET_UINT,
REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
{"thread-count", 't', "Number of threads to start",
- (uchar**) &number_of_threads, (uchar**) &number_of_threads, 0, GET_UINT,
+ &number_of_threads, &number_of_threads, 0, GET_UINT,
REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -151,7 +142,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'p':
if (argument)
{
- my_free(password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(password);
password= my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
}
@@ -177,9 +168,8 @@ static void get_options(int argc, char **argv)
{
int ho_error;
- load_defaults("my",load_default_groups,&argc,&argv);
-
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ if ((ho_error= load_defaults("my",load_default_groups,&argc,&argv)) ||
+ (ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error);
free_defaults(argv);
@@ -256,4 +246,3 @@ int main(int argc, char **argv)
return 0; /* Keep some compilers happy */
}
-#endif /* THREAD */
diff --git a/tests/truncate.pl b/tests/truncate.pl
index 57b50cf96b6..85e826fd4cd 100755
--- a/tests/truncate.pl
+++ b/tests/truncate.pl
@@ -1,4 +1,20 @@
#!/usr/bin/perl -w
+
+# Copyright (C) 2002 MySQL 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
#
# This is a test with uses many processes to test a MySQL server.
#