diff --git a/.bzrignore b/.bzrignore index b344b511251..ae028ae9426 100644 --- a/.bzrignore +++ b/.bzrignore @@ -102,6 +102,7 @@ Makefile.in Makefile.in' PENDING/* TAGS +VC++Files/client/mysql_amd64.dsp ac_available_languages_fragment acinclude.m4 aclocal.m4 @@ -274,6 +275,8 @@ client/mysqlmanager-pwgen client/mysqlmanagerc client/mysqlshow client/mysqltest +client/mysqltestmanager-pwgen +client/mysqltestmanagerc client/mysys_priv.h client/select_test client/ssl_test @@ -284,10 +287,12 @@ cmd-line-utils/libedit/common.h cmd-line-utils/libedit/makelist comon.h config.cache +config.guess config.h config.h.in config.log config.status +config.sub configure configure.lineno core @@ -355,6 +360,7 @@ innobase/ib_config.h.in innobase/stamp-h1 insert_test install +install-sh isam/isamchk isam/isamlog isam/pack_isam @@ -519,7 +525,9 @@ linked_libmysqldex_sources linked_server_sources linked_tools_sources locked +ltmain.sh man/*.1 +missing mit-pthreads/config.flags mit-pthreads/include/bits mit-pthreads/include/pthread/machdep.h @@ -936,6 +944,7 @@ scripts/mysqld_multi scripts/mysqld_safe scripts/mysqldumpslow scripts/mysqlhotcopy +scripts/mysqlhotcopy.sh.rej scripts/safe_mysqld select_test server-tools/instance-manager/client.c @@ -1100,18 +1109,10 @@ tmp/* tools/my_vsnprintf.c tools/mysqlmanager tools/mysqlmngd +tools/mysqltestmanager tools/mysys_priv.h vi.h vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl -VC++Files/client/mysql_amd64.dsp -client/mysqltestmanager-pwgen -client/mysqltestmanagerc -tools/mysqltestmanager -config.guess -config.sub -install-sh -ltmain.sh -missing diff --git a/BUILD/check-cpu b/BUILD/check-cpu index 0283c669fb2..b970a4b9a5b 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -6,113 +6,200 @@ # if test -r /proc/cpuinfo ; then + # on Linux (and others?) we can get detailed CPU information out of /proc cpuinfo="cat /proc/cpuinfo" + + # detect CPU family cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` if test -z "$cpu_family" ; then cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` fi + + # detect CPU vendor and model cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1` if test -z "$model_name" ; then model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1` fi + + # fallback: get CPU model from uname output if test -z "$model_name" ; then model_name=`uname -m` fi + + # parse CPU flags + for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do + eval cpu_flag_$flag=yes + done else # Fallback when there is no /proc/cpuinfo case "`uname -s`" in - FreeBSD) + FreeBSD|OpenBSD) cpu_family=`uname -m`; - model_name=`sysctl -b hw.model` + model_name=`sysctl -n hw.model` + ;; + Darwin) + cpu_family=`uname -p` + model_name=`machine` ;; *) cpu_family=`uname -m`; - model_name="unknown"; + model_name=`uname -p`; ;; esac fi -cpu_flag="" -cpu_flag_old="" - +# detect CPU shortname as used by gcc options +# this list is not complete, feel free to add further entries +cpu_arg="" case "$cpu_family--$model_name" in + # DEC Alpha Alpha*EV6*) - cpu_flag="ev6"; + cpu_arg="ev6"; ;; + + # Intel ia32 *Xeon*) - cpu_flag="nocona"; + # a Xeon is just another pentium4 ... + # ... unless it has the "lm" (long-mode) flag set, + # in that case it's a Xeon with EM64T support + if [ -z "$cpu_flag_lm" ]; then + cpu_arg="pentium4"; + else + cpu_arg="nocona"; + fi ;; - *Pentium*4*Mobile*CPU*) - cpu_flag="pentium4m"; + *Pentium*4*Mobile*) + cpu_arg="pentium4m"; ;; - *Pentium*4*CPU*) - cpu_flag="pentium4"; + *Pentium*4*) + cpu_arg="pentium4"; ;; - *Pentium*III*Mobile*CPU*) - cpu_flag="pentium3m"; + *Pentium*III*Mobile*) + cpu_arg="pentium3m"; ;; - *Pentium*III*CPU*) - cpu_flag="pentium3"; + *Pentium*III*) + cpu_arg="pentium3"; ;; *Pentium*M*pro*) - cpu_flag="pentium-m"; - cpu_flag_old="pentium"; + cpu_arg="pentium-m"; ;; *Athlon*64*) - cpu_flag="athlon64"; - cpu_flag_old="athlon"; + cpu_arg="athlon64"; ;; *Athlon*) - cpu_flag="athlon"; + cpu_arg="athlon"; ;; + + # Intel ia64 *Itanium*) # Don't need to set any flags for itanium(at the moment) - cpu_flag=""; + cpu_arg=""; ;; - *ppc) - cpu_flag="powerpc"; - no_march=1; + + # + *ppc*) + cpu_arg='powerpc' ;; + + *powerpc*) + cpu_arg='powerpc' + ;; + + # unknown *) - cpu_flag=""; + cpu_arg=""; ;; esac -if test -z "$cpu_flag"; then - echo "BUILD/check-cpu: Oops, could not findout what kind of cpu this machine is using." - check_cpu_flags="" + +if test -z "$cpu_arg"; then + echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." + check_cpu_cflags="" return fi -echo "cpu_flag: $cpu_flag" - +# different compiler versions have different option names +# for CPU specific command line options if test -z "$CC" ; then cc="gcc"; else cc=$CC - fi cc_ver=`$cc --version | sed 1q` cc_verno=`echo $cc_ver | sed -e 's/[^0-9. ]//g; s/^ *//g; s/ .*//g'` case "$cc_ver--$cc_verno" in - *GCC*--3.4*|*GCC*--3.5*|*GCC*--4.*) - check_cpu_cflags="-mtune=$cpu_flag -march=$cpu_flag" - ;; *GCC*) - # Fix for older compiler versions - if test -n "$cpu_flag_old"; then - cpu_flag="$cpu_flag_old" - fi - check_cpu_cflags="-mcpu=$cpu_flag -march=$cpu_flag" - if test -n "$no_march"; then - check_cpu_cflags="-mcpu=$cpu_flag" - fi + # different gcc backends (and versions) have different CPU flags + case `gcc -dumpmachine` in + i?86-*) + case "$cc_verno" in + 3.4*|3.5*|4.*) + check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg' + ;; + *) + check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg' + ;; + esac + ;; + ppc-*) + check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg' + ;; + *) + check_cpu_cflags="" + return + ;; + esac + ;; + 2.95.*) + # GCC 2.95 doesn't expose its name in --version output + check_cpu_args='-m$cpu_arg' ;; *) check_cpu_cflags="" + return ;; esac -echo $check_cpu_cflags + +# now we check whether the compiler really understands the cpu type +touch __test.c + +while [ "$cpu_arg" ] ; do + echo -n testing $cpu_arg "... " + + # compile check + check_cpu_cflags=`eval echo $check_cpu_args` + if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then + echo ok + break; + fi + + echo failed + check_cpu_cflags="" + + # if compile failed: check whether it supports a predecessor of this CPU + # this list is not complete, feel free to add further entries + case "$cpu_arg" in + # Intel ia32 + nocona) cpu_arg=pentium4 ;; + prescott) cpu_arg=pentium4 ;; + pentium4m) cpu_arg=pentium4 ;; + pentium4) cpu_arg=pentium3 ;; + pentium3m) cpu_arg=pentium3 ;; + pentium3) cpu_arg=pentium2 ;; + pentium2) cpu_arg=pentiumpro ;; + pentiumpro) cpu_arg=pentium ;; + pentium) cpu_arg=i486 ;; + i486) cpu_arg=i386 ;; + + # power / powerPC + 7450) cpu_arg=7400 ;; + + *) cpu_arg="" ;; + esac +done + +rm __test.* + diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index eaf79d29cee..3d4c3d60ca8 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -52,6 +52,7 @@ dlenev@build.mysql.com dlenev@jabberwock.localdomain dlenev@mysql.com ejonore@mc03.ndb.mysql.com +elliot@mysql.com evgen@moonbone.(none) evgen@moonbone.local gbichot@bk-internal.mysql.com @@ -201,6 +202,7 @@ ndbdev@ndbmaster.mysql.com ndbdev@shark. nick@mysql.com nick@nick.leippe.com +obarnir@mysql.com papa@gbichot.local patg@krsna. patg@krsna.patg.net diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp index 4f93ac93c40..32d32fd6b2c 100644 --- a/VC++Files/libmysql/libmysql.dsp +++ b/VC++Files/libmysql/libmysql.dsp @@ -147,10 +147,6 @@ SOURCE="..\strings\ctype-czech.c" # End Source File # Begin Source File -SOURCE="..\strings\ctype-cp932.c" -# End Source File -# Begin Source File - SOURCE="..\strings\ctype-euc_kr.c" # End Source File # Begin Source File diff --git a/client/mysql.cc b/client/mysql.cc index 9cdc270e8ed..bc0cceda0cc 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include #endif -const char *VER= "14.10"; +const char *VER= "14.11"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -1657,11 +1657,12 @@ int mysql_real_query_for_lazy(const char *buf, int length) { for (uint retry=0;; retry++) { + int error; if (!mysql_real_query(&mysql,buf,length)) return 0; - int error= put_error(&mysql); + error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || - !opt_reconnect) + !opt_reconnect) return error; if (reconnect()) return error; @@ -1917,7 +1918,7 @@ com_go(String *buffer,char *line __attribute__((unused))) time_buff[0]=0; if (result) { - if (!mysql_num_rows(result) && ! quick) + if (!mysql_num_rows(result) && ! quick && !info_flag) { strmov(buff, "Empty set"); } @@ -2049,18 +2050,93 @@ com_ego(String *buffer,char *line) return result; } +static char *fieldtype2str(enum enum_field_types type) { + switch(type) { + case FIELD_TYPE_BIT: return "BIT"; + case FIELD_TYPE_BLOB: return "BLOB"; + case FIELD_TYPE_DATE: return "DATE"; + case FIELD_TYPE_DATETIME: return "DATETIME"; + case FIELD_TYPE_NEWDECIMAL: return "NEWDECIMAL"; + case FIELD_TYPE_DECIMAL: return "DECIMAL"; + case FIELD_TYPE_DOUBLE: return "DOUBLE"; + case FIELD_TYPE_ENUM: return "ENUM"; + case FIELD_TYPE_FLOAT: return "FLOAT"; + case FIELD_TYPE_GEOMETRY: return "GEOMETRY"; + case FIELD_TYPE_INT24: return "INT24"; + case FIELD_TYPE_LONG: return "LONG"; + case FIELD_TYPE_LONGLONG: return "LONGLONG"; + case FIELD_TYPE_LONG_BLOB: return "LONG_BLOB"; + case FIELD_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB"; + case FIELD_TYPE_NEWDATE: return "NEWDATE"; + case FIELD_TYPE_NULL: return "NULL"; + case FIELD_TYPE_SET: return "SET"; + case FIELD_TYPE_SHORT: return "SHORT"; + case FIELD_TYPE_STRING: return "STRING"; + case FIELD_TYPE_TIME: return "TIME"; + case FIELD_TYPE_TIMESTAMP: return "TIMESTAMP"; + case FIELD_TYPE_TINY: return "TINY"; + case FIELD_TYPE_TINY_BLOB: return "TINY_BLOB"; + case FIELD_TYPE_VAR_STRING: return "VAR_STRING"; + case FIELD_TYPE_YEAR: return "YEAR"; + default: return "?-unknown-?"; + } +} + +static char *fieldflags2str(uint f) { + static char buf[1024]; + char *s=buf; + *s=0; +#define ff2s_check_flag(X) \ + if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; } + ff2s_check_flag(NOT_NULL); + ff2s_check_flag(PRI_KEY); + ff2s_check_flag(UNIQUE_KEY); + ff2s_check_flag(MULTIPLE_KEY); + ff2s_check_flag(BLOB); + ff2s_check_flag(UNSIGNED); + ff2s_check_flag(ZEROFILL); + ff2s_check_flag(BINARY); + ff2s_check_flag(ENUM); + ff2s_check_flag(AUTO_INCREMENT); + ff2s_check_flag(TIMESTAMP); + ff2s_check_flag(SET); + ff2s_check_flag(NO_DEFAULT_VALUE); + ff2s_check_flag(NUM); + ff2s_check_flag(PART_KEY); + ff2s_check_flag(GROUP); + ff2s_check_flag(UNIQUE); + ff2s_check_flag(BINCMP); +#undef ff2s_check_flag + if (f) + sprintf(s, " unknows=0x%04x", f); + return buf; +} + static void print_field_types(MYSQL_RES *result) { - MYSQL_FIELD *field; + MYSQL_FIELD *field; + uint i=0; + while ((field = mysql_fetch_field(result))) { - tee_fprintf(PAGER,"Catalog: '%s'\nDatabase: '%s'\nTable: '%s'\nName: '%s'\nType: %d\nLength: %ld\nMax length: %ld\nIs_null: %d\nFlags: %u\nDecimals: %u\n\n", - field->catalog, field->db, field->table, field->name, - (int) field->type, - field->length, field->max_length, - !IS_NOT_NULL(field->flags), - field->flags, field->decimals); + tee_fprintf(PAGER, "Field %3u: `%s`\n" + "Catalog: `%s`\n" + "Database: `%s`\n" + "Table: `%s`\n" + "Org_table: `%s`\n" + "Type: %s\n" + "Collation: %s (%u)\n" + "Length: %lu\n" + "Max_length: %lu\n" + "Decimals: %u\n" + "Flags: %s\n\n", + ++i, + field->name, field->catalog, field->db, field->table, + field->org_table, fieldtype2str(field->type), + get_charset_name(field->charsetnr), field->charsetnr, + field->length, field->max_length, field->decimals, + fieldflags2str(field->flags)); } tee_puts("", PAGER); } @@ -2078,6 +2154,8 @@ print_table_data(MYSQL_RES *result) if (info_flag) { print_field_types(result); + if (!mysql_num_rows(result)) + return; mysql_field_seek(result,0); } separator.copy("+",1,charset_info); @@ -2237,22 +2315,23 @@ print_table_data_vertically(MYSQL_RES *result) } } + /* print_warnings should be called right after executing a statement */ -static void -print_warnings() + +static void print_warnings() { - char query[30]; + const char *query; MYSQL_RES *result; MYSQL_ROW cur; + my_ulonglong num_rows; /* Get the warnings */ - strmov(query,"show warnings"); - mysql_real_query_for_lazy(query,strlen(query)); + query= "show warnings"; + mysql_real_query_for_lazy(query, strlen(query)); mysql_store_result_for_lazy(&result); /* Bail out when no warnings */ - my_ulonglong num_rows = mysql_num_rows(result); - if (num_rows == 0) + if (!(num_rows= mysql_num_rows(result))) { mysql_free_result(result); return; @@ -2266,13 +2345,12 @@ print_warnings() mysql_free_result(result); } -static const char -*array_value(const char **array, char key) + +static const char *array_value(const char **array, char key) { - int x; - for (x= 0; array[x]; x+= 2) - if (*array[x] == key) - return array[x + 1]; + for (; *array; array+= 2) + if (**array == key) + return array[1]; return 0; } diff --git a/client/mysqltest.c b/client/mysqltest.c index e3267b1731b..c172d18cbd0 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -246,6 +246,7 @@ typedef struct static char *subst_env_var(const char *cmd); static FILE *my_popen(const char *cmd, const char *mode); +#undef popen #define popen(A,B) my_popen((A),(B)) #endif /* __NETWARE__ */ @@ -2587,13 +2588,13 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) { if (i) dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); + replace_dynstr_append_mem(ds, val, (int)len); } else { dynstr_append(ds, fields[i].name); dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); + replace_dynstr_append_mem(ds, val, (int)len); dynstr_append_mem(ds, "\n", 1); } } @@ -2960,7 +2961,7 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) int error= 0; /* Function return code if "goto end;" */ int err; /* Temporary storage of return code from calls */ int query_len, got_error_on_execute; - uint num_rows; + ulonglong num_rows; char *query; MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ DYNAMIC_STRING *ds; @@ -3215,13 +3216,13 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) { if (col_idx) /* No tab before first col */ dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); + replace_dynstr_append_mem(ds, val, (int)len); } else { dynstr_append(ds, field[col_idx].name); dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); + replace_dynstr_append_mem(ds, val, (int)len); dynstr_append_mem(ds, "\n", 1); } } diff --git a/client/sql_string.cc b/client/sql_string.cc index be4354227a5..51f802e7465 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -16,12 +16,11 @@ /* This file is originally from the mysql distribution. Coded by monty */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif +#include #include #include #include diff --git a/client/sql_string.h b/client/sql_string.h index 242b31e7ed6..e284301b214 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -260,8 +260,6 @@ public: } bool fill(uint32 max_length,char fill); void strip_sp(); - inline void caseup() { my_caseup(str_charset,Ptr,str_length); } - inline void casedn() { my_casedn(str_charset,Ptr,str_length); } friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); diff --git a/configure.in b/configure.in index 936e4ed22e1..08b739c5782 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # Don't forget to also update the NDB lines below. -AM_INIT_AUTOMAKE(mysql, 5.0.7-beta) +AM_INIT_AUTOMAKE(mysql, 5.0.8-beta) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -17,7 +17,7 @@ SHARED_LIB_VERSION=14:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=7 +NDB_VERSION_BUILD=8 NDB_VERSION_STATUS="beta" # Set all version vars based on $VERSION. How do we do this more elegant ? @@ -442,33 +442,33 @@ PS=$ac_cv_path_PS # Linux style if $PS p $$ 2> /dev/null | grep $0 > /dev/null then - FIND_PROC="$PS p \$\$PID | grep \$\$MYSQLD > /dev/null" + FIND_PROC="$PS p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" # Solaris elif $PS -fp $$ 2> /dev/null | grep $0 > /dev/null then - FIND_PROC="$PS -p \$\$PID | grep \$\$MYSQLD > /dev/null" + FIND_PROC="$PS -p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" # BSD style elif $PS -uaxww 2> /dev/null | grep $0 > /dev/null then - FIND_PROC="$PS -uaxww | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" + FIND_PROC="$PS -uaxww | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" # SysV style elif $PS -ef 2> /dev/null | grep $0 > /dev/null then - FIND_PROC="$PS -ef | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" + FIND_PROC="$PS -ef | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" # Do anybody use this? elif $PS $$ 2> /dev/null | grep $0 > /dev/null then - FIND_PROC="$PS \$\$PID | grep \$\$MYSQLD > /dev/null" + FIND_PROC="$PS \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" else case $SYSTEM_TYPE in *freebsd*) - FIND_PROC="$PS p \$\$PID | grep \$\$MYSQLD > /dev/null" + FIND_PROC="$PS p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" ;; *darwin*) - FIND_PROC="$PS -uaxww | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" + FIND_PROC="$PS -uaxww | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" ;; *cygwin*) - FIND_PROC="$PS -e | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" + FIND_PROC="$PS -e | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" ;; *netware*) FIND_PROC= @@ -1765,12 +1765,23 @@ if test "$ac_cv_sizeof_off_t" -eq 0 then AC_MSG_ERROR("MySQL needs a off_t type.") fi + +# do we need #pragma interface/#pragma implementation ? +# yes if it's gcc 2.x, and not icc pretending to be gcc, and not cygwin +AC_MSG_CHECKING(the need for @%:@pragma interface/implementation) +# instead of trying to match SYSTEM_TYPE and CC_VERSION (that doesn't +# follow any standard), we'll use well-defined preprocessor macros: +AC_TRY_CPP([ +#if !defined(__CYGWIN__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ < 3) +#error USE_PRAGMA_IMPLEMENTATION +#endif +],AC_MSG_RESULT(no) ,AC_MSG_RESULT(yes) ; CXXFLAGS="$CXXFLAGS -DUSE_PRAGMA_IMPLEMENTATION") + # This always gives a warning. Ignore it unless you are cross compiling AC_C_BIGENDIAN #---START: Used in for client configure # Check base type of last arg to accept MYSQL_TYPE_ACCEPT - #---END: # Figure out what type of struct rlimit to use with setrlimit MYSQL_TYPE_STRUCT_RLIMIT diff --git a/extra/yassl/mySTL/memory.hpp b/extra/yassl/mySTL/memory.hpp index 729abae7ebc..cc70fbf60d8 100644 --- a/extra/yassl/mySTL/memory.hpp +++ b/extra/yassl/mySTL/memory.hpp @@ -37,16 +37,18 @@ namespace mySTL { -template +template struct auto_ptr_ref { + typedef void (*Deletor)(T*); T* ptr_; Deletor del_; auto_ptr_ref(T* p, Deletor d) : ptr_(p), del_(d) {} }; -template +template class auto_ptr { + typedef void (*Deletor)(T*); T* ptr_; Deletor del_; diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index e49d1ec76cc..45dfb6fa032 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -718,7 +718,7 @@ void processReply(SSL& ssl) mySTL::auto_ptr buffered(ysDelete); for (;;) { - mySTL::auto_ptr tmp = DoProcessReply(ssl, buffered); + mySTL::auto_ptr tmp(DoProcessReply(ssl, buffered)); if (tmp.get()) // had only part of a record's data, call again buffered = tmp; else diff --git a/extra/yassl/taocrypt/include/type_traits.hpp b/extra/yassl/taocrypt/include/type_traits.hpp index caf71f90e11..d03ccae64ed 100644 --- a/extra/yassl/taocrypt/include/type_traits.hpp +++ b/extra/yassl/taocrypt/include/type_traits.hpp @@ -67,7 +67,7 @@ MK_FUNDAMENTAL_TYPE(float) MK_FUNDAMENTAL_TYPE( double) MK_FUNDAMENTAL_TYPE(long double) -#ifdef WORD64_AVAILABLE +#if defined(WORD64_AVAILABLE) && defined(WORD64_IS_DISTINCT_TYPE) MK_FUNDAMENTAL_TYPE(word64) #endif diff --git a/extra/yassl/taocrypt/include/types.hpp b/extra/yassl/taocrypt/include/types.hpp index 0d57022a2d0..9c5d3e4b194 100644 --- a/extra/yassl/taocrypt/include/types.hpp +++ b/extra/yassl/taocrypt/include/types.hpp @@ -45,10 +45,12 @@ typedef unsigned int word32; #if defined(__GNUC__) || defined(__MWERKS__) || defined(_LONGLONG_TYPE) #define WORD64_AVAILABLE + #define WORD64_IS_DISTINCT_TYPE typedef unsigned long long word64; #define W64LIT(x) x##LL #elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) #define WORD64_AVAILABLE + #define WORD64_IS_DISTINCT_TYPE typedef unsigned __int64 word64; #define W64LIT(x) x##ui64 #elif defined(__DECCXX) @@ -66,8 +68,9 @@ typedef unsigned int word32; // TODO: FIXME, add asm multiply for x86_64 on Solaris and remove !__sun -#if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \ - defined(__mips64) || (defined(__x86_64__) && !defined(__sun)) +#if defined(__alpha__) || (defined(__ia64__) && !defined(__INTEL_COMPILER)) || \ + defined(_ARCH_PPC64) || defined(__mips64) || \ + (defined(__x86_64__) && !defined(__sun)) // These platforms have 64-bit CPU registers. Unfortunately most C++ compilers // don't allow any way to access the 64-bit by 64-bit multiply instruction // without using assembly, so in order to use word64 as word, the assembly diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 1780b3050e9..8ff5f47cfa4 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -149,7 +149,8 @@ unsigned long Crop(unsigned long value, unsigned int size) } -#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) +#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) && \ + !(defined(__HP_aCC) && (__HP_aCC <= 35700)) using std::new_handler; using std::set_new_handler; #endif diff --git a/include/config-win.h b/include/config-win.h index b17e4df4e26..f6c72a85a60 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -392,7 +392,6 @@ inline double ulonglong2double(ulonglong value) /* #undef HAVE_CHARSET_armscii8 */ /* #undef HAVE_CHARSET_ascii */ #define HAVE_CHARSET_big5 1 -#define HAVE_CHARSET_cp932 #define HAVE_CHARSET_cp1250 1 /* #undef HAVE_CHARSET_cp1251 */ /* #undef HAVE_CHARSET_cp1256 */ diff --git a/include/m_ctype.h b/include/m_ctype.h index 6f304f4ba43..8bb8e5c76df 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -44,6 +44,9 @@ typedef struct unicase_info_st uint16 sort; } MY_UNICASE_INFO; +extern MY_UNICASE_INFO *my_unicase_default[256]; +extern MY_UNICASE_INFO *my_unicase_turkish[256]; + #define MY_CS_ILSEQ 0 #define MY_CS_ILUNI 0 #define MY_CS_TOOSMALL -1 @@ -164,8 +167,10 @@ typedef struct my_charset_handler_st /* Functions for case and sort convertion */ void (*caseup_str)(struct charset_info_st *, char *); void (*casedn_str)(struct charset_info_st *, char *); - void (*caseup)(struct charset_info_st *, char *, uint); - void (*casedn)(struct charset_info_st *, char *, uint); + uint (*caseup)(struct charset_info_st *, char *src, uint srclen, + char *dst, uint dstlen); + uint (*casedn)(struct charset_info_st *, char *src, uint srclen, + char *dst, uint dstlen); /* Charset dependant snprintf() */ int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt, @@ -216,9 +221,12 @@ typedef struct charset_info_st uint16 **sort_order_big; uint16 *tab_to_uni; MY_UNI_IDX *tab_from_uni; + MY_UNICASE_INFO **caseinfo; uchar *state_map; uchar *ident_map; uint strxfrm_multiply; + uchar caseup_multiply; + uchar casedn_multiply; uint mbminlen; uint mbmaxlen; uint16 min_sort_char; @@ -286,8 +294,10 @@ extern uint my_instr_simple(struct charset_info_st *, /* Functions for 8bit */ extern void my_caseup_str_8bit(CHARSET_INFO *, char *); extern void my_casedn_str_8bit(CHARSET_INFO *, char *); -extern void my_caseup_8bit(CHARSET_INFO *, char *, uint); -extern void my_casedn_8bit(CHARSET_INFO *, char *, uint); +extern uint my_caseup_8bit(CHARSET_INFO *, char *src, uint srclen, + char *dst, uint dstlen); +extern uint my_casedn_8bit(CHARSET_INFO *, char *src, uint srclen, + char *dst, uint dstlen); extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *); @@ -359,8 +369,10 @@ int my_mbcharlen_8bit(CHARSET_INFO *, uint c); /* Functions for multibyte charsets */ extern void my_caseup_str_mb(CHARSET_INFO *, char *); extern void my_casedn_str_mb(CHARSET_INFO *, char *); -extern void my_caseup_mb(CHARSET_INFO *, char *, uint); -extern void my_casedn_mb(CHARSET_INFO *, char *, uint); +extern uint my_caseup_mb(CHARSET_INFO *, char *src, uint srclen, + char *dst, uint dstlen); +extern uint my_casedn_mb(CHARSET_INFO *, char *src, uint srclen, + char *dst, uint dstlen); extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *); int my_wildcmp_mb(CHARSET_INFO *, @@ -441,8 +453,6 @@ my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, uint len); #define my_mbcharlen(s, a) 1 #endif -#define my_caseup(s, a, l) ((s)->cset->caseup((s), (a), (l))) -#define my_casedn(s, a, l) ((s)->cset->casedn((s), (a), (l))) #define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a))) #define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a))) #define my_strntol(s, a, b, c, d, e) ((s)->cset->strntol((s),(a),(b),(c),(d),(e))) diff --git a/include/my_global.h b/include/my_global.h index b4dfb5b7f7d..04d33be38b4 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -43,16 +43,11 @@ #define HAVE_ERRNO_AS_DEFINE #endif /* __CYGWIN__ */ -/* Determine when to use "#pragma interface" */ -#if !defined(__CYGWIN__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ < 3) +/* to make command line shorter we'll define USE_PRAGMA_INTERFACE here */ +#ifdef USE_PRAGMA_IMPLEMENTATION #define USE_PRAGMA_INTERFACE #endif -/* Determine when to use "#pragma implementation" */ -#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ < 3) -#define USE_PRAGMA_IMPLEMENTATION -#endif - #if defined(i386) && !defined(__i386__) #define __i386__ #endif @@ -290,13 +285,7 @@ C_MODE_END # endif #endif /* TIME_WITH_SYS_TIME */ #ifdef HAVE_UNISTD_H -#if defined(HAVE_OPENSSL) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__) && !defined(__APPLE__) -#define crypt unistd_crypt -#endif #include -#ifdef HAVE_OPENSSL -#undef crypt -#endif #endif #if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA) #undef HAVE_ALLOCA @@ -306,13 +295,6 @@ C_MODE_END #include #endif #ifdef HAVE_ATOMIC_ADD -#define __SMP__ -#ifdef HAVE_LINUX_CONFIG_H -#include /* May define CONFIG_SMP */ -#endif -#ifndef CONFIG_SMP -#define CONFIG_SMP -#endif #if defined(__ia64__) #define new my_arg_new #define need_to_restore_new 1 diff --git a/include/my_sys.h b/include/my_sys.h index 62affb31740..ee4312be058 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -181,7 +181,7 @@ extern void my_large_free(gptr ptr, myf my_flags); #endif /* _AIX */ #if defined(__MWERKS__) #undef alloca -#define alloca __alloca +#define alloca _alloca #endif /* __MWERKS__ */ #if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca) #define alloca __builtin_alloca @@ -836,7 +836,10 @@ my_bool my_gethwaddr(uchar *to); #define MAP_NOSYNC 0x0800 #define MAP_FAILED ((void *)-1) #define MS_SYNC 0x0000 + +#ifndef __NETWARE__ #define HAVE_MMAP +#endif int my_getpagesize(void); void *my_mmap(void *, size_t, int, int, int, my_off_t); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 9df26150160..ac5d1c72c72 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -605,7 +605,7 @@ os_file_opendir( lpFindFileData = ut_malloc(sizeof(WIN32_FIND_DATA)); - dir = FindFirstFile(path, lpFindFileData); + dir = FindFirstFile((LPCTSTR) path, lpFindFileData); ut_free(lpFindFileData); @@ -686,15 +686,15 @@ next_file: ret = FindNextFile(dir, lpFindFileData); if (ret) { - ut_a(strlen(lpFindFileData->cFileName) < OS_FILE_MAX_PATH); + ut_a(strlen((char *) lpFindFileData->cFileName) < OS_FILE_MAX_PATH); - if (strcmp(lpFindFileData->cFileName, ".") == 0 - || strcmp(lpFindFileData->cFileName, "..") == 0) { + if (strcmp((char *) lpFindFileData->cFileName, ".") == 0 + || strcmp((char *) lpFindFileData->cFileName, "..") == 0) { goto next_file; } - strcpy(info->name, lpFindFileData->cFileName); + strcpy(info->name, (char *) lpFindFileData->cFileName); info->size = (ib_longlong)(lpFindFileData->nFileSizeLow) + (((ib_longlong)(lpFindFileData->nFileSizeHigh)) << 32); @@ -830,7 +830,7 @@ os_file_create_directory( #ifdef __WIN__ BOOL rcode; - rcode = CreateDirectory(pathname, NULL); + rcode = CreateDirectory((LPCTSTR) pathname, NULL); if (!(rcode != 0 || (GetLastError() == ERROR_ALREADY_EXISTS && !fail_if_exists))) { /* failure */ @@ -914,7 +914,7 @@ try_again: ut_error; } - file = CreateFile(name, + file = CreateFile((LPCTSTR) name, access, FILE_SHARE_READ | FILE_SHARE_WRITE, /* file can be read ansd written also @@ -1053,7 +1053,7 @@ os_file_create_simple_no_error_handling( ut_error; } - file = CreateFile(name, + file = CreateFile((LPCTSTR) name, access, share_mode, NULL, /* default security attributes */ @@ -1200,7 +1200,7 @@ try_again: ut_error; } - file = CreateFile(name, + file = CreateFile((LPCTSTR) name, GENERIC_READ | GENERIC_WRITE, /* read and write access */ share_mode, /* File can be read also by other diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index 18d92af5054..356d7c8c163 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -121,7 +121,7 @@ os_event_create( event->handle = CreateEvent(NULL,/* No security attributes */ TRUE, /* Manual reset */ FALSE, /* Initial state nonsignaled */ - name); + (LPCTSTR) name); if (!event->handle) { fprintf(stderr, "InnoDB: Could not create a Windows event semaphore; Windows error %lu\n", @@ -177,7 +177,7 @@ os_event_create_auto( event->handle = CreateEvent(NULL,/* No security attributes */ FALSE, /* Auto-reset */ FALSE, /* Initial state nonsignaled */ - name); + (LPCTSTR) name); if (!event->handle) { fprintf(stderr, @@ -440,7 +440,7 @@ os_mutex_create( mutex = CreateMutex(NULL, /* No security attributes */ FALSE, /* Initial state: no owner */ - name); + (LPCTSTR) name); ut_a(mutex); #else os_fast_mutex_t* mutex; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index c87728ab783..753657951ee 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1738,7 +1738,7 @@ myodbc_remove_escape(MYSQL *mysql,char *name) /* Default number of rows fetched per one COM_FETCH command. */ -#define DEFAULT_PREFETCH_ROWS 1UL +#define DEFAULT_PREFETCH_ROWS (ulong) 1 /* These functions are called by function pointer MYSQL_STMT::read_row_func. @@ -2809,11 +2809,14 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, { switch (attr_type) { case STMT_ATTR_UPDATE_MAX_LENGTH: - *(unsigned long *) value= stmt->update_max_length; + *(ulong*) value= stmt->update_max_length; break; case STMT_ATTR_CURSOR_TYPE: - *(unsigned long *) value= stmt->flags; + *(ulong*) value= stmt->flags; break; + case STMT_ATTR_PREFETCH_ROWS: + *(ulong*) value= stmt->prefetch_rows; + break; default: return TRUE; } diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 38f3ebaa20a..9e003a18dac 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3871,6 +3871,14 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) if (!share->state.create_time) share->state.create_time=share->state.check_time; } + /* + When tables are locked we haven't synched the share state and the + real state for a while so we better do it here before synching + the share state to disk. Only when table is write locked is it + necessary to perform this synch. + */ + if (info->lock_type == F_WRLCK) + share->state.state= *info->state; if (mi_state_info_write(share->kfile,&share->state,1+2)) goto err; share->changed=0; diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 12b03e65baa..47332b02a72 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -667,7 +667,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { tmp_keydef.keysegs=1; tmp_keydef.flag= HA_UNIQUE_CHECK; - tmp_keydef.block_length= myisam_block_size; + tmp_keydef.block_length= (uint16)myisam_block_size; tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer; tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; tmp_keyseg.type= MI_UNIQUE_HASH_TYPE; diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 9fb673483ea..ae50900a190 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -107,7 +107,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, } if (keyseg->flag & HA_SPACE_PACK) { - end=pos+length; + end= pos + length; if (type != HA_KEYTYPE_NUM) { while (end > pos && end[-1] == ' ') diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c index 06408f57a3f..4d770258a72 100644 --- a/myisam/mi_rnext_same.c +++ b/myisam/mi_rnext_same.c @@ -68,8 +68,8 @@ int mi_rnext_same(MI_INFO *info, byte *buf) info->lastkey_length,SEARCH_BIGGER, info->s->state.key_root[inx]))) break; - if (ha_key_cmp(keyinfo->seg,info->lastkey2,info->lastkey, - info->last_rkey_length, SEARCH_FIND, ¬_used)) + if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2, + info->last_rkey_length, SEARCH_FIND, ¬_used)) { error=1; my_errno=HA_ERR_END_OF_FILE; diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index aa6cd98ac8e..5727c699469 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -471,20 +471,25 @@ static void update_record(char *record) ptr=blob_key; memcpy_fixed(pos+4,&ptr,sizeof(char*)); /* Store pointer to new key */ if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) - my_casedn(default_charset_info,blob_key,length); + default_charset_info->cset->casedn(default_charset_info, + blob_key, length, blob_key, length); pos+=recinfo[1].length; } else if (recinfo[1].type == FIELD_VARCHAR) { uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1); uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos); - my_casedn(default_charset_info,pos+pack_length,length); + default_charset_info->cset->casedn(default_charset_info, + pos + pack_length, length, + pos + pack_length, length); pos+=recinfo[1].length; } else { if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM) - my_casedn(default_charset_info,pos,keyinfo[0].seg[0].length); + default_charset_info->cset->casedn(default_charset_info, + pos, keyinfo[0].seg[0].length, + pos, keyinfo[0].seg[0].length); pos+=recinfo[1].length; } diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 9963074daf5..3a59a060778 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -35,7 +35,8 @@ testdir = $(benchdir_root)/mysql-test EXTRA_SCRIPTS = mysql-test-run.sh mysql-test-run.pl install_test_db.sh valgrind.supp EXTRA_DIST = $(EXTRA_SCRIPTS) test_SCRIPTS = mysql-test-run install_test_db -test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem +test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem \ + std_data/server-cert.pem std_data/server-key.pem CLEANFILES = $(test_SCRIPTS) $(test_DATA) INCLUDES = -I$(srcdir)/../include -I../include -I.. @@ -48,6 +49,7 @@ dist-hook: mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \ $(distdir)/std_data $(distdir)/lib $(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t + $(INSTALL_DATA) $(srcdir)/t/*.sql $(distdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include @@ -69,6 +71,7 @@ install-data-local: $(DESTDIR)$(testdir)/lib $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) $(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t + $(INSTALL_DATA) $(srcdir)/t/*.sql $(DESTDIR)$(testdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.disabled $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t diff --git a/mysql-test/include/ps_modify.inc b/mysql-test/include/ps_modify.inc index 04b9734240b..633c317f4b2 100644 --- a/mysql-test/include/ps_modify.inc +++ b/mysql-test/include/ps_modify.inc @@ -174,11 +174,8 @@ where a=2 limit 1'; execute stmt1 ; select a,b from t1 where b = 'bla' ; -# currently (May 2004, Version 4.1) it is impossible --- error 1064 -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; --disable_query_log select '------ insert tests ------' as test_sequence ; diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc index 9a413bff2f3..63504a0fa2b 100644 --- a/mysql-test/include/ps_query.inc +++ b/mysql-test/include/ps_query.inc @@ -300,10 +300,8 @@ set @arg00=1; prepare stmt1 from ' select a,b from t1 order by a limit 1 '; execute stmt1 ; -# currently (May 2004, Version 4.1) it is impossible --- error 1064 -prepare stmt1 from ' select a,b from t1 -limit ? '; +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; ##### parameter used in many places set @arg00='b' ; diff --git a/mysql-test/include/show_msg.inc b/mysql-test/include/show_msg.inc new file mode 100755 index 00000000000..5a29541edcf --- /dev/null +++ b/mysql-test/include/show_msg.inc @@ -0,0 +1,19 @@ +#### include/show_msg.inc +# +# This file writes the value set in @message into the +# a protocol file as part of executing a test sequence +# +# Usage: +# Add the following to any *.test file: +# : +# set @message="This is a message example"; +# --source include/show_msg.inc +# : +# + +--disable_query_log +SET @utf8_message = CONVERT(@message using utf8); +select @utf8_message as "" +union +select repeat(CONVERT('-' using utf8),char_length(@utf8_message)); +--enable_query_log diff --git a/mysql-test/include/show_msg80.inc b/mysql-test/include/show_msg80.inc new file mode 100755 index 00000000000..d9a59c5517a --- /dev/null +++ b/mysql-test/include/show_msg80.inc @@ -0,0 +1,23 @@ +#### include/show_msg80.inc +# +# This file writes the value set in @message into the +# a protocol file as part of executing a test sequence +# with a dash line that is fixed on 80 characters. +# This can be used in the case of long messages, +# multi line messages that exceed 80 or if an 80 char +# line is desired for short messages. +# +# Usage: +# Add the following to any *.test file: +# : +# set @message="This is a message example"; +# --source include/show_msg80.inc +# : +# + +--disable_query_log +SET @utf8_message = CONVERT(@message using utf8); +select @utf8_message as "" +union +select repeat(CONVERT('-' using utf8),80); +--enable_query_log diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 5f80864d1f7..efa1b3bec21 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -25,7 +25,7 @@ sub mtr_full_hostname () { if ( $hostname !~ /\./ ) { my $address= gethostbyname($hostname) - or die "Couldn't resolve $hostname : $!"; + or mtr_error("Couldn't resolve $hostname : $!"); my $fullname= gethostbyaddr($address, AF_INET); $hostname= $fullname if $fullname; } diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 78758e54aa4..7bca422773c 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -17,6 +17,7 @@ sub mtr_spawn ($$$$$$); sub mtr_stop_mysqld_servers ($); sub mtr_kill_leftovers (); sub mtr_record_dead_children (); +sub mtr_exit ($); sub sleep_until_file_created ($$$); # static in C @@ -784,4 +785,17 @@ sub sleep_until_file_created ($$$) { } +############################################################################## +# +# When we exit, we kill off all children +# +############################################################################## + +sub mtr_exit ($) { + my $code= shift; + local $SIG{HUP} = 'IGNORE'; + kill('HUP', -$$); + exit($code); +} + 1; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index cb41549422f..a258d139bb1 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -268,7 +268,8 @@ sub mtr_warning (@) { } sub mtr_error (@) { - die "mysql-test-run: *** ERROR: ",join(" ", @_),"\n"; + print STDERR "mysql-test-run: *** ERROR: ",join(" ", @_),"\n"; + mtr_exit(1); } sub mtr_debug (@) { diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 52ffff088b5..7b57108466d 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -398,7 +398,7 @@ sub main () { } } - exit(0); + mtr_exit(0); } ############################################################################## @@ -568,7 +568,9 @@ sub command_line_setup () { $opt_vardir= "$glob_mysql_test_dir/var"; } - if ( $opt_vardir !~ m,^/, ) + # We make the path absolute, as the server will do a chdir() before usage + unless ( $opt_vardir =~ m,^/, or + ($glob_win32 and $opt_vardir =~ m,^[a-z]:/,i) ) { # Make absolute path, relative test dir $opt_vardir= "$glob_mysql_test_dir/$opt_vardir"; @@ -1292,9 +1294,9 @@ sub install_db ($$) { mtr_report("Installing \u$type Databases"); open(IN, $init_db_sql) - or error("Can't open $init_db_sql: $!"); + or mtr_error("Can't open $init_db_sql: $!"); open(OUT, ">", $init_db_sql_tmp) - or error("Can't write to $init_db_sql_tmp: $!"); + or mtr_error("Can't write to $init_db_sql_tmp: $!"); while () { chomp; @@ -1568,7 +1570,7 @@ sub report_failure_and_restart ($) { { stop_masters_slaves(); } - exit(1); + mtr_exit(1); } # FIXME always terminate on failure?! @@ -2267,5 +2269,5 @@ Options not yet described, or that I want to look into more with-openssl HERE - exit(1); + mtr_exit(1); } diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 45b1e948ac2..bdd92e7941b 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -887,7 +887,7 @@ report_stats () { found_error=0 # Find errors - for i in "^Warning:" "^Error:" "^==.* at 0x" + for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" do if $GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings then diff --git a/mysql-test/r/analyze.result b/mysql-test/r/analyze.result new file mode 100644 index 00000000000..0b44a502b13 --- /dev/null +++ b/mysql-test/r/analyze.result @@ -0,0 +1,32 @@ +create table t1 (a bigint); +lock tables t1 write; +insert into t1 values(0); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +unlock tables; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +create table t1 (a bigint); +insert into t1 values(0); +lock tables t1 write; +delete from t1; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +unlock tables; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +create table t1 (a bigint); +insert into t1 values(0); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 4587c675150..61a42b004a9 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -355,3 +355,42 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)); +insert into t1 (b) values (1); +replace into t1 (b) values (2), (1), (3); +select * from t1; +a b +3 1 +2 2 +4 3 +truncate table t1; +insert into t1 (b) values (1); +replace into t1 (b) values (2); +replace into t1 (b) values (1); +replace into t1 (b) values (3); +select * from t1; +a b +3 1 +2 2 +4 3 +drop table t1; +create table t1 (rowid int not null auto_increment, val int not null,primary +key (rowid), unique(val)); +replace into t1 (val) values ('1'),('2'); +replace into t1 (val) values ('1'),('2'); +insert into t1 (val) values ('1'),('2'); +ERROR 23000: Duplicate entry '1' for key 2 +select * from t1; +rowid val +3 1 +4 2 +drop table t1; +create table t1 (a int not null auto_increment primary key, val int); +insert into t1 (val) values (1); +update t1 set a=2 where a=1; +insert into t1 (val) values (1); +select * from t1; +a val +2 1 +3 1 +drop table t1; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index ae09b8d730c..d622127e8f0 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -434,7 +434,7 @@ d date YES NULL e varchar(1) NO f datetime YES NULL g time YES NULL -h varbinary(23) NO +h longblob NO dd time YES NULL select * from t2; a b c d e f g h dd @@ -513,9 +513,9 @@ drop database mysqltest; select database(); database() NULL -select database(); -database() -NULL +select database(), user(); +database() user() +NULL mysqltest_1@localhost use test; create table t1 (a int, index `primary` (a)); ERROR 42000: Incorrect index name 'primary' @@ -579,7 +579,6 @@ select * from t2; b 1 drop table t1,t2; -use test; create table t1 (a int); create table t1 select * from t1; ERROR HY000: You can't specify target table 't1' for update in FROM clause @@ -597,3 +596,9 @@ ERROR 42000: Incorrect database name 'xyz' create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2; +create database mysqltest; +use mysqltest; +drop database mysqltest; +create table test.t1 like x; +ERROR 42000: Incorrect database name 'NULL' +drop table if exists test.t1; diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result index 62936b84caf..7b2ca7d7e0e 100644 --- a/mysql-test/r/ctype_cp1250_ch.result +++ b/mysql-test/r/ctype_cp1250_ch.result @@ -7,3 +7,15 @@ SELECT a, length(a), a='', a=' ', a=' ' FROM t1; a length(a) a='' a=' ' a=' ' 0 1 1 1 DROP TABLE t1; +CREATE TABLE t1 ( +popisek varchar(30) collate cp1250_general_ci NOT NULL default '', +PRIMARY KEY (`popisek`) +); +INSERT INTO t1 VALUES ('2005-01-1'); +SELECT * FROM t1 WHERE popisek = '2005-01-1'; +popisek +2005-01-1 +SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; +popisek +2005-01-1 +drop table t1; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index c6e803904a3..3803dd932d7 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -2396,3 +2396,27 @@ utf8_unicode_ci 6109 utf8_unicode_ci 61 utf8_unicode_ci 6120 drop table t1; +CREATE TABLE t1 (id int, a varchar(30) character set utf8); +INSERT INTO t1 VALUES (1, _ucs2 0x01310069), (2, _ucs2 0x01310131); +INSERT INTO t1 VALUES (3, _ucs2 0x00690069), (4, _ucs2 0x01300049); +INSERT INTO t1 VALUES (5, _ucs2 0x01300130), (6, _ucs2 0x00490049); +SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu +FROM t1 ORDER BY id; +a la l ll u lu +ıi 3 ıi 3 II 2 +ıı 4 ıı 4 II 2 +ii 2 ii 2 II 2 +İI 3 ii 2 İI 3 +İİ 4 ii 2 İİ 4 +II 2 ii 2 II 2 +ALTER TABLE t1 MODIFY a VARCHAR(30) character set utf8 collate utf8_turkish_ci; +SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu +FROM t1 ORDER BY id; +a la l ll u lu +ıi 3 ıi 3 Iİ 3 +ıı 4 ıı 4 II 2 +ii 2 ii 2 İİ 4 +İI 3 iı 3 İI 3 +İİ 4 ii 2 İİ 4 +II 2 ıı 4 II 2 +DROP TABLE t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 4be9139f20b..30f18c09dec 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -891,3 +891,17 @@ string create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1; +create table t1 ( +id int not null, +city varchar(20) not null, +key (city(7),id) +) character set=utf8; +insert into t1 values (1,'Durban North'); +insert into t1 values (2,'Durban'); +select * from t1 where city = 'Durban'; +id city +2 Durban +select * from t1 where city = 'Durban '; +id city +2 Durban +drop table t1; diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 411cd52b4ca..ddfeeac77b5 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -1,4 +1,4 @@ -drop table if exists t1,t11,t12,t2; +drop table if exists t1,t2,t3,t11,t12; CREATE TABLE t1 (a tinyint(3), b tinyint(5)); INSERT INTO t1 VALUES (1,1); INSERT LOW_PRIORITY INTO t1 VALUES (1,2); @@ -172,3 +172,23 @@ a 0 2 DROP TABLE t1; +CREATE TABLE t1 (a int not null,b int not null); +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b)); +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b)); +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +a b a b a b +1 1 1 1 1 1 +2 1 2 2 2 1 +1 3 1 1 1 3 +explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index +1 SIMPLE t3 index PRIMARY PRIMARY 8 NULL 3 Using where; Using index +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +select * from t3; +a b +drop table t1,t2,t3; diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 955ea5b8673..3ad2b73f1d3 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -464,3 +464,11 @@ SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; html prod 1 0.0000 drop table t1; +create table t1 (id int, dsc varchar(50)); +insert into t1 values (1, "line number one"), (2, "line number two"), (3, "line number three"); +select distinct id, IFNULL(dsc, '-') from t1; +id IFNULL(dsc, '-') +1 line number one +2 line number two +3 line number three +drop table t1; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 09ff3fc5a6e..10afb61ba1d 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -343,18 +343,6 @@ GROUP_CONCAT(b ORDER BY b) First Row Second Row DROP TABLE t1; -CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; -INSERT INTO t1 VALUES (1),(2),(3); -CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a), -CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1; -INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2); -SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz; -a_id b_list -1 1,2,3 -2 4,5 -3 NULL -DROP TABLE t2; -DROP TABLE t1; CREATE TABLE t1 (A_ID INT NOT NULL,A_DESC CHAR(3) NOT NULL,PRIMARY KEY (A_ID)); INSERT INTO t1 VALUES (1,'ABC'), (2,'EFG'), (3,'HIJ'); CREATE TABLE t2 (A_ID INT NOT NULL,B_DESC CHAR(3) NOT NULL,PRIMARY KEY (A_ID,B_DESC)); @@ -462,6 +450,49 @@ SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; gc NULL DROP TABLE t1; +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2); +select b x, (select group_concat(x) from t2) from t2; +x (select group_concat(x) from t2) +1 1,1 +2 2,2 +drop table t2; +create table t1 (d int not null auto_increment,primary key(d), a int, b int, c int); +insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3); +select d,a,b from t1 order by a; +d a b +1 1 3 +2 1 4 +3 1 2 +5 1 1 +6 1 2 +4 2 7 +7 2 3 +8 2 3 +explain select a, group_concat(b) from t1 group by a with rollup; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using filesort +select a, group_concat(b) from t1 group by a with rollup; +a group_concat(b) +1 3,4,2,1,2 +2 7,3,3 +NULL 3,4,2,1,2,7,3,3 +select a, group_concat(distinct b) from t1 group by a with rollup; +a group_concat(distinct b) +1 3,4,2,1 +2 7,3 +NULL 3,4,2,1,7 +select a, group_concat(b order by b) from t1 group by a with rollup; +a group_concat(b order by b) +1 1,2,2,3,4 +2 3,3,7 +NULL 1,2,2,3,3,3,4,7 +select a, group_concat(distinct b order by b) from t1 group by a with rollup; +a group_concat(distinct b order by b) +1 1,2,3,4 +2 3,7 +NULL 1,2,3,4,7 +drop table t1; create table t1 (a char(3), b char(20), primary key (a, b)); insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English'); select group_concat(a) from t1 group by b; @@ -469,10 +500,3 @@ group_concat(a) ABW ABW drop table t1; -create table r2 (a int, b int); -insert into r2 values (1,1), (2,2); -select b x, (select group_concat(x) from r2) from r2; -x (select group_concat(x) from r2) -1 1,1 -2 2,2 -drop table r2; diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 0798a034c3e..c7674c57c8d 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -130,3 +130,19 @@ Warnings: Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)` select rand(rand); ERROR 42S22: Unknown column 'rand' in 'field list' +create table t1 (col1 int, col2 decimal(60,30)); +insert into t1 values(1,1234567890.12345); +select format(col2,7) from t1; +format(col2,7) +1,234,567,890.1234500 +select format(col2,8) from t1; +format(col2,8) +1,234,567,890.12345000 +insert into t1 values(7,1234567890123456.12345); +select format(col2,6) from t1 where col1=7; +format(col2,6) +1,234,567,890,123,456.123450 +drop table t1; +select round(150, 2); +round(150, 2) +150.00 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 4293ef5bd85..cb51da75368 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -688,3 +688,21 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select timestamp_diff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestamp_diff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2` +select last_day('2005-00-00'); +last_day('2005-00-00') +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '2005-00-00' +select last_day('2005-00-01'); +last_day('2005-00-01') +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '2005-00-01' +select last_day('2005-01-00'); +last_day('2005-01-00') +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '2005-01-00' +select time_format('100:00:00', '%H %k %h %I %l'); +time_format('100:00:00', '%H %k %h %I %l') +100 100 04 04 4 diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 88b43c7ce35..937ed401f40 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -711,3 +711,14 @@ select min(b) from t1; min(b) 3000000000 drop table t1; +CREATE TABLE t1 (id int PRIMARY KEY, user_id int, hostname longtext); +INSERT INTO t1 VALUES +(1, 7, 'cache-dtc-af05.proxy.aol.com'), +(2, 3, 'what.ever.com'), +(3, 7, 'cache-dtc-af05.proxy.aol.com'), +(4, 7, 'cache-dtc-af05.proxy.aol.com'); +SELECT hostname, COUNT(DISTINCT user_id) as no FROM t1 +WHERE hostname LIKE '%aol%' + GROUP BY hostname; +hostname no +cache-dtc-af05.proxy.aol.com 1 diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index d2750fd5a43..22304c4a93d 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -696,3 +696,8 @@ drop table t1; create table t1 (a int not null, b int not null auto_increment, primary key(a, b)) engine=heap; ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key +create table t1 (c char(255), primary key(c(90))); +insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); +insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); +ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1 +drop table t1; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 872d1f6ea7f..38eb1d6a3ae 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS t0,t1,t2; show variables where variable_name like "skip_show_database"; Variable_name Value skip_show_database OFF @@ -752,3 +753,73 @@ SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHE table_schema count(*) information_schema 15 mysql 17 +create database mysqltest; +create table mysqltest.t1 (f1 int, f2 int); +create table mysqltest.t2 (f1 int); +grant select (f1) on mysqltest.t1 to user1@localhost; +grant select on mysqltest.t2 to user2@localhost; +grant select on mysqltest.* to user3@localhost; +grant select on *.* to user4@localhost; +select * from information_schema.column_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +'user1'@'localhost' NULL mysqltest t1 f1 SELECT NO +select * from information_schema.table_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.schema_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.user_privileges; +GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE +'user1'@'localhost' NULL USAGE NO +show grants; +Grants for user1@localhost +GRANT USAGE ON *.* TO 'user1'@'localhost' +GRANT SELECT (f1) ON `mysqltest`.`t1` TO 'user1'@'localhost' +select * from information_schema.column_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.table_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +'user2'@'localhost' NULL mysqltest t2 SELECT NO +select * from information_schema.schema_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.user_privileges; +GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE +'user2'@'localhost' NULL USAGE NO +show grants; +Grants for user2@localhost +GRANT USAGE ON *.* TO 'user2'@'localhost' +GRANT SELECT ON `mysqltest`.`t2` TO 'user2'@'localhost' +select * from information_schema.column_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.table_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +select * from information_schema.schema_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE +'user3'@'localhost' NULL mysqltest SELECT NO +select * from information_schema.user_privileges; +GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE +'user3'@'localhost' NULL USAGE NO +show grants; +Grants for user3@localhost +GRANT USAGE ON *.* TO 'user3'@'localhost' +GRANT SELECT ON `mysqltest`.* TO 'user3'@'localhost' +select * from information_schema.column_privileges where grantee like '%user%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +'user1'@'localhost' NULL mysqltest t1 f1 SELECT NO +select * from information_schema.table_privileges where grantee like '%user%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +'user2'@'localhost' NULL mysqltest t2 SELECT NO +select * from information_schema.schema_privileges where grantee like '%user%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE +'user3'@'localhost' NULL mysqltest SELECT NO +select * from information_schema.user_privileges where grantee like '%user%'; +GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE +'user1'@'localhost' NULL USAGE NO +'user2'@'localhost' NULL USAGE NO +'user3'@'localhost' NULL USAGE NO +'user4'@'localhost' NULL SELECT NO +show grants; +Grants for user4@localhost +GRANT SELECT ON *.* TO 'user4'@'localhost' +drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost; +use test; +drop database mysqltest; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 424543ba4b9..31480e32c16 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -931,7 +931,6 @@ a 1 2 truncate table t1; -truncate table t1; insert into t1 values(1),(2); delete from t1; select * from t1; @@ -1451,16 +1450,22 @@ test.t3 NULL test.t4 NULL Warnings: Error 1146 Table 'test.t4' doesn't exist -checksum table t1, t2, t3; +checksum table t1, t2, t3, t4; Table Checksum test.t1 2948697075 test.t2 1157260244 test.t3 1157260244 -checksum table t1, t2, t3 extended; +test.t4 NULL +Warnings: +Error 1146 Table 'test.t4' doesn't exist +checksum table t1, t2, t3, t4 extended; Table Checksum test.t1 3092701434 test.t2 1157260244 test.t3 1157260244 +test.t4 NULL +Warnings: +Error 1146 Table 'test.t4' doesn't exist drop table t1,t2,t3; create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb; insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt'); @@ -1633,14 +1638,14 @@ t2 CREATE TABLE `t2` ( drop table t2, t1; show status like "binlog_cache_use"; Variable_name Value -Binlog_cache_use 154 +Binlog_cache_use 153 show status like "binlog_cache_disk_use"; Variable_name Value Binlog_cache_disk_use 0 create table t1 (a int) engine=innodb; show status like "binlog_cache_use"; Variable_name Value -Binlog_cache_use 155 +Binlog_cache_use 154 show status like "binlog_cache_disk_use"; Variable_name Value Binlog_cache_disk_use 1 @@ -1649,11 +1654,51 @@ delete from t1; commit; show status like "binlog_cache_use"; Variable_name Value -Binlog_cache_use 156 +Binlog_cache_use 155 show status like "binlog_cache_disk_use"; Variable_name Value Binlog_cache_disk_use 1 drop table t1; +create table t1 (c char(10), index (c,c)) engine=innodb; +ERROR 42S21: Duplicate column name 'c' +create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb; +ERROR 42S21: Duplicate column name 'c1' +create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb; +ERROR 42S21: Duplicate column name 'c1' +create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb; +ERROR 42S21: Duplicate column name 'c1' +create table t1 (c1 char(10), c2 char(10)) engine=innodb; +alter table t1 add key (c1,c1); +ERROR 42S21: Duplicate column name 'c1' +alter table t1 add key (c2,c1,c1); +ERROR 42S21: Duplicate column name 'c1' +alter table t1 add key (c1,c2,c1); +ERROR 42S21: Duplicate column name 'c1' +alter table t1 add key (c1,c1,c2); +ERROR 42S21: Duplicate column name 'c1' +drop table t1; +create table t1(a int(1) , b int(1)) engine=innodb; +insert into t1 values ('1111', '3333'); +select distinct concat(a, b) from t1; +concat(a, b) +11113333 +drop table t1; +CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; +SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); +ERROR HY000: The used table type doesn't support FULLTEXT indexes +DROP TABLE t1; +CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a), +CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2); +SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz; +a_id b_list +1 1,2,3 +2 4,5 +3 NULL +DROP TABLE t2; +DROP TABLE t1; create table t1 (x bigint unsigned not null primary key) engine=innodb; insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1); select * from t1; @@ -1688,24 +1733,6 @@ select count(*) from t1 where x = 18446744073709551601; count(*) 1 drop table t1; -create table t1 (c char(10), index (c,c)) engine=innodb; -ERROR 42S21: Duplicate column name 'c' -create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb; -ERROR 42S21: Duplicate column name 'c1' -create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb; -ERROR 42S21: Duplicate column name 'c1' -create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb; -ERROR 42S21: Duplicate column name 'c1' -create table t1 (c1 char(10), c2 char(10)) engine=innodb; -alter table t1 add key (c1,c1); -ERROR 42S21: Duplicate column name 'c1' -alter table t1 add key (c2,c1,c1); -ERROR 42S21: Duplicate column name 'c1' -alter table t1 add key (c1,c2,c1); -ERROR 42S21: Duplicate column name 'c1' -alter table t1 add key (c1,c1,c2); -ERROR 42S21: Duplicate column name 'c1' -drop table t1; show status like "Innodb_buffer_pool_pages_total"; Variable_name Value Innodb_buffer_pool_pages_total 512 @@ -1717,7 +1744,7 @@ Variable_name Value Innodb_rows_deleted 2070 show status like "Innodb_rows_inserted"; Variable_name Value -Innodb_rows_inserted 31709 +Innodb_rows_inserted 31718 show status like "Innodb_rows_updated"; Variable_name Value Innodb_rows_updated 29530 @@ -2391,13 +2418,51 @@ drop table t1; set storage_engine=MyISAM; create table t1 (v varchar(16384)) engine=innodb; drop table t1; -create table t1(a int(1) , b int(1)) engine=innodb; -insert into t1 values ('1111', '3333'); -select distinct concat(a, b) from t1; -concat(a, b) -11113333 +create table t1 (a char(1), b char(1), key(a, b)) engine=innodb; +insert into t1 values ('8', '6'), ('4', '7'); +select min(a) from t1; +min(a) +4 +select min(b) from t1 where a='8'; +min(b) +6 +drop table t1; +CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb; +insert into t1 (b) values (1); +replace into t1 (b) values (2), (1), (3); +select * from t1; +a b +3 1 +2 2 +4 3 +truncate table t1; +insert into t1 (b) values (1); +replace into t1 (b) values (2); +replace into t1 (b) values (1); +replace into t1 (b) values (3); +select * from t1; +a b +3 1 +2 2 +4 3 +drop table t1; +create table t1 (rowid int not null auto_increment, val int not null,primary +key (rowid), unique(val)) engine=innodb; +replace into t1 (val) values ('1'),('2'); +replace into t1 (val) values ('1'),('2'); +insert into t1 (val) values ('1'),('2'); +ERROR 23000: Duplicate entry '1' for key 2 +select * from t1; +rowid val +3 1 +4 2 +drop table t1; +create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB; +insert into t1 (val) values (1); +update t1 set a=2 where a=1; +insert into t1 (val) values (1); +ERROR 23000: Duplicate entry '2' for key 1 +select * from t1; +a val +2 1 drop table t1; -CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; -SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); -ERROR HY000: The used table type doesn't support FULLTEXT indexes -DROP TABLE t1; diff --git a/mysql-test/r/innodb_handler.result b/mysql-test/r/innodb_handler.result index 7f4960ffa35..7e853a55e37 100644 --- a/mysql-test/r/innodb_handler.result +++ b/mysql-test/r/innodb_handler.result @@ -132,6 +132,22 @@ a b handler t2 read last; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 handler t2 close; +handler t1 open; +handler t1 read a next; +a b +14 aaa +handler t1 read a next; +a b +15 bbb +handler t1 close; +handler t1 open; +handler t1 read a prev; +a b +22 iii +handler t1 read a prev; +a b +21 hhh +handler t1 close; handler t1 open as t2; handler t2 read first; a b diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 98e8851bb7e..3ad8571aadd 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -329,3 +329,28 @@ ERROR 42S21: Duplicate column name 'c1' alter table t1 add key (c1,c1,c2); ERROR 42S21: Duplicate column name 'c1' drop table t1; +create table t1 (a varchar(10), b varchar(10), key(a(10),b(10))); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) default NULL, + `b` varchar(10) default NULL, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify b varchar(20); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(10) default NULL, + `b` varchar(20) default NULL, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify a varchar(20); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(20) default NULL, + `b` varchar(20) default NULL, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 51e56c21a07..87e2fca970b 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -148,3 +148,17 @@ a'b a"b select 'aaa\\','aa''a',"aa""a"; aaa\ aa'a aa"a aaa\ aa'a aa"a +SET @message = 'Here comes a message'; + +Here comes a message +-------------------- +SET @message = USER(); + +root@localhost +-------------- +SET @message = 'Here comes a very very long message that is longer then 80 characters +on multiple lines'; + +Here comes a very very long message that is longer then 80 characters +on multiple lines +-------------------------------------------------------------------------------- diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result index 5ba2bc80484..c37a42d3fa7 100644 --- a/mysql-test/r/olap.result +++ b/mysql-test/r/olap.result @@ -88,7 +88,7 @@ TV NULL NULL 600 NULL NULL NULL 7785 explain extended select product, country_id , year, sum(profit) from t1 group by product, country_id, year with rollup; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using filesort Warnings: Note 1003 select `test`.`t1`.`product` AS `product`,`test`.`t1`.`country_id` AS `country_id`,`test`.`t1`.`year` AS `year`,sum(`test`.`t1`.`profit`) AS `sum(profit)` from `test`.`t1` group by `test`.`t1`.`product`,`test`.`t1`.`country_id`,`test`.`t1`.`year` with rollup select product, country_id , sum(profit) from t1 group by product desc, country_id with rollup; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 8371437d664..496d566a5ee 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -634,3 +634,44 @@ id 3 deallocate prepare stmt; drop table t1, t2; +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +a +1 +select * from t1 limit 0, 1; +a +1 +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +a +4 +5 +select * from t1 limit 3, 2; +a +4 +5 +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +a +1 +2 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +a +10 +1 +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; +a +10 +10 +drop table t1; +deallocate prepare stmt; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 18bc76789b1..54c35873201 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -471,13 +471,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 14 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort @@ -487,13 +487,13 @@ execute stmt1 using @arg00; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 5 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 5 Y 0 31 8 def possible_keys 253 4096 7 Y 0 31 8 def key 253 64 7 Y 0 31 8 def key_len 253 4096 1 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 27 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index d6c3d0e78d5..3df9b6dcb6e 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -444,9 +444,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1151,13 +1152,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -1381,10 +1382,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 1bbc1091393..851178e2aee 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -444,9 +444,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1151,13 +1152,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -1364,10 +1365,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 009b642d7e7..60675a72bdc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -445,9 +445,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1152,13 +1153,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -1365,10 +1366,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 5bd18078213..a177290daa4 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -487,9 +487,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1194,13 +1195,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -1407,10 +1408,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; @@ -3500,9 +3499,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -4207,13 +4207,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -4420,10 +4420,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 753def70dc0..92399c3b3b9 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -444,9 +444,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +1 one set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1151,13 +1152,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 @@ -1364,10 +1365,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index a6da6e169db..c7dabc2016d 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -444,9 +444,10 @@ limit 1 '; execute stmt1 ; a b 1 one -prepare stmt1 from ' select a,b from t1 -limit ? '; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 2 +prepare stmt1 from ' select a,b from t1 limit ? '; +execute stmt1 using @arg00; +a b +3 three set @arg00='b' ; set @arg01=0 ; set @arg02=2 ; @@ -1151,13 +1152,13 @@ execute stmt1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 -def table 253 64 2 N 1 31 8 -def type 253 10 3 N 1 31 8 +def table 253 64 2 Y 0 31 8 +def type 253 10 3 Y 0 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32929 0 63 +def rows 8 10 1 Y 32928 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -1364,10 +1365,8 @@ execute stmt1 ; select a,b from t1 where b = 'bla' ; a b 2 bla -prepare stmt1 from 'update t1 set b=''bla'' -where a=2 -limit ?'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 3 +prepare stmt1 from 'update t1 set b=''bla'' where a=2 limit ?'; +execute stmt1 using @arg00; test_sequence ------ insert tests ------ delete from t1 ; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index eaed7719673..1c0321ac658 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2682,3 +2682,20 @@ AND FK_firma_id = 2; COUNT(*) 0 drop table t1; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT INTO t2 VALUES (2), (4), (6); +SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; +a +2 +4 +EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where +EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +DROP TABLE t1,t2; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 1dc97124a07..b6ba737a8ba 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -672,3 +672,17 @@ select default(t30.s1) from t30; end| drop procedure bug10969| drop table t1| +prepare stmt from "select 1"; +create procedure p() deallocate prepare stmt; +ERROR 0A000: DEALLOCATE is not allowed in stored procedures +create function f() returns int begin deallocate prepare stmt; +ERROR 0A000: DEALLOCATE is not allowed in stored procedures +create procedure p() prepare stmt from "select 1"; +ERROR 0A000: PREPARE is not allowed in stored procedures +create function f() returns int begin prepare stmt from "select 1"; +ERROR 0A000: PREPARE is not allowed in stored procedures +create procedure p() execute stmt; +ERROR 0A000: EXECUTE is not allowed in stored procedures +create function f() returns int begin execute stmt; +ERROR 0A000: EXECUTE is not allowed in stored procedures +deallocate prepare stmt; diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result index a081e520496..a9d50e6e697 100644 --- a/mysql-test/r/sp-threads.result +++ b/mysql-test/r/sp-threads.result @@ -40,3 +40,18 @@ Id User Host db Command Time State Info unlock tables; drop procedure bug9486; drop table t1, t2; +drop procedure if exists bug11158; +create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; +create table t1 (id int, j int); +insert into t1 values (1, 1), (2, 2); +create table t2 (id int); +insert into t2 values (1); +call bug11158(); +select * from t1; +id j +2 2 +lock tables t2 read; +call bug11158(); +unlock tables; +drop procedure bug11158; +drop table t1, t2; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1741070669f..bf6a4dbf68c 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3134,4 +3134,44 @@ x x 3 drop procedure bug10961| +DROP PROCEDURE IF EXISTS bug6866| +DROP VIEW IF EXISTS tv| +Warnings: +Note 1051 Unknown table 'test.tv' +DROP TABLE IF EXISTS tt1,tt2,tt3| +Warnings: +Note 1051 Unknown table 'tt1' +Note 1051 Unknown table 'tt2' +Note 1051 Unknown table 'tt3' +CREATE TABLE tt1 (a1 int, a2 int, a3 int, data varchar(10))| +CREATE TABLE tt2 (a2 int, data2 varchar(10))| +CREATE TABLE tt3 (a3 int, data3 varchar(10))| +INSERT INTO tt1 VALUES (1, 1, 4, 'xx')| +INSERT INTO tt2 VALUES (1, 'a')| +INSERT INTO tt2 VALUES (2, 'b')| +INSERT INTO tt2 VALUES (3, 'c')| +INSERT INTO tt3 VALUES (4, 'd')| +INSERT INTO tt3 VALUES (5, 'e')| +INSERT INTO tt3 VALUES (6, 'f')| +CREATE VIEW tv AS +SELECT tt1.*, tt2.data2, tt3.data3 +FROM tt1 INNER JOIN tt2 ON tt1.a2 = tt2.a2 +LEFT JOIN tt3 ON tt1.a3 = tt3.a3 +ORDER BY tt1.a1, tt2.a2, tt3.a3| +CREATE PROCEDURE bug6866 (_a1 int) +BEGIN +SELECT * FROM tv WHERE a1 = _a1; +END| +CALL bug6866(1)| +a1 a2 a3 data data2 data3 +1 1 4 xx a d +CALL bug6866(1)| +a1 a2 a3 data data2 data3 +1 1 4 xx a d +CALL bug6866(1)| +a1 a2 a3 data data2 data3 +1 1 4 xx a d +DROP PROCEDURE bug6866; +DROP VIEW tv| +DROP TABLE tt1, tt2, tt3| drop table t1,t2; diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index dee87979ff4..047711bb736 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -1,3 +1,4 @@ +drop table if exists t1, t2; drop procedure if exists bug8850| create table t1 (a int) engine=innodb| create procedure bug8850() @@ -20,3 +21,160 @@ a 2 drop table t1| drop procedure bug8850| +drop function if exists bug10015_1| +drop function if exists bug10015_2| +drop function if exists bug10015_3| +drop function if exists bug10015_4| +drop function if exists bug10015_5| +drop function if exists bug10015_6| +drop function if exists bug10015_7| +drop procedure if exists bug10015_8| +create table t1 (id int) engine=innodb| +create table t2 (id int primary key, j int) engine=innodb| +insert into t1 values (1),(2),(3)| +create function bug10015_1() returns int return (select count(*) from t1)| +select *, bug10015_1() from t1| +id bug10015_1() +1 3 +2 3 +3 3 +drop function bug10015_1| +create function bug10015_2() returns int +begin +declare i, s int; +set i:= (select min(id) from t1); +set s:= (select max(id) from t1); +return (s - i); +end| +select *, bug10015_2() from t1| +id bug10015_2() +1 2 +2 2 +3 2 +drop function bug10015_2| +create function bug10015_3() returns int +return (select max(a.id - b.id) from t1 as a, t1 as b where a.id >= b.id)| +select *, bug10015_3() from t1| +id bug10015_3() +1 2 +2 2 +3 2 +drop function bug10015_3| +create function bug10015_4(i int) returns int +begin +declare m int; +set m:= (select max(id) from t2); +insert into t2 values (i, m); +return m; +end| +select *, bug10015_4(id) from t1| +id bug10015_4(id) +1 NULL +2 1 +3 2 +select * from t2| +id j +1 NULL +2 1 +3 2 +drop function bug10015_4| +create function bug10015_5(i int) returns int +begin +if (i = 5) then +insert into t2 values (1, 0); +end if; +return i; +end| +insert into t1 values (bug10015_5(4)), (bug10015_5(5))| +ERROR 23000: Duplicate entry '1' for key 1 +select * from t1| +id +1 +2 +3 +drop function bug10015_5| +create function bug10015_6(i int) returns int +begin +declare continue handler for sqlexception set @error_in_func:= 1; +if (i = 5) then +insert into t2 values (4, 0), (1, 0); +end if; +return i; +end| +set @error_in_func:= 0| +insert into t1 values (bug10015_6(5)), (bug10015_6(6))| +select @error_in_func| +@error_in_func +1 +select * from t1| +id +1 +2 +3 +5 +6 +select * from t2| +id j +1 NULL +2 1 +3 2 +4 0 +drop function bug10015_6| +create function bug10015_7() returns int +begin +alter table t1 add k int; +return 1; +end| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +create function bug10015_7() returns int +begin +start transaction; +return 1; +end| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +create function bug10015_7() returns int +begin +drop table t1; +return 1; +end| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +create function bug10015_7() returns int +begin +drop temporary table t1; +return 1; +end| +drop function bug10015_7| +create function bug10015_7() returns int +begin +commit; +return 1; +end| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +create function bug10015_7() returns int +begin +call bug10015_8(); +return 1; +end| +create procedure bug10015_8() alter table t1 add k int| +select *, bug10015_7() from t1| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +drop procedure bug10015_8| +create procedure bug10015_8() start transaction| +select *, bug10015_7() from t1| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +drop procedure bug10015_8| +create procedure bug10015_8() drop temporary table if exists t1_temp| +select *, bug10015_7() from t1| +id bug10015_7() +1 1 +2 1 +3 1 +5 1 +6 1 +drop procedure bug10015_8| +create procedure bug10015_8() commit| +select *, bug10015_7() from t1| +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. +drop procedure bug10015_8| +drop function bug10015_7| +drop table t1, t2| diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 09adc48259c..c5ba4d15a50 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -138,6 +138,8 @@ t1 CREATE TABLE `t1` ( `min_num` decimal(7,6) default '0.000001' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1 ; +set @@SQL_MODE=NULL; +ERROR 42000: Variable 'sql_mode' can't be set to the value of 'NULL' SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=''; show local variables like 'SQL_MODE'; Variable_name Value diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 64c9a11b3cd..4d9bc0c7fe1 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -458,3 +458,11 @@ select h from t1; h a drop table t1; +create table t1 (a bit(8)) engine=heap; +insert into t1 values ('1111100000'); +Warnings: +Warning 1264 Out of range value adjusted for column 'a' at row 1 +select a+0 from t1; +a+0 +255 +drop table t1; diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index ab57caacc0f..93467d1d7da 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -414,8 +414,8 @@ Warning 1264 Out of range value adjusted for column 'a' at row 2 Warning 1264 Out of range value adjusted for column 'a' at row 7 select * from t1; a -9999999999 -9999999999 +0 +0 1 1 1 @@ -430,8 +430,8 @@ Warning 1264 Out of range value adjusted for column 'a' at row 2 Warning 1264 Out of range value adjusted for column 'a' at row 7 select * from t1; a -9999999999 -9999999999 +0000000000 +0000000000 0000000001 0000000001 0000000001 @@ -446,8 +446,8 @@ Warning 1264 Out of range value adjusted for column 'a' at row 2 Warning 1264 Out of range value adjusted for column 'a' at row 7 select * from t1; a -9999999999 -9999999999 +0000000000 +0000000000 0000000001 0000000001 0000000001 diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index f03f2f5a862..b406dbab82f 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -119,7 +119,7 @@ a 99.99 99.99 99.99 -99.99 +0.00 0.00 0.00 0.00 @@ -891,3 +891,40 @@ NULL select abs(NULL); abs(NULL) NULL +set @@sql_mode='traditional'; +create table t1( d1 decimal(18) unsigned, d2 decimal(20) unsigned, d3 decimal (22) unsigned); +insert into t1 values(1,-1,-1); +ERROR 22003: Out of range value adjusted for column 'd2' at row 1 +drop table t1; +create table t1 (col1 decimal(5,2), col2 numeric(5,2)); +insert into t1 values (999.999,999.999); +ERROR 22003: Out of range value adjusted for column 'col1' at row 1 +insert into t1 values (-999.999,-999.999); +ERROR 22003: Out of range value adjusted for column 'col1' at row 1 +select * from t1; +col1 col2 +drop table t1; +set sql_mode=''; +set @sav_dpi= @@div_precision_increment; +set @@div_precision_increment=15; +create table t1 (col1 int, col2 decimal(30,25), col3 numeric(30,25)); +insert into t1 values (1,0.0123456789012345678912345,0.0123456789012345678912345); +select col2/9999999999 from t1 where col1=1; +col2/9999999999 +0.000000000001234567890246913578 +select 9999999999/col2 from t1 where col1=1; +9999999999/col2 +810000007209.000065537105051 +select 77777777/7777777; +77777777/7777777 +10.000000900000090 +drop table t1; +set div_precision_increment= @sav_dpi; +create table t1 (a decimal(4,2)); +insert into t1 values (0.00); +select * from t1 where a > -0.00; +a +select * from t1 where a = -0.00; +a +0.00 +drop table t1; diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index 3bd7fe6b175..e3b12cc36e3 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -126,13 +126,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 258 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 258 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 258 NULL 2 Using where; Using index alter table t1 change v v varchar(256); select * from t1 where v like 'This is a test' order by v; v @@ -150,13 +150,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 259 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 259 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 259 NULL 2 Using where; Using index alter table t1 change v v varchar(257); select * from t1 where v like 'This is a test' order by v; v @@ -174,13 +174,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 260 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 260 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 260 NULL 2 Using where; Using index alter table t1 change v v varchar(258); select * from t1 where v like 'This is a test' order by v; v @@ -198,13 +198,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 261 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 261 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 261 NULL 2 Using where; Using index alter table t1 change v v varchar(259); select * from t1 where v like 'This is a test' order by v; v @@ -222,13 +222,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 262 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 262 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 262 NULL 2 Using where; Using index alter table t1 change v v varchar(258); select * from t1 where v like 'This is a test' order by v; v @@ -246,13 +246,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 261 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 261 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 261 NULL 2 Using where; Using index alter table t1 change v v varchar(257); select * from t1 where v like 'This is a test' order by v; v @@ -270,13 +270,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 260 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 260 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 260 NULL 2 Using where; Using index alter table t1 change v v varchar(256); select * from t1 where v like 'This is a test' order by v; v @@ -294,13 +294,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 259 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 259 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 259 NULL 2 Using where; Using index alter table t1 change v v varchar(255); select * from t1 where v like 'This is a test' order by v; v @@ -318,13 +318,13 @@ Some sample data Some samples explain select * from t1 where v like 'This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 3 Using where; Using filesort +1 SIMPLE t1 range v v 258 NULL 3 Using where; Using index explain select * from t1 where v='This is a test' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 257 const 3 Using where +1 SIMPLE t1 ref v v 258 const 3 Using where; Using index explain select * from t1 where v like 'S%' order by v; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 257 NULL 2 Using where; Using filesort +1 SIMPLE t1 range v v 258 NULL 2 Using where; Using index alter table t1 change v v varchar(254); select * from t1 where v like 'This is a test' order by v; v @@ -392,3 +392,26 @@ group by t1.b, t1.a; a b min(t1.b) 22 NULL NULL drop table t1, t2; +create table t1 (f1 varchar(65500)); +create index index1 on t1(f1(10)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` varchar(65500) default NULL, + KEY `index1` (`f1`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify f1 varchar(255); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` varchar(255) default NULL, + KEY `index1` (`f1`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 modify f1 tinytext; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` tinytext, + KEY `index1` (`f1`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 442d0784953..fd516996ae8 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -181,3 +181,56 @@ drop table t1; set table_type=MYISAM; Warnings: Warning 1287 'table_type' is deprecated; use 'storage_engine' instead +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +update t1 set a='abc'; +Warnings: +Warning 1264 Out of range value adjusted for column 'a' at row 1 +Warning 1264 Out of range value adjusted for column 'a' at row 2 +Warning 1264 Out of range value adjusted for column 'a' at row 3 +Warning 1264 Out of range value adjusted for column 'a' at row 4 +Warning 1264 Out of range value adjusted for column 'a' at row 5 +Warning 1264 Out of range value adjusted for column 'a' at row 6 +Warning 1264 Out of range value adjusted for column 'a' at row 7 +Warning 1264 Out of range value adjusted for column 'a' at row 8 +Warning 1264 Out of range value adjusted for column 'a' at row 9 +Warning 1264 Out of range value adjusted for column 'a' at row 10 +show warnings limit 2, 1; +Level Code Message +Warning 1264 Out of range value adjusted for column 'a' at row 3 +show warnings limit 0, 10; +Level Code Message +Warning 1264 Out of range value adjusted for column 'a' at row 1 +Warning 1264 Out of range value adjusted for column 'a' at row 2 +Warning 1264 Out of range value adjusted for column 'a' at row 3 +Warning 1264 Out of range value adjusted for column 'a' at row 4 +Warning 1264 Out of range value adjusted for column 'a' at row 5 +Warning 1264 Out of range value adjusted for column 'a' at row 6 +Warning 1264 Out of range value adjusted for column 'a' at row 7 +Warning 1264 Out of range value adjusted for column 'a' at row 8 +Warning 1264 Out of range value adjusted for column 'a' at row 9 +Warning 1264 Out of range value adjusted for column 'a' at row 10 +show warnings limit 9, 1; +Level Code Message +Warning 1264 Out of range value adjusted for column 'a' at row 10 +show warnings limit 10, 1; +Level Code Message +show warnings limit 9, 2; +Level Code Message +Warning 1264 Out of range value adjusted for column 'a' at row 10 +show warnings limit 0, 0; +Level Code Message +show warnings limit 1; +Level Code Message +Warning 1264 Out of range value adjusted for column 'a' at row 1 +show warnings limit 0; +Level Code Message +show warnings limit 1, 0; +Level Code Message +select * from t1 limit 0; +a +select * from t1 limit 1, 0; +a +select * from t1 limit 0, 0; +a +drop table t1; diff --git a/mysql-test/t/analyze.test b/mysql-test/t/analyze.test new file mode 100644 index 00000000000..faf30279c68 --- /dev/null +++ b/mysql-test/t/analyze.test @@ -0,0 +1,39 @@ +# +# Bug #10901 Analyze Table on new table destroys table +# This is minimal test case to get error +# The problem was that analyze table wrote the shared state to the file and this +# didn't include the inserts while locked. A check was needed to ensure that +# state information was not updated when executing analyze table for a locked table. +# The analyze table had to be within locks and check table had to be after unlocking +# since then it brings the wrong state from disk rather than from the currently +# correct internal state. The insert is needed since it changes the file state, +# number of records. +# The fix is to synchronise the state of the shared state and the current state before +# calling mi_state_info_write +# +create table t1 (a bigint); +lock tables t1 write; +insert into t1 values(0); +analyze table t1; +unlock tables; +check table t1; + +drop table t1; + +create table t1 (a bigint); +insert into t1 values(0); +lock tables t1 write; +delete from t1; +analyze table t1; +unlock tables; +check table t1; + +drop table t1; + +create table t1 (a bigint); +insert into t1 values(0); +analyze table t1; +check table t1; + +drop table t1; + diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index ef344df5fb6..afc4c722051 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -218,3 +218,39 @@ CHECK TABLE t1; INSERT INTO t1 (b) VALUES ('bbbb'); CHECK TABLE t1; DROP TABLE IF EXISTS t1; + +# +# Bug #11080 & #11005 Multi-row REPLACE fails on a duplicate key error +# + +CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)); +insert into t1 (b) values (1); +replace into t1 (b) values (2), (1), (3); +select * from t1; +truncate table t1; +insert into t1 (b) values (1); +replace into t1 (b) values (2); +replace into t1 (b) values (1); +replace into t1 (b) values (3); +select * from t1; +drop table t1; + +create table t1 (rowid int not null auto_increment, val int not null,primary +key (rowid), unique(val)); +replace into t1 (val) values ('1'),('2'); +replace into t1 (val) values ('1'),('2'); +--error 1062 +insert into t1 (val) values ('1'),('2'); +select * from t1; +drop table t1; + +# +# Test that update changes internal auto-increment value +# + +create table t1 (a int not null auto_increment primary key, val int); +insert into t1 (val) values (1); +update t1 set a=2 where a=1; +insert into t1 (val) values (1); +select * from t1; +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index d9712a28788..d870ff368d3 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -414,14 +414,17 @@ drop database mysqltest; select database(); # Connect without a database -connect (user4,localhost,mysqltest_1,,*NO-ONE*); -select database(); +connect (user1,localhost,mysqltest_1,,*NO-ONE*); +connection user1; +select database(), user(); +connection default; +disconnect user1; +use test; # # Test for Bug 856 'Naming a key "Primary" causes trouble' # -use test; --error 1280 create table t1 (a int, index `primary` (a)); --error 1280 @@ -478,8 +481,6 @@ drop table t1,t2; # This tests two additional possible errors and a hang if # an improper fix is present. # -connection default; -use test; create table t1 (a int); --error 1093 create table t1 select * from t1; @@ -501,3 +502,15 @@ create table t1(xyz.t1.name int); create table t1(t1.name int); create table t2(test.t2.name int); drop table t1,t2; + +# +# Bug#11028: Crash on create table like +# +create database mysqltest; +use mysqltest; +drop database mysqltest; +--error 1102 +create table test.t1 like x; +--disable_warnings +drop table if exists test.t1; +--enable_warnings diff --git a/mysql-test/t/ctype_cp1250_ch.test b/mysql-test/t/ctype_cp1250_ch.test index 06aea7b9979..814da628fb7 100644 --- a/mysql-test/t/ctype_cp1250_ch.test +++ b/mysql-test/t/ctype_cp1250_ch.test @@ -10,3 +10,15 @@ CREATE TABLE t1 (a char(16)) character set cp1250 collate cp1250_czech_cs; INSERT INTO t1 VALUES (''); SELECT a, length(a), a='', a=' ', a=' ' FROM t1; DROP TABLE t1; + +# +# Bug#9759 Empty result with 'LIKE' and cp1250_czech_cs +# +CREATE TABLE t1 ( + popisek varchar(30) collate cp1250_general_ci NOT NULL default '', + PRIMARY KEY (`popisek`) +); +INSERT INTO t1 VALUES ('2005-01-1'); +SELECT * FROM t1 WHERE popisek = '2005-01-1'; +SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; +drop table t1; diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index dfca82fa70a..e5c2acc8b4e 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -455,3 +455,18 @@ drop table t1; SET collation_connection='utf8_unicode_ci'; -- source include/ctype_filesort.inc + +# +# Check UPPER/LOWER changeing length +# +# Result shorter than argument +CREATE TABLE t1 (id int, a varchar(30) character set utf8); +INSERT INTO t1 VALUES (1, _ucs2 0x01310069), (2, _ucs2 0x01310131); +INSERT INTO t1 VALUES (3, _ucs2 0x00690069), (4, _ucs2 0x01300049); +INSERT INTO t1 VALUES (5, _ucs2 0x01300130), (6, _ucs2 0x00490049); +SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu +FROM t1 ORDER BY id; +ALTER TABLE t1 MODIFY a VARCHAR(30) character set utf8 collate utf8_turkish_ci; +SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu +FROM t1 ORDER BY id; +DROP TABLE t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index bac6e60c302..3c49b2a47f7 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -731,3 +731,18 @@ select ifnull(NULL, _utf8'string'); create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1; + +# +# Bug#10253 compound index length and utf8 char set +# produces invalid query results +# +create table t1 ( + id int not null, + city varchar(20) not null, + key (city(7),id) +) character set=utf8; +insert into t1 values (1,'Durban North'); +insert into t1 values (2,'Durban'); +select * from t1 where city = 'Durban'; +select * from t1 where city = 'Durban '; +drop table t1; diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index a6335d77a0c..265089adfa2 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1,t11,t12,t2; +drop table if exists t1,t2,t3,t11,t12; --enable_warnings CREATE TABLE t1 (a tinyint(3), b tinyint(5)); INSERT INTO t1 VALUES (1,1); @@ -152,3 +152,20 @@ INSERT INTO t1 VALUES (0),(1),(2); DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1; SELECT * FROM t1; DROP TABLE t1; + +# +# Test of multi-delete where we are not scanning the first table +# + +CREATE TABLE t1 (a int not null,b int not null); +CREATE TABLE t2 (a int not null, b int not null, primary key (a,b)); +CREATE TABLE t3 (a int not null, b int not null, primary key (a,b)); +insert into t1 values (1,1),(2,1),(1,3); +insert into t2 values (1,1),(2,2),(3,3); +insert into t3 values (1,1),(2,1),(1,3); +select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; +# This should be empty +select * from t3; +drop table t1,t2,t3; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index a3862786cc3..057c9bd9239 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -332,3 +332,11 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES ('1',1,0); SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; drop table t1; + +# +# Bug 9784 DISTINCT IFNULL truncates data +# +create table t1 (id int, dsc varchar(50)); +insert into t1 values (1, "line number one"), (2, "line number two"), (3, "line number three"); +select distinct id, IFNULL(dsc, '-') from t1; +drop table t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 694e0223753..96cd51f58db 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -213,21 +213,6 @@ INSERT INTO t1 VALUES (1,'First Row'), (2,'Second Row'); SELECT GROUP_CONCAT(b ORDER BY b) FROM t1 GROUP BY a; DROP TABLE t1; -# -# check null values #1 -# - ---disable_warnings -CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; -INSERT INTO t1 VALUES (1),(2),(3); -CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a), - CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1; ---enable_warnings -INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2); -SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz; -DROP TABLE t2; -DROP TABLE t1; - # # check null values #2 # @@ -285,6 +270,28 @@ CREATE TABLE t1 (id int); SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; DROP TABLE t1; +# +# Bug #8656: Crash with group_concat on alias in outer table +# +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2); +select b x, (select group_concat(x) from t2) from t2; +drop table t2; + +# +# Bug #7405: problems with rollup +# + +create table t1 (d int not null auto_increment,primary key(d), a int, b int, c int); +insert into t1(a,b) values (1,3), (1,4), (1,2), (2,7), (1,1), (1,2), (2,3), (2,3); +select d,a,b from t1 order by a; +explain select a, group_concat(b) from t1 group by a with rollup; +select a, group_concat(b) from t1 group by a with rollup; +select a, group_concat(distinct b) from t1 group by a with rollup; +select a, group_concat(b order by b) from t1 group by a with rollup; +select a, group_concat(distinct b order by b) from t1 group by a with rollup; +drop table t1; + # # Bug #6475 # @@ -292,12 +299,3 @@ create table t1 (a char(3), b char(20), primary key (a, b)); insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English'); select group_concat(a) from t1 group by b; drop table t1; - -# -# Bug #8656: Crash with group_concat on alias in outer table -# -create table r2 (a int, b int); -insert into r2 values (1,1), (2,2); -select b x, (select group_concat(x) from r2) from r2; -drop table r2; - diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 0eac72782a8..03057af6911 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -67,3 +67,20 @@ explain extended select degrees(pi()),radians(360); --error 1054 select rand(rand); + +# +# Bug #8459 (FORMAT returns incorrect result) +# +create table t1 (col1 int, col2 decimal(60,30)); +insert into t1 values(1,1234567890.12345); +select format(col2,7) from t1; +select format(col2,8) from t1; +insert into t1 values(7,1234567890123456.12345); +select format(col2,6) from t1 where col1=7; +drop table t1; + + +# +# Bug #10083 (round doesn't increase decimals) +# +select round(150, 2); diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 80ddb205110..6ca29ccded2 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -336,3 +336,17 @@ DROP TABLE t1; explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; + +# +# Bug #10568 +# + +select last_day('2005-00-00'); +select last_day('2005-00-01'); +select last_day('2005-01-00'); + +# +# Bug #10590: %h, %I, and %l format specifies should all return results in +# the 0-11 range +# +select time_format('100:00:00', '%H %k %h %I %l'); diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index fbd39019e6d..21d5abcc287 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -522,3 +522,20 @@ insert into t1 values(3000000000); select * from t1; select min(b) from t1; drop table t1; + +# +# Test for bug #11088: GROUP BY a BLOB colimn with COUNT(DISTINCT column1) +# + +CREATE TABLE t1 (id int PRIMARY KEY, user_id int, hostname longtext); + +INSERT INTO t1 VALUES + (1, 7, 'cache-dtc-af05.proxy.aol.com'), + (2, 3, 'what.ever.com'), + (3, 7, 'cache-dtc-af05.proxy.aol.com'), + (4, 7, 'cache-dtc-af05.proxy.aol.com'); + +SELECT hostname, COUNT(DISTINCT user_id) as no FROM t1 + WHERE hostname LIKE '%aol%' + GROUP BY hostname; + diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index 68a84e1c193..75ef5a73cb0 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -426,3 +426,12 @@ drop table t1; --error 1075 create table t1 (a int not null, b int not null auto_increment, primary key(a, b)) engine=heap; + +# +# Bug #10566: Verify that we can create a prefixed key with length > 255 +# +create table t1 (c char(255), primary key(c(90))); +insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); +--error 1062 +insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); +drop table t1; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 05dfeb67ccc..7302b3e5e58 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -4,6 +4,11 @@ # Test for information_schema.schemata & # show databases +--disable_warnings +DROP TABLE IF EXISTS t0,t1,t2; +--enable_warnings + + show variables where variable_name like "skip_show_database"; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; @@ -493,3 +498,47 @@ flush privileges; # SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; +# +# Bug #10964 Information Schema:Authorization check on privilege tables is improper +# + +create database mysqltest; +create table mysqltest.t1 (f1 int, f2 int); +create table mysqltest.t2 (f1 int); +grant select (f1) on mysqltest.t1 to user1@localhost; +grant select on mysqltest.t2 to user2@localhost; +grant select on mysqltest.* to user3@localhost; +grant select on *.* to user4@localhost; + +connect (con1,localhost,user1,,); +connect (con2,localhost,user2,,); +connect (con3,localhost,user3,,); +connect (con4,localhost,user4,,); +connection con1; +select * from information_schema.column_privileges; +select * from information_schema.table_privileges; +select * from information_schema.schema_privileges; +select * from information_schema.user_privileges; +show grants; +connection con2; +select * from information_schema.column_privileges; +select * from information_schema.table_privileges; +select * from information_schema.schema_privileges; +select * from information_schema.user_privileges; +show grants; +connection con3; +select * from information_schema.column_privileges; +select * from information_schema.table_privileges; +select * from information_schema.schema_privileges; +select * from information_schema.user_privileges; +show grants; +connection con4; +select * from information_schema.column_privileges where grantee like '%user%'; +select * from information_schema.table_privileges where grantee like '%user%'; +select * from information_schema.schema_privileges where grantee like '%user%'; +select * from information_schema.user_privileges where grantee like '%user%'; +show grants; +connection default; +drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost; +use test; +drop database mysqltest; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index dc9645a8326..7b27d589ec3 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -615,7 +615,6 @@ truncate table t1; insert into t1 values(1),(2); select * from t1; truncate table t1; -truncate table t1; insert into t1 values(1),(2); delete from t1; select * from t1; @@ -1056,8 +1055,8 @@ insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); insert t2 select * from t1; insert t3 select * from t1; checksum table t1, t2, t3, t4 quick; -checksum table t1, t2, t3; -checksum table t1, t2, t3 extended; +checksum table t1, t2, t3, t4; +checksum table t1, t2, t3, t4 extended; #show table status; drop table t1,t2,t3; @@ -1176,28 +1175,6 @@ show status like "binlog_cache_use"; show status like "binlog_cache_disk_use"; drop table t1; -# -# range optimizer problem -# - -create table t1 (x bigint unsigned not null primary key) engine=innodb; -insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1); -select * from t1; -select count(*) from t1 where x>0; -select count(*) from t1 where x=0; -select count(*) from t1 where x<0; -select count(*) from t1 where x < -16; -select count(*) from t1 where x = -16; -explain select count(*) from t1 where x > -16; - -# The following result should be (2). To be fixed when we add 'unsigned flag' to -# Field::store(longlong) -select count(*) from t1 where x > -16; -select * from t1 where x > -16; -select count(*) from t1 where x = 18446744073709551601; - -drop table t1; - # # Bug #6126: Duplicate columns in keys gives misleading error message # @@ -1220,6 +1197,62 @@ alter table t1 add key (c1,c2,c1); alter table t1 add key (c1,c1,c2); drop table t1; +# +# Bug #4082: integer truncation +# + +create table t1(a int(1) , b int(1)) engine=innodb; +insert into t1 values ('1111', '3333'); +select distinct concat(a, b) from t1; +drop table t1; + +# +# BUG#7709 test case - Boolean fulltext query against unsupported +# engines does not fail +# + +CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; +--error 1214; +SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); +DROP TABLE t1; + +# +# check null values #1 +# + +--disable_warnings +CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a), + CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1; +--enable_warnings +INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2); +SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz; +DROP TABLE t2; +DROP TABLE t1; + +# +# range optimizer problem +# + +create table t1 (x bigint unsigned not null primary key) engine=innodb; +insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1); +select * from t1; +select count(*) from t1 where x>0; +select count(*) from t1 where x=0; +select count(*) from t1 where x<0; +select count(*) from t1 where x < -16; +select count(*) from t1 where x = -16; +explain select count(*) from t1 where x > -16; + +# The following result should be (2). To be fixed when we add 'unsigned flag' to +# Field::store(longlong) +select count(*) from t1 where x > -16; +select * from t1 where x > -16; +select count(*) from t1 where x = 18446744073709551601; +drop table t1; + + # Test for testable InnoDB status variables. This test # uses previous ones(pages_created, rows_deleted, ...). show status like "Innodb_buffer_pool_pages_total"; @@ -1302,20 +1335,50 @@ create table t1 (v varchar(16384)) engine=innodb; drop table t1; # -# Bug #4082: integer truncation +# BUG#11039 Wrong key length in min() # -create table t1(a int(1) , b int(1)) engine=innodb; -insert into t1 values ('1111', '3333'); -select distinct concat(a, b) from t1; +create table t1 (a char(1), b char(1), key(a, b)) engine=innodb; +insert into t1 values ('8', '6'), ('4', '7'); +select min(a) from t1; +select min(b) from t1 where a='8'; drop table t1; # -# BUG#7709 test case - Boolean fulltext query against unsupported -# engines does not fail +# Bug #11080 & #11005 Multi-row REPLACE fails on a duplicate key error # -CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; ---error 1214; -SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); -DROP TABLE t1; +CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb; +insert into t1 (b) values (1); +replace into t1 (b) values (2), (1), (3); +select * from t1; +truncate table t1; +insert into t1 (b) values (1); +replace into t1 (b) values (2); +replace into t1 (b) values (1); +replace into t1 (b) values (3); +select * from t1; +drop table t1; + +create table t1 (rowid int not null auto_increment, val int not null,primary +key (rowid), unique(val)) engine=innodb; +replace into t1 (val) values ('1'),('2'); +replace into t1 (val) values ('1'),('2'); +--error 1062 +insert into t1 (val) values ('1'),('2'); +select * from t1; +drop table t1; + + +# +# Test that update does not change internal auto-increment value +# + +create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB; +insert into t1 (val) values (1); +update t1 set a=2 where a=1; +# We should get the following error because InnoDB does not update the counter +--error 1062 +insert into t1 (val) values (1); +select * from t1; +drop table t1; diff --git a/mysql-test/t/innodb_handler.test b/mysql-test/t/innodb_handler.test index e8c486caf66..65728519e7b 100644 --- a/mysql-test/t/innodb_handler.test +++ b/mysql-test/t/innodb_handler.test @@ -69,6 +69,16 @@ handler t2 read next; handler t2 read last; handler t2 close; +handler t1 open; +handler t1 read a next; # this used to crash as a bug#5373 +handler t1 read a next; +handler t1 close; + +handler t1 open; +handler t1 read a prev; # this used to crash as a bug#5373 +handler t1 read a prev; +handler t1 close; + handler t1 open as t2; handler t2 read first; alter table t1 engine=innodb; diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index af3509c8454..9db1523be51 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -324,3 +324,16 @@ alter table t1 add key (c1,c2,c1); --error 1060 alter table t1 add key (c1,c1,c2); drop table t1; + +# +# If we use a partial field for a key that is actually the length of the +# field, and we extend the field, we end up with a key that includes the +# whole new length of the field. +# +create table t1 (a varchar(10), b varchar(10), key(a(10),b(10))); +show create table t1; +alter table t1 modify b varchar(20); +show create table t1; +alter table t1 modify a varchar(20); +show create table t1; +drop table t1; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 067b0db492f..4e16e57058d 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -295,3 +295,23 @@ select 1 as `a'b`, 2 as `a"b`; # Test escaping of quotes select 'aaa\\','aa''a',"aa""a"; + + + +# +# Check of include/show_msg.inc +# + +# The message contains in most cases a string with the default character set +SET @message = 'Here comes a message'; +--source include/show_msg.inc + +# The message could also contain a string with character set utf8 +SET @message = USER(); +--source include/show_msg.inc + +# The message contains more then 80 characters on multiple lines +SET @message = 'Here comes a very very long message that is longer then 80 characters +on multiple lines'; +--source include/show_msg80.inc + diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test index 3c7b99da25a..0173fabd46f 100644 --- a/mysql-test/t/ndb_restore.test +++ b/mysql-test/t/ndb_restore.test @@ -214,4 +214,4 @@ drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c; # Test BUG#10287 # ---exec $NDB_TOOLS_DIR/ndb_select_all -d sys -D , SYSTAB_0 | grep 520093696 +--exec $NDB_TOOLS_DIR/ndb_select_all --no-defaults -d sys -D , SYSTAB_0 | grep 520093696 diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index f4396e41a20..60b77576572 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -664,3 +664,32 @@ select t2.id from t2, t1 where (t1.id=1 and t2.t1_id=t1.id); deallocate prepare stmt; drop table t1, t2; + +# +# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement +# support for placeholders in LIMIT clause." +# Add basic test coverage for the feature. +# +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +select * from t1 limit 0, 1; +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +select * from t1 limit 3, 2; +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +--error 1235 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; + +drop table t1; +deallocate prepare stmt; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index b6132d23d02..372325c4cbd 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2255,3 +2255,19 @@ AND FK_firma_id = 2; drop table t1; +# +# Test for bug #10084: STRAIGHT_JOIN with ON expression +# + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT INTO t2 VALUES (2), (4), (6); + +SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; + +EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a; +EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a; + +DROP TABLE t1,t2; + diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 891e282e335..faf6d8b4de3 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -965,3 +965,24 @@ drop procedure bug10969| drop table t1| delimiter ;| + +# +# Bug#10975, #10605, #7115: Dynamic SQL by means of +# PREPARE/EXECUTE/DEALLOCATE is not supported yet. +# Check that an error message is returned. +# +prepare stmt from "select 1"; +--error ER_SP_BADSTATEMENT +create procedure p() deallocate prepare stmt; +--error ER_SP_BADSTATEMENT +create function f() returns int begin deallocate prepare stmt; +--error ER_SP_BADSTATEMENT +create procedure p() prepare stmt from "select 1"; +--error ER_SP_BADSTATEMENT +create function f() returns int begin prepare stmt from "select 1"; +--error ER_SP_BADSTATEMENT +create procedure p() execute stmt; +--error ER_SP_BADSTATEMENT +create function f() returns int begin execute stmt; +deallocate prepare stmt; + diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test index 608ac3e2ee7..8fec5d14bc1 100644 --- a/mysql-test/t/sp-threads.test +++ b/mysql-test/t/sp-threads.test @@ -84,6 +84,32 @@ reap; drop procedure bug9486; drop table t1, t2; +# +# BUG#11158: Can't perform multi-delete in stored procedure +# +--disable_warnings +drop procedure if exists bug11158; +--enable_warnings +create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id; +create table t1 (id int, j int); +insert into t1 values (1, 1), (2, 2); +create table t2 (id int); +insert into t2 values (1); +# Procedure should work and cause proper effect (delete only first row) +call bug11158(); +select * from t1; +# Also let us test that we obtain only read (and thus non exclusive) lock +# for table from which we are not going to delete rows. +connection con2root; +lock tables t2 read; +connection con1root; +call bug11158(); +connection con2root; +unlock tables; +connection con1root; +# Clean-up +drop procedure bug11158; +drop table t1, t2; # # BUG#NNNN: New bug synopsis diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index e76dc971df7..20b1a98702c 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3268,12 +3268,6 @@ drop procedure bug8762| # # BUG#5240: Stored procedure crash if function has cursor declaration # -# The following test case fails in --ps-protocol mode due to some bugs -# in algorithm which calculates list of tables to be locked for queries -# using Stored Functions. It is disabled until Dmitri fixes this. -# ---disable_ps_protocol - --disable_warnings drop function if exists bug5240| --enable_warnings @@ -3293,8 +3287,6 @@ insert into t1 values ("answer", 42)| select id, bug5240() from t1| drop function bug5240| ---enable_ps_protocol - # # BUG#5278: Stored procedure packets out of order if SET PASSWORD. # @@ -3849,6 +3841,50 @@ call bug10961()| drop procedure bug10961| +# +# BUG #6866: Second call of a stored procedure using a view with on expressions +# + +--disable_warnings +DROP PROCEDURE IF EXISTS bug6866| +--enable_warnings + +DROP VIEW IF EXISTS tv| +DROP TABLE IF EXISTS tt1,tt2,tt3| + +CREATE TABLE tt1 (a1 int, a2 int, a3 int, data varchar(10))| +CREATE TABLE tt2 (a2 int, data2 varchar(10))| +CREATE TABLE tt3 (a3 int, data3 varchar(10))| + +INSERT INTO tt1 VALUES (1, 1, 4, 'xx')| + +INSERT INTO tt2 VALUES (1, 'a')| +INSERT INTO tt2 VALUES (2, 'b')| +INSERT INTO tt2 VALUES (3, 'c')| + +INSERT INTO tt3 VALUES (4, 'd')| +INSERT INTO tt3 VALUES (5, 'e')| +INSERT INTO tt3 VALUES (6, 'f')| + +CREATE VIEW tv AS +SELECT tt1.*, tt2.data2, tt3.data3 + FROM tt1 INNER JOIN tt2 ON tt1.a2 = tt2.a2 + LEFT JOIN tt3 ON tt1.a3 = tt3.a3 + ORDER BY tt1.a1, tt2.a2, tt3.a3| + +CREATE PROCEDURE bug6866 (_a1 int) +BEGIN +SELECT * FROM tv WHERE a1 = _a1; +END| + +CALL bug6866(1)| +CALL bug6866(1)| +CALL bug6866(1)| + +DROP PROCEDURE bug6866; + +DROP VIEW tv| +DROP TABLE tt1, tt2, tt3| # # BUG#NNNN: New bug synopsis diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index f5b38ada674..d860d4818ba 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -4,6 +4,10 @@ -- source include/have_innodb.inc +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + delimiter |; # @@ -35,6 +39,146 @@ drop table t1| drop procedure bug8850| +# +# BUG#10015: Crash in InnoDB if stored routines are used +# (crash happens in auto-commit mode) +# +--disable_warnings +drop function if exists bug10015_1| +drop function if exists bug10015_2| +drop function if exists bug10015_3| +drop function if exists bug10015_4| +drop function if exists bug10015_5| +drop function if exists bug10015_6| +drop function if exists bug10015_7| +drop procedure if exists bug10015_8| +--enable_warnings +create table t1 (id int) engine=innodb| +create table t2 (id int primary key, j int) engine=innodb| +insert into t1 values (1),(2),(3)| +create function bug10015_1() returns int return (select count(*) from t1)| +select *, bug10015_1() from t1| +drop function bug10015_1| +# Test couple of a bit more complex cases +create function bug10015_2() returns int + begin + declare i, s int; + set i:= (select min(id) from t1); + set s:= (select max(id) from t1); + return (s - i); + end| +select *, bug10015_2() from t1| +drop function bug10015_2| +create function bug10015_3() returns int + return (select max(a.id - b.id) from t1 as a, t1 as b where a.id >= b.id)| +select *, bug10015_3() from t1| +drop function bug10015_3| +create function bug10015_4(i int) returns int + begin + declare m int; + set m:= (select max(id) from t2); + insert into t2 values (i, m); + return m; + end| +select *, bug10015_4(id) from t1| +select * from t2| +drop function bug10015_4| +# Now let us test how statement rollback works +# This function will cause the whole stmt to be rolled back, +# there should not be any traces left. +create function bug10015_5(i int) returns int + begin + if (i = 5) then + insert into t2 values (1, 0); + end if; + return i; + end| +--error 1062 +insert into t1 values (bug10015_5(4)), (bug10015_5(5))| +select * from t1| +drop function bug10015_5| +# Thanks to error-handler this function should not cause rollback +# of statement calling it. But insert statement in it should be +# rolled back completely and don't leave any traces in t2. +# Unfortunately we can't implement such behavior in 5.0, so it +# is something to be fixed in later 5.* releases (TODO). +create function bug10015_6(i int) returns int + begin + declare continue handler for sqlexception set @error_in_func:= 1; + if (i = 5) then + insert into t2 values (4, 0), (1, 0); + end if; + return i; + end| +set @error_in_func:= 0| +insert into t1 values (bug10015_6(5)), (bug10015_6(6))| +select @error_in_func| +select * from t1| +select * from t2| +drop function bug10015_6| +# Let us test that we don't allow any statements causing transaction +# commit in stored functions (we test only most interesting cases here). +# Cases which can be caught at creation time: +--error 1422 +create function bug10015_7() returns int + begin + alter table t1 add k int; + return 1; + end| +--error 1422 +create function bug10015_7() returns int + begin + start transaction; + return 1; + end| +--error 1422 +create function bug10015_7() returns int + begin + drop table t1; + return 1; + end| +# It should be OK to drop temporary table. +create function bug10015_7() returns int + begin + drop temporary table t1; + return 1; + end| +drop function bug10015_7| +--error 1422 +create function bug10015_7() returns int + begin + commit; + return 1; + end| +# Now let us test cases which we can catch only at run-time: +create function bug10015_7() returns int + begin + call bug10015_8(); + return 1; + end| +create procedure bug10015_8() alter table t1 add k int| +--error 1422 +select *, bug10015_7() from t1| +drop procedure bug10015_8| +create procedure bug10015_8() start transaction| +--error 1422 +select *, bug10015_7() from t1| +drop procedure bug10015_8| +# Again it is OK to drop temporary table +# We are surpressing warnings since they are not essential +create procedure bug10015_8() drop temporary table if exists t1_temp| +--disable_warnings +select *, bug10015_7() from t1| +--enable_warnings +drop procedure bug10015_8| +create procedure bug10015_8() commit| +--error 1422 +select *, bug10015_7() from t1| +drop procedure bug10015_8| +drop function bug10015_7| +drop table t1, t2| + + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index e80752eb71b..6a0c4aecada 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -80,6 +80,11 @@ create table t1 ( min_num dec(6,6) default .000001); show create table t1; drop table t1 ; +# +# Bug #10732: Set SQL_MODE to NULL gives garbled error message +# +--error 1231 +set @@SQL_MODE=NULL; # # test for diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 19d16f95990..2df5f0ed05d 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -162,3 +162,12 @@ create table t1 (a int, b time, c tinyint, d bool, e char(10), f bit(1), insert into t1 set a=1; select h from t1; drop table t1; + +# +# Bug #10539 +# + +create table t1 (a bit(8)) engine=heap; +insert into t1 values ('1111100000'); +select a+0 from t1; +drop table t1; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 9b09c415379..6199bd34fa9 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -911,7 +911,9 @@ DROP TABLE t1; # Bug #10465 # +--disable_warnings CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB; +--enable_warnings INSERT INTO t1 (GRADE) VALUES (151),(252),(343); SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300; SELECT GRADE FROM t1 WHERE GRADE= 151; @@ -923,3 +925,42 @@ DROP TABLE t1; select abs(10/0); select abs(NULL); + +# +# Bug #9894 (negative to unsigned column) +# +set @@sql_mode='traditional'; +create table t1( d1 decimal(18) unsigned, d2 decimal(20) unsigned, d3 decimal (22) unsigned); +--error 1264 +insert into t1 values(1,-1,-1); +drop table t1; +create table t1 (col1 decimal(5,2), col2 numeric(5,2)); +--error 1264 +insert into t1 values (999.999,999.999); +--error 1264 +insert into t1 values (-999.999,-999.999); +select * from t1; +drop table t1; +set sql_mode=''; + +# +# Bug #8425 (insufficient precision of the division) +# +set @sav_dpi= @@div_precision_increment; +set @@div_precision_increment=15; +create table t1 (col1 int, col2 decimal(30,25), col3 numeric(30,25)); +insert into t1 values (1,0.0123456789012345678912345,0.0123456789012345678912345); +select col2/9999999999 from t1 where col1=1; +select 9999999999/col2 from t1 where col1=1; +select 77777777/7777777; +drop table t1; +set div_precision_increment= @sav_dpi; + +# +# Bug #10896 (0.00 > -0.00) +# +create table t1 (a decimal(4,2)); +insert into t1 values (0.00); +select * from t1 where a > -0.00; +select * from t1 where a = -0.00; +drop table t1; diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test index 2bffca6b889..1a3a93018a4 100644 --- a/mysql-test/t/type_varchar.test +++ b/mysql-test/t/type_varchar.test @@ -118,3 +118,15 @@ insert into t2 values (22), (22); select t1.a, t1.b, min(t1.b) from t1 inner join t2 ON t2.a = t1.a group by t1.b, t1.a; drop table t1, t2; + +# +# Bug #10543: convert varchar with index to text +# +create table t1 (f1 varchar(65500)); +create index index1 on t1(f1(10)); +show create table t1; +alter table t1 modify f1 varchar(255); +show create table t1; +alter table t1 modify f1 tinytext; +show create table t1; +drop table t1; diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 69284b4c6e4..314432af83e 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -129,3 +129,25 @@ drop table t1; # Test for deprecated table_type variable # set table_type=MYISAM; + +# +# Tests for show warnings limit a, b +# +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +# should generate 10 warnings +update t1 set a='abc'; +show warnings limit 2, 1; +show warnings limit 0, 10; +show warnings limit 9, 1; +show warnings limit 10, 1; +show warnings limit 9, 2; +show warnings limit 0, 0; +show warnings limit 1; +show warnings limit 0; +show warnings limit 1, 0; +# make sure behaviour is consistent with select ... limit +select * from t1 limit 0; +select * from t1 limit 1, 0; +select * from t1 limit 0, 0; +drop table t1; diff --git a/mysys/default.c b/mysys/default.c index e28161ba7b0..ab9bdaf0ed2 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -850,7 +850,7 @@ static void init_default_directories() *ptr++= "C:/"; if (GetWindowsDirectory(system_dir,sizeof(system_dir))) - *ptr++= &system_dir; + *ptr++= (char*)&system_dir; #if defined(_MSC_VER) && (_MSC_VER >= 1300) /* Only VC7 and up */ /* Only add shared system directory if different from default. */ diff --git a/mysys/default_modify.c b/mysys/default_modify.c index add4317bb56..721ca596428 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -37,22 +37,20 @@ #define NEWLINE_LEN 1 #endif +static char *add_option(char *dst, const char *option_value, + const char *option, int remove_option); + int modify_defaults_file(const char *file_location, const char *option, const char *option_value, const char *section_name, int remove_option) { FILE *cnf_file; MY_STAT file_stat; - char linebuff[BUFF_SIZE], tmp[BUFF_SIZE], *tmp_ptr, *src_ptr, *dst_ptr, - *file_buffer; - uint optlen, optval_len, sect_len; - my_bool in_section= FALSE; + char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer; + uint optlen, optval_len, sect_len, nr_newlines= 0; + my_bool in_section= FALSE, opt_applied= 0; DBUG_ENTER("modify_defaults_file"); - optlen= strlen(option); - optval_len= strlen(option_value); - sect_len= strlen(section_name); - if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0)))) DBUG_RETURN(2); @@ -60,12 +58,15 @@ int modify_defaults_file(const char *file_location, const char *option, if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) goto err; + optlen= strlen(option); + optval_len= strlen(option_value); + /* Reserve space to read the contents of the file and some more for the option we want to add. */ - if (!(file_buffer= (char*) my_malloc(sizeof(char)* - (file_stat.st_size + + if (!(file_buffer= (char*) my_malloc(sizeof(char) * + (file_stat.st_size + /* option name len */ optlen + /* reserve space for newline */ @@ -73,35 +74,44 @@ int modify_defaults_file(const char *file_location, const char *option, /* reserve for '=' char */ 1 + /* option value len */ - optval_len), MYF(MY_WME)))) + optval_len + + /* The ending zero plus some safety */ + FN_REFLEN), MYF(MY_WME)))) goto malloc_err; - for (dst_ptr= file_buffer, tmp_ptr= 0; - fgets(linebuff, BUFF_SIZE, cnf_file); ) + sect_len= strlen(section_name); + + for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); ) { /* Skip over whitespaces */ for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} - if (in_section && !strncmp(src_ptr, option, optlen) && + if (!*src_ptr) /* Empty line */ + { + nr_newlines++; + continue; + } + + if (!opt_applied && in_section && !strncmp(src_ptr, option, optlen) && (*(src_ptr + optlen) == '=' || my_isspace(&my_charset_latin1, *(src_ptr + optlen)) || *(src_ptr + optlen) == '\0')) { - /* The option under modifying was found in this section. Apply new. */ - if (!remove_option) - dst_ptr= strmov(dst_ptr, tmp); - tmp_ptr= 0; /* To mark that we have already applied this */ + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + opt_applied= 1; } else { /* If going to new group and we have option to apply, do it now */ - if (tmp_ptr && *src_ptr == '[') + if (in_section && !opt_applied && *src_ptr == '[') { - dst_ptr= strmov(dst_ptr, tmp); - tmp_ptr= 0; + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + } + for (; nr_newlines; nr_newlines--) + dst_ptr= strmov(dst_ptr, NEWLINE); dst_ptr= strmov(dst_ptr, linebuff); } /* Look for a section */ @@ -117,43 +127,38 @@ int modify_defaults_file(const char *file_location, const char *option, if (*src_ptr != ']') continue; /* Missing closing parenthesis. Assume this was no group */ - in_section= TRUE; - /* add option */ - if (!remove_option) - { - tmp_ptr= strmov(tmp, option); - if (*option_value) - { - *tmp_ptr++= '='; - tmp_ptr= strmov(tmp_ptr, option_value); - } - /* add a newline */ - strmov(tmp_ptr, NEWLINE); - } } else in_section= FALSE; /* mark that this section is of no interest to us */ } } - /* File ended. New option still remains to apply at the end */ - if (tmp_ptr) + /* File ended. */ + if (!opt_applied && !remove_option && in_section) { + /* New option still remains to apply at the end */ if (*(dst_ptr - 1) != '\n') - *dst_ptr++= '\n'; - dst_ptr= strmov(dst_ptr, tmp); + dst_ptr= strmov(dst_ptr, NEWLINE); + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + opt_applied= 1; } + for (; nr_newlines; nr_newlines--) + dst_ptr= strmov(dst_ptr, NEWLINE); - if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, - MYF(MY_WME)) || - my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || - my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), - MYF(MY_NABP)) || - my_fclose(cnf_file, MYF(MY_WME))) - goto err; + if (opt_applied) + { + /* Don't write the file if there are no changes to be made */ + if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, + MYF(MY_WME)) || + my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || + my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), + MYF(MY_NABP))) + goto err; + } + if (my_fclose(cnf_file, MYF(MY_WME))) + goto err; my_free(file_buffer, MYF(0)); - DBUG_RETURN(0); err: @@ -162,3 +167,21 @@ malloc_err: my_fclose(cnf_file, MYF(0)); DBUG_RETURN(1); /* out of resources */ } + + +static char *add_option(char *dst, const char *option_value, + const char *option, int remove_option) +{ + if (!remove_option) + { + dst= strmov(dst, option); + if (*option_value) + { + *dst++= '='; + dst= strmov(dst, option_value); + } + /* add a newline */ + dst= strmov(dst, NEWLINE); + } + return dst; +} diff --git a/mysys/hash.c b/mysys/hash.c index fe27b5fcb6d..28f8797288c 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -262,7 +262,25 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink) return; } - /* Compare a key in a record to a whole key. Return 0 if identical */ +/* + Compare a key in a record to a whole key. Return 0 if identical + + SYNOPSIS + hashcmp() + hash hash table + pos position of hash record to use in comparison + key key for comparison + length length of key + + NOTES: + If length is 0, comparison is done using the length of the + record being compared against. + + RETURN + < 0 key of record < key + = 0 key of record == key + > 0 key of record > key + */ static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) { @@ -270,7 +288,7 @@ static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1); return ((length && length != rec_keylength) || my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength, - (uchar*) key, length)); + (uchar*) key, rec_keylength)); } diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index e0d6288f76b..4aa31829c59 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -39,10 +39,11 @@ DESCRIPTION This function prepares memory root for further use, sets initial size of chunk for memory allocation and pre-allocates first block if specified. - Altough error can happen during execution of this function if pre_alloc_size - is non-0 it won't be reported. Instead it will be reported as error in first - alloc_root() on this memory root. + Altough error can happen during execution of this function if + pre_alloc_size is non-0 it won't be reported. Instead it will be + reported as error in first alloc_root() on this memory root. */ + void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { @@ -71,6 +72,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, DBUG_VOID_RETURN; } + /* SYNOPSIS reset_root_defaults() @@ -86,7 +88,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, reuse one of existing blocks as prealloc block, or malloc new one of requested size. If no blocks can be reused, all unused blocks are freed before allocation. - */ +*/ void reset_root_defaults(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) @@ -260,6 +262,7 @@ static inline void mark_blocks_free(MEM_ROOT* root) NOTES One can call this function either with root block initialised with init_alloc_root() or with a bzero()-ed block. + It's also safe to call this multiple times with the same mem_root. */ void free_root(MEM_ROOT *root, myf MyFlags) diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 3c6f1b15384..002e5ca0f06 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -158,32 +158,52 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) DBUG_RETURN(fd); } /* my_fdopen */ +/* + make_ftype + Make a filehandler-open-typestring from ordinary inputflags - /* Make a filehandler-open-typestring from ordinary inputflags */ - + Note: This routine attempts to find the best possible match + between a numeric option and a string option that could be + fed to fopen. There is not a 1 to 1 mapping between the two. + + r == O_RDONLY + w == O_WRONLY|O_TRUNC|O_CREAT + a == O_WRONLY|O_APPEND|O_CREAT + r+ == O_RDWR + w+ == O_RDWR|O_TRUNC|O_CREAT + a+ == O_RDWR|O_APPEND|O_CREAT +*/ static void make_ftype(register my_string to, register int flag) { -#if FILE_BINARY /* If we have binary-files */ +#if FILE_BINARY + /* If we have binary-files */ reg3 int org_flag=flag; -#endif - flag&= ~FILE_BINARY; /* remove binary bit */ - if (flag == O_RDONLY) - *to++= 'r'; - else if (flag == O_WRONLY) - *to++= 'w'; - else - { /* Add '+' after theese */ - if (flag == O_RDWR) +#endif + flag&= ~FILE_BINARY; /* remove binary bit */ + + /* check some possible invalid combinations */ + DBUG_ASSERT(flag & (O_TRUNC|O_APPEND) != O_TRUNC|O_APPEND); + + if (flag & (O_RDONLY|O_WRONLY) == O_WRONLY) + *to++= (flag & O_APPEND) ? 'a' : 'w'; + else if (flag & O_RDWR) + { + /* Add '+' after theese */ + if (flag & (O_TRUNC | O_CREAT)) + *to++= 'w'; + else if (flag & O_APPEND) + *to++= 'a'; + else *to++= 'r'; - else if (flag & O_APPEND) - *to++= 'a'; - else - *to++= 'w'; /* Create file */ - *to++= '+'; - } -#if FILE_BINARY /* If we have binary-files */ - if (org_flag & FILE_BINARY) + *to++= '+'; + } + else + *to++= 'r'; + +#if FILE_BINARY /* If we have binary-files */ + if (org_flag & FILE_BINARY) *to++='b'; -#endif +#endif *to='\0'; } /* make_ftype */ + diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 87e526d0ea3..e14bd7529f9 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -23,7 +23,7 @@ int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, { if (!part_key) return charset_info->coll->strnncollsp(charset_info, a, a_length, - b, b_length, !skip_end_space); + b, b_length, (my_bool)!skip_end_space); return charset_info->coll->strnncoll(charset_info, a, a_length, b, b_length, part_key); } diff --git a/mysys/raid.cc b/mysys/raid.cc index a645c0109db..29819a878c4 100644 --- a/mysys/raid.cc +++ b/mysys/raid.cc @@ -70,8 +70,6 @@ tonu@mysql.com & monty@mysql.com */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 7761d2a9fc8..85a2b34b851 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -684,8 +684,10 @@ void thr_unlock(THR_LOCK_DATA *data) lock->read.last=data->prev; else if (lock_type == TL_WRITE_DELAYED && data->cond) { - /* This only happens in extreme circumstances when a - write delayed lock that is waiting for a lock */ + /* + This only happens in extreme circumstances when a + write delayed lock that is waiting for a lock + */ lock->write_wait.last=data->prev; /* Put it on wait queue */ } else diff --git a/ndb/include/transporter/TransporterRegistry.hpp b/ndb/include/transporter/TransporterRegistry.hpp index 363cdabe10a..1ae8a4068c4 100644 --- a/ndb/include/transporter/TransporterRegistry.hpp +++ b/ndb/include/transporter/TransporterRegistry.hpp @@ -203,6 +203,13 @@ public: bool createSCITransporter(struct TransporterConfiguration * config); bool createSHMTransporter(struct TransporterConfiguration * config); bool createOSETransporter(struct TransporterConfiguration * config); + + /** + * Get free buffer space + * + * Get #free bytes in send buffer for node + */ + Uint32 get_free_buffer(Uint32 node) const ; /** * prepareSend diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index f188a433f1b..f45bc6ead54 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -188,7 +188,7 @@ IPCConfig::configureTransporters(Uint32 nodeId, if(iter.get(CFG_NODE_HOST, &hostname)) continue; if( strlen(hostname) == 0 ) continue; if(iter.get(CFG_MGM_PORT, &port)) continue; - connect_string.appfmt("%s%s:port",separator,hostname,port); + connect_string.appfmt("%s%s:%u",separator,hostname,port); separator= ","; } NdbMgmHandle h= ndb_mgm_create_handle(); diff --git a/ndb/src/common/transporter/SCI_Transporter.cpp b/ndb/src/common/transporter/SCI_Transporter.cpp index 506140a887f..c96f84a4f4f 100644 --- a/ndb/src/common/transporter/SCI_Transporter.cpp +++ b/ndb/src/common/transporter/SCI_Transporter.cpp @@ -1025,7 +1025,8 @@ SCI_Transporter::initSCI() { DBUG_RETURN(true); } - - - - +Uint32 +SCI_Transporter::get_free_buffer() const +{ + return (m_TargetSegm[m_ActiveAdapterId].writer)->get_free_buffer(); +} diff --git a/ndb/src/common/transporter/SCI_Transporter.hpp b/ndb/src/common/transporter/SCI_Transporter.hpp index 8d263f32a57..cb42e437118 100644 --- a/ndb/src/common/transporter/SCI_Transporter.hpp +++ b/ndb/src/common/transporter/SCI_Transporter.hpp @@ -133,7 +133,8 @@ public: * remote segment is mapped. Otherwize false. */ bool getConnectionStatus(); - + + virtual Uint32 get_free_buffer() const; private: SCI_Transporter(TransporterRegistry &t_reg, const char *local_host, diff --git a/ndb/src/common/transporter/SHM_Buffer.hpp b/ndb/src/common/transporter/SHM_Buffer.hpp index f49b4fe73cb..27321a3191f 100644 --- a/ndb/src/common/transporter/SHM_Buffer.hpp +++ b/ndb/src/common/transporter/SHM_Buffer.hpp @@ -157,6 +157,7 @@ public: inline Uint32 getWriteIndex() const { return m_writeIndex;} inline Uint32 getBufferSize() const { return m_bufferSize;} + inline Uint32 get_free_buffer() const; inline void copyIndexes(SHM_Writer * standbyWriter); @@ -212,5 +213,21 @@ SHM_Writer::updateWritePtr(Uint32 sz){ m_writeIndex = tWriteIndex; * m_sharedWriteIndex = tWriteIndex; } + +inline +Uint32 +SHM_Writer::get_free_buffer() const +{ + Uint32 tReadIndex = * m_sharedReadIndex; + Uint32 tWriteIndex = m_writeIndex; + + Uint32 free; + if(tReadIndex <= tWriteIndex){ + free = m_bufferSize + tReadIndex - tWriteIndex; + } else { + free = tReadIndex - tWriteIndex; + } + return free; +} #endif diff --git a/ndb/src/common/transporter/SHM_Transporter.cpp b/ndb/src/common/transporter/SHM_Transporter.cpp index e2d23cf94e2..a225988d37f 100644 --- a/ndb/src/common/transporter/SHM_Transporter.cpp +++ b/ndb/src/common/transporter/SHM_Transporter.cpp @@ -365,3 +365,9 @@ SHM_Transporter::doSend() kill(m_remote_pid, g_ndb_shm_signum); } } + +Uint32 +SHM_Transporter::get_free_buffer() const +{ + return writer->get_free_buffer(); +} diff --git a/ndb/src/common/transporter/SHM_Transporter.hpp b/ndb/src/common/transporter/SHM_Transporter.hpp index 677bd6efc37..e7a76225471 100644 --- a/ndb/src/common/transporter/SHM_Transporter.hpp +++ b/ndb/src/common/transporter/SHM_Transporter.hpp @@ -139,6 +139,8 @@ protected: int m_remote_pid; Uint32 m_last_signal; Uint32 m_signal_threshold; + + virtual Uint32 get_free_buffer() const; private: bool _shmSegCreated; diff --git a/ndb/src/common/transporter/SendBuffer.cpp b/ndb/src/common/transporter/SendBuffer.cpp index 58cad96931f..8f69eb4bd40 100644 --- a/ndb/src/common/transporter/SendBuffer.cpp +++ b/ndb/src/common/transporter/SendBuffer.cpp @@ -60,7 +60,7 @@ SendBuffer::bufferSize() { } Uint32 -SendBuffer::bufferSizeRemaining() { +SendBuffer::bufferSizeRemaining() const { return (sizeOfBuffer - dataSize); } diff --git a/ndb/src/common/transporter/SendBuffer.hpp b/ndb/src/common/transporter/SendBuffer.hpp index 63a01f3de24..7ebeb6d890e 100644 --- a/ndb/src/common/transporter/SendBuffer.hpp +++ b/ndb/src/common/transporter/SendBuffer.hpp @@ -51,7 +51,7 @@ public: bool initBuffer(Uint32 aRemoteNodeId); // Number of bytes remaining in the buffer - Uint32 bufferSizeRemaining(); + Uint32 bufferSizeRemaining() const; // Number of bytes of data in the buffer int bufferSize(); diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp index fd71cf71cd9..5db12d3985c 100644 --- a/ndb/src/common/transporter/TCP_Transporter.cpp +++ b/ndb/src/common/transporter/TCP_Transporter.cpp @@ -253,6 +253,11 @@ TCP_Transporter::sendIsPossible(struct timeval * timeout) { #endif } +Uint32 +TCP_Transporter::get_free_buffer() const +{ + return m_sendBuffer.bufferSizeRemaining(); +} Uint32 * TCP_Transporter::getWritePtr(Uint32 lenBytes, Uint32 prio){ diff --git a/ndb/src/common/transporter/TCP_Transporter.hpp b/ndb/src/common/transporter/TCP_Transporter.hpp index 9cd174150c1..df4149531b4 100644 --- a/ndb/src/common/transporter/TCP_Transporter.hpp +++ b/ndb/src/common/transporter/TCP_Transporter.hpp @@ -101,6 +101,7 @@ private: */ virtual void updateReceiveDataPtr(Uint32 bytesRead); + virtual Uint32 get_free_buffer() const; protected: /** * Setup client/server and perform connect/accept diff --git a/ndb/src/common/transporter/Transporter.hpp b/ndb/src/common/transporter/Transporter.hpp index 53414f1179d..8c5e96226a3 100644 --- a/ndb/src/common/transporter/Transporter.hpp +++ b/ndb/src/common/transporter/Transporter.hpp @@ -86,6 +86,8 @@ public: m_socket_client->set_port(port); }; + virtual Uint32 get_free_buffer() const = 0; + protected: Transporter(TransporterRegistry &, TransporterType, diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index f331b1660c1..5ffd3ac334e 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -558,6 +558,18 @@ TransporterRegistry::removeTransporter(NodeId nodeId) { theTransporters[nodeId] = NULL; } +Uint32 +TransporterRegistry::get_free_buffer(Uint32 node) const +{ + Transporter *t; + if(likely((t = theTransporters[node]) != 0)) + { + return t->get_free_buffer(); + } + return 0; +} + + SendStatus TransporterRegistry::prepareSend(const SignalHeader * const signalHeader, Uint8 prio, diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index fdff2702bec..327fcc33aff 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -1676,13 +1676,30 @@ Backup::execWAIT_GCP_CONF(Signal* signal){ ptr.p->masterData.sendCounter= 0; ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ; nextFragment(signal, ptr); + return; } else { jam(); - CRASH_INSERTION((10009)); - ptr.p->stopGCP = gcp; - sendDropTrig(signal, ptr); // regular dropping of triggers - }//if + if(gcp >= ptr.p->startGCP + 3) + { + CRASH_INSERTION((10009)); + ptr.p->stopGCP = gcp; + sendDropTrig(signal, ptr); // regular dropping of triggers + return; + }//if + + /** + * Make sure that we got entire stopGCP + */ + WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend(); + req->senderRef = reference(); + req->senderData = ptr.i; + req->requestType = WaitGCPReq::CompleteForceStart; + sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal, + WaitGCPReq::SignalLength,JBB); + return; + } } + /***************************************************************************** * * Master functionallity - Backup fragment diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 0054b935cdb..24f9715c8b4 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -1668,7 +1668,7 @@ void Dbacc::initOpRec(Signal* signal) void Dbacc::sendAcckeyconf(Signal* signal) { signal->theData[0] = operationRecPtr.p->userptr; - signal->theData[1] = operationRecPtr.p->insertIsDone; + signal->theData[1] = operationRecPtr.p->operation; signal->theData[2] = operationRecPtr.p->fid; signal->theData[3] = operationRecPtr.p->localdata[0]; signal->theData[4] = operationRecPtr.p->localdata[1]; @@ -1754,6 +1754,11 @@ void Dbacc::execACCKEYREQ(Signal* signal) case ZWRITE: case ZSCAN_OP: if (!tgeLocked){ + if(operationRecPtr.p->operation == ZWRITE) + { + jam(); + operationRecPtr.p->operation = ZUPDATE; + } sendAcckeyconf(signal); if (operationRecPtr.p->dirtyRead == ZFALSE) { /*---------------------------------------------------------------*/ @@ -2279,6 +2284,12 @@ Uint32 Dbacc::placeWriteInLockQueue(Signal* signal) return ZWRITE_ERROR; }//if + if(operationRecPtr.p->operation == ZWRITE) + { + operationRecPtr.p->operation = + (mlpqOperPtr.p->operation == ZDELETE) ? ZINSERT : ZUPDATE; + } + operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0]; operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1]; operationRecPtr.p->prevParallelQue = mlpqOperPtr.i; diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index b2ed7acd347..03309f3ac67 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -5072,6 +5072,7 @@ Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr) * And reset nextLcp */ replicaPtr.p->nextLcp = 0; + replicaPtr.p->noCrashedReplicas = 0; }//if }//for }//for diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 138a2526804..725ea04c148 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -3905,20 +3905,21 @@ void Dblqh::execACCKEYCONF(Signal* signal) * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A * TABLE. - * ------------------------------------------------------------------------ */ - if (regTcPtr->operation == ZWRITE) { - if (signal->theData[1] > 0) { - /* -------------------------------------------------------------------- - * ACC did perform an insert and thus we should indicate that the WRITE - * is an INSERT otherwise it is an UPDATE. - * -------------------------------------------------------------------- */ - jam(); - regTcPtr->operation = ZINSERT; - } else { - jam(); - tcConnectptr.p->operation = ZUPDATE; - }//if + * ----------------------------------------------------------------------- */ + if (regTcPtr->operation == ZWRITE) + { + Uint32 op= signal->theData[1]; + if(likely(op == ZINSERT || op == ZUPDATE)) + { + regTcPtr->operation = op; + } + else + { + warningEvent("Convering %d to ZUPDATE", op); + regTcPtr->operation = ZUPDATE; + } }//if + ndbrequire(localKeyFlag == 1); localKey2 = localKey1 & MAX_TUPLES_PER_PAGE; localKey1 = localKey1 >> MAX_TUPLES_BITS; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp index 6527864135b..6a478bea917 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp @@ -133,6 +133,9 @@ void Dbtup::sendReadAttrinfo(Signal* signal, Uint32 ToutBufIndex, const Operationrec * const regOperPtr) { + if(ToutBufIndex == 0) + return; + const BlockReference recBlockref = regOperPtr->recBlockref; const Uint32 sig0 = regOperPtr->tcOperationPtr; const Uint32 sig1 = regOperPtr->transid1; diff --git a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp index 9750e1c5179..6f848d7fe16 100644 --- a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp @@ -247,10 +247,10 @@ Ndbfs::readWriteRequest(int action, Signal * signal) AsyncFile* openFile = theOpenFiles.find(filePointer); const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsRWReq->varIndex]; - unsigned int tPageSize; - unsigned int tClusterSize; - unsigned int tNRR; - unsigned int tPageOffset; + UintPtr tPageSize; + UintPtr tClusterSize; + UintPtr tNRR; + UintPtr tPageOffset; char* tWA; FsRef::NdbfsErrorCodeType errorCode; @@ -294,8 +294,8 @@ Ndbfs::readWriteRequest(int action, Signal * signal) jam(); for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) { jam(); - const Uint32 varIndex = fsRWReq->data.listOfPair[i].varIndex; - const Uint32 fileOffset = fsRWReq->data.listOfPair[i].fileOffset; + const UintPtr varIndex = fsRWReq->data.listOfPair[i].varIndex; + const UintPtr fileOffset = fsRWReq->data.listOfPair[i].fileOffset; if (varIndex >= tNRR) { jam(); errorCode = FsRef::fsErrInvalidParameters; @@ -316,8 +316,8 @@ Ndbfs::readWriteRequest(int action, Signal * signal) errorCode = FsRef::fsErrInvalidParameters; goto error; }//if - const Uint32 varIndex = fsRWReq->data.arrayOfPages.varIndex; - const Uint32 fileOffset = fsRWReq->data.arrayOfPages.fileOffset; + const UintPtr varIndex = fsRWReq->data.arrayOfPages.varIndex; + const UintPtr fileOffset = fsRWReq->data.arrayOfPages.fileOffset; request->par.readWrite.pages[0].offset = fileOffset * tPageSize; request->par.readWrite.pages[0].size = tPageSize * fsRWReq->numberOfPages; @@ -334,7 +334,7 @@ Ndbfs::readWriteRequest(int action, Signal * signal) for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) { jam(); - Uint32 varIndex = fsRWReq->data.listOfMemPages.varIndex[i]; + UintPtr varIndex = fsRWReq->data.listOfMemPages.varIndex[i]; if (varIndex >= tNRR) { jam(); diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 67bf09fab10..b1fe0735612 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1668,7 +1668,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { false, ConfigInfo::CI_INT, "256K", - "16K", + "64K", STR_VALUE(MAX_INT_RNIL) }, { @@ -1856,7 +1856,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { false, ConfigInfo::CI_INT, "1M", - "4K", + "64K", STR_VALUE(MAX_INT_RNIL) }, { diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp index da9d5b70d47..ccc45a04824 100644 --- a/ndb/src/ndbapi/DictCache.cpp +++ b/ndb/src/ndbapi/DictCache.cpp @@ -24,7 +24,8 @@ Ndb_local_table_info * Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz) { - Uint32 tot_size= sizeof(NdbTableImpl *) + ((sz+7) & ~7); // round to Uint64 + Uint32 tot_size= sizeof(Ndb_local_table_info) - sizeof(Uint64) + + ((sz+7) & ~7); // round to Uint64 void *data= malloc(tot_size); if (data == 0) return 0; diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 58c08a93e61..ca31c345396 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -33,7 +33,7 @@ public: static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0); static void destroy(Ndb_local_table_info *); NdbTableImpl *m_table_impl; - Uint64 m_local_data[1]; + Uint64 m_local_data[1]; // Must be last member. Used to access extra space. private: Ndb_local_table_info(NdbTableImpl *table_impl); ~Ndb_local_table_info(); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index baf5c7e5c83..6ecaf54b888 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1605,6 +1605,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, bool haveAutoIncrement = false; Uint64 autoIncrementValue = 0; + Uint32 distKeys= 0; for(i = 0; im_autoIncrementInitialValue; - } + } + if (col->m_distributionKey) + distKeys++; } // Check max length of frm data @@ -1649,7 +1652,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, abort(); } - int distKeys= impl.m_noOfDistributionKeys; + if (distKeys == impl.m_noOfKeys) + distKeys= 0; + impl.m_noOfDistributionKeys= distKeys; + for(i = 0; im_pk; tmpAttr.AttributeNullableFlag = col->m_nullable; - tmpAttr.AttributeDKey = col->m_distributionKey; + tmpAttr.AttributeDKey = distKeys ? col->m_distributionKey : 0; tmpAttr.AttributeExtType = (Uint32)col->m_type; tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF); diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index 4200300615d..58a816e3c1a 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -104,8 +104,9 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) { Uint32 tTransId1, tTransId2; Uint32 tReqInfo; - Uint32 tInterpretInd = theInterpretIndicator; - + Uint8 tInterpretInd = theInterpretIndicator; + Uint8 tDirtyIndicator = theDirtyIndicator; + Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len; theErrorLine = 0; if (tInterpretInd != 1) { @@ -123,7 +124,13 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) if (tStatus != GetValue) { setErrorCodeAbort(4116); return -1; - }//if + } + else if(unlikely(tDirtyIndicator && tTotalCurrAI_Len == 0)) + { + getValue(NdbDictionary::Column::FRAGMENT); + tTotalCurrAI_Len = theTotalCurrAI_Len; + assert(theTotalCurrAI_Len); + } } else { setErrorCodeAbort(4005); return -1; @@ -132,6 +139,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) if (prepareSendInterpreted() == -1) { return -1; }//if + tTotalCurrAI_Len = theTotalCurrAI_Len; }//if //------------------------------------------------------------- @@ -140,7 +148,6 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) //------------------------------------------------------------- TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend()); - Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len; Uint32 tTableId = m_currentTable->m_tableId; Uint32 tSchemaVersion = m_currentTable->m_version; @@ -188,7 +195,6 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) tcKeyReq->setStartFlag(tReqInfo, tStartIndicator); tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator); - Uint8 tDirtyIndicator = theDirtyIndicator; OperationType tOperationType = theOperationType; Uint32 tTupKeyLen = theTupKeyLen; Uint8 abortOption = diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 4867ea11a9a..65324af6fe6 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -866,6 +866,112 @@ int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){ return result; } + +int runReadWithoutGetValue(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + HugoOperations hugoOps(*pTab); + + Ndb* pNdb = GETNDB(step); + Uint32 lm; + + for(Uint32 cm= 0; cm < 2; cm++) + { + for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++) + { + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->readTuple((NdbOperation::LockMode)lm) != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + // Dont' call any getValues + + // Execute should work + int check = pCon->execute(cm == 0 ? NoCommit : Commit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + pNdb->closeTransaction(pCon); + } + } + + /** + * Now test scans + */ + for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++) + { + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if ((pOp->readTuples((NdbOperation::LockMode)lm)) != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + + // Dont' call any getValues + + // Execute should work + int check = pCon->execute(NoCommit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + int res; + while((res = pOp->nextResult()) == 0); + pNdb->closeTransaction(pCon); + + if(res != 1) + result = NDBT_FAILED; + } + + return result; +} + + int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; const NdbDictionary::Table* pTab = ctx->getTab(); @@ -931,6 +1037,239 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + HugoOperations hugoOps(*pTab); + + Ndb* pNdb = GETNDB(step); + Uint32 lm; + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->readTuple(NdbOperation::LM_Exclusive) != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() != true){ + if (pOp->getValue(pTab->getColumn(a)->getName()) == NULL) { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + int check = pCon->execute(NoCommit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->deleteTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + check = pCon->execute(NoCommit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->writeTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() != true){ + if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0) + { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + check = pCon->execute(NoCommit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->writeTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() != true){ + if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0) + { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + check = pCon->execute(NoCommit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + check = pCon->execute(Rollback); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + pCon->close(); + + pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + + if (pOp->writeTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() != true){ + if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0) + { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + } + + check = pCon->execute(Commit); + if (check == 0){ + ndbout << "execute worked" << endl; + } else { + ERR(pCon->getNdbError()); + result = NDBT_FAILED; + } + + return result; +} + + NDBT_TESTSUITE(testNdbApi); TESTCASE("MaxNdb", @@ -1000,6 +1339,18 @@ TESTCASE("NdbErrorOperation", "Test that NdbErrorOperation is properly set"){ INITIALIZER(runCheckGetNdbErrorOperation); } +TESTCASE("ReadWithoutGetValue", + "Test that it's possible to perform read wo/ getvalue's\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runReadWithoutGetValue); + FINALIZER(runClearTable); +} +TESTCASE("Bug_11133", + "Test ReadEx-Delete-Write\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runBug_11133); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testNdbApi); int main(int argc, const char** argv){ diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index b2d809ef6be..ce9f97a9cb2 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -512,6 +512,14 @@ max-time: 500 cmd: testNdbApi args: -n UpdateWithoutValues T6 +max-time: 500 +cmd: testNdbApi +args: -n ReadWithoutGetValue + +max-time: 500 +cmd: testNdbApi +args: -n Bug_11133 T1 + #max-time: 500 #cmd: testInterpreter #args: T1 diff --git a/ndb/test/run-test/ndb-autotest.sh b/ndb/test/run-test/ndb-autotest.sh index f1c83f079cd..09087a8a8c7 100755 --- a/ndb/test/run-test/ndb-autotest.sh +++ b/ndb/test/run-test/ndb-autotest.sh @@ -1,10 +1,20 @@ #!/bin/sh +############################################################# +# This script created by Jonas does the following # +# Cleans up clones and pevious builds, pulls new clones, # +# builds, deploys, configures the tests and launches ATRT # +############################################################# + +############### +#Script setup # +############## save_args=$* VERSION="ndb-autotest.sh version 1.04" DATE=`date '+%Y-%m-%d'` -export DATE +HOST=`hostname` +export DATE HOST set -e ulimit -Sc unlimited @@ -14,21 +24,33 @@ echo "`date` starting: $*" RSYNC_RSH=ssh export RSYNC_RSH +verbose=0 do_clone=yes build=yes deploy=yes +run_test=yes +config=yes +report=yes clone=5.0-ndb RUN="daily-basic daily-devel" conf=autotest.conf +############################ +# Read command line entries# +############################ + while [ "$1" ] do case "$1" in --no-clone) do_clone="";; --no-build) build="";; --no-deploy) deploy="";; - --clone=*) clone=`echo $1 | sed s/--clone=//`;; + --no-test) run_test="";; + --no-config) config="";; + --no-report) report="";; + --verbose) verbose=`expr $verbose + 1`;; + --clone=*) clone=`echo $1 | sed s/--clone=//`;; --conf=*) conf=`echo $1 | sed s/--conf=//`;; --version) echo $VERSION; exit;; *) RUN=$*;; @@ -36,6 +58,12 @@ do shift done +################################# +#Make sure the configfile exists# +#if it does not exit. if it does# +# (.) load it # +################################# + if [ -f $conf ] then . $conf @@ -44,51 +72,119 @@ else exit fi -env +############################### +# Validate that all interesting +# variables where set in conf +############################### +vars="target base_dir src_clone_base install_dir build_dir hosts configure" +if [ "$report" ] +then + vars="$vars result_host result_path" +fi +for i in $vars +do + t=`echo echo \\$$i` + if [ -z `eval $t` ] + then + echo "Invalid config: $conf, variable $i is not set" + exit + fi +done + +############################### +#Print out the enviroment vars# +############################### + +if [ $verbose -gt 0 ] +then + env +fi + +#################################### +# Setup the lock file name and path# +# Setup the clone source location # +#################################### LOCK=$HOME/.autotest-lock src_clone=$src_clone_base-$clone +####################################### +# Check to see if the lock file exists# +# If it does exit. # +####################################### + if [ -f $LOCK ] then echo "Lock file exists: $LOCK" exit 1 fi +####################################### +# If the lock file does not exist then# +# create it with date and run info # +####################################### + echo "$DATE $RUN" > $LOCK + +############################# +#If any errors here down, we# +# trap them, and remove the # +# Lock file before exit # +############################# + trap "rm -f $LOCK" ERR +# You can add more to this path# +################################ + dst_place=${build_dir}/clone-mysql-$clone-$DATE +######################################### +# Delete source and pull down the latest# +######################################### + if [ "$do_clone" ] then rm -rf $dst_place bk clone $src_clone $dst_place fi +########################################## +# Build the source, make installs, and # +# create the database to be rsynced # +########################################## + if [ "$build" ] then cd $dst_place - rm -rf $run_dir/* - aclocal; autoheader; autoconf; automake - if [ -d storage ] + rm -rf $install_dir/* + if [ -x BUILD/autorun.sh ] then - (cd storage/innobase; aclocal; autoheader; autoconf; automake) - (cd storage/bdb/dist; sh s_all) + ./BUILD/autorun.sh else - (cd innobase; aclocal; autoheader; autoconf; automake) - (cd bdb/dist; sh s_all) + aclocal; autoheader; autoconf; automake + if [ -d storage ] + then + (cd storage/innobase; aclocal; autoheader; autoconf; automake) + (cd storage/bdb/dist; sh s_all) + else + (cd innobase; aclocal; autoheader; autoconf; automake) + (cd bdb/dist; sh s_all) + fi fi - eval $configure --prefix=$run_dir + eval $configure --prefix=$install_dir make make install - (cd $run_dir; ./bin/mysql_install_db) + (cd $install_dir; ./bin/mysql_install_db) # This will be rsynced to all fi -### -# check script version -# -script=$run_dir/mysql-test/ndb/ndb-autotest.sh +################################ +# check script version. If the # +# version is old, replace it # +# and restart # +################################ + +script=$install_dir/mysql-test/ndb/ndb-autotest.sh if [ -x $script ] then $script --version > /tmp/version.$$ @@ -100,21 +196,34 @@ rm -f /tmp/version.$$ if [ $match -eq 0 ] then echo "Incorrect script version...restarting" - cp $run_dir/mysql-test/ndb/ndb-autotest.sh /tmp/at.$$.sh - rm -rf $run_dir $dst_place + cp $install_dir/mysql-test/ndb/ndb-autotest.sh /tmp/at.$$.sh + rm -rf $install_dir $dst_place sh /tmp/at.$$.sh $save_args exit fi -# Check that all interesting files are present -test_dir=$run_dir/mysql-test/ndb +############################################### +# Check that all interesting files are present# +############################################### + +test_dir=$install_dir/mysql-test/ndb atrt=$test_dir/atrt html=$test_dir/make-html-reports.sh -mkconfig=$run_dir/mysql-test/ndb/make-config.sh +mkconfig=$install_dir/mysql-test/ndb/make-config.sh -PATH=$run_dir/bin:$test_dir:$PATH +########################## +#Setup bin and test paths# +########################## + +PATH=$install_dir/bin:$test_dir:$PATH export PATH +########################### +# This will filter out all# +# the host that did not # +# respond. Called below # +########################### + filter(){ neg=$1 shift @@ -125,18 +234,22 @@ filter(){ done } -### -# check ndb_cpcc fail hosts -# +############################ +# check ndb_cpcc fail hosts# +############################ ndb_cpcc $hosts | awk '{ if($1=="Failed"){ print;}}' > /tmp/failed.$DATE filter /tmp/failed.$DATE $hosts > /tmp/hosts.$DATE hosts=`cat /tmp/hosts.$DATE` +############################# +# Push bin and test to hosts# +############################# + if [ "$deploy" ] then for i in $hosts - do - rsync -a --delete --force --ignore-errors $run_dir/ $i:$run_dir + do + rsync -a --delete --force --ignore-errors $install_dir/ $i:$install_dir ok=$? if [ $ok -ne 0 ] then @@ -145,7 +258,6 @@ then fi done fi -rm -f /tmp/build.$DATE.tgz ### # handle scp failed hosts @@ -154,9 +266,11 @@ filter /tmp/failed.$DATE $hosts > /tmp/hosts.$DATE hosts=`cat /tmp/hosts.$DATE` cat /tmp/failed.$DATE > /tmp/filter_hosts.$$ -### -# functions for running atrt -# +############################# +# Function for replacing the# +# choose host with real host# +# names. Note $$ = PID # +############################# choose(){ SRC=$1 TMP1=/tmp/choose.$$ @@ -177,16 +291,25 @@ choose(){ } choose_conf(){ - host=`hostname -s` - if [ -f $test_dir/conf-$1-$host.txt ] - then + if [ -f $test_dir/conf-$1-$HOST.txt ] + then + echo "$test_dir/conf-$1-$HOST.txt" echo "$test_dir/conf-$1-$host.txt" elif [ -f $test_dir/conf-$1.txt ] then echo "$test_dir/conf-$1.txt" + else + echo "Unable to find conf file looked for" 1>&2 + echo "$testdir/conf-$1-host.txt and" 1>&2 + echo "$testdir/conf-$1.txt" 1>&2 + exit fi } - +###################################### +# Starts ATRT and gives it the right # +# command line options. after it # +# Gathers results and moves them # +###################################### start(){ rm -rf report.txt result* log.txt $atrt -v -v -r -R --log-file=log.txt --testcase-file=$test_dir/$2-tests.txt & @@ -202,17 +325,34 @@ start(){ cd .. p2=`pwd` cd .. - tar cfz /tmp/res.$$.tgz `basename $p2`/$DATE - scp /tmp/res.$$.tgz $result_host:$result_path/res.$DATE.`hostname -s`.$2.$$.tgz - rm -f /tmp/res.$$.tgz + if [ "$report" ] + then + tar cfz /tmp/res.$2.$$.tgz `basename $p2`/$DATE + scp /tmp/res.$2.$$.tgz \ + $result_host:$result_path/res.$DATE.$HOST.$2.$$.tgz + if [ $? -eq 0 ] + then + rm -f /tmp/res.$2.$$.tgz + fi + fi } +######################################### +# Count how many computers we have ready# +######################################### + count_hosts(){ - cnt=`grep "CHOOSE_host" $1 | - awk '{for(i=1; i<=NF;i++) if(match($i, "CHOOSE_host") > 0) print $i;}' | - sort | uniq | wc -l` + cnt=`grep "CHOOSE_host" $1 | awk '{for(i=1; i<=NF;i++) \ + if(match($i, "CHOOSE_host") > 0) print $i;}' | sort | uniq | wc -l` echo $cnt } +####################################################### +# Calls: Choose # +# Choose_host # +# Count_host # +# start # +# for each directory in the $RUN variable # +####################################################### p=`pwd` for dir in $RUN @@ -223,26 +363,36 @@ do res_dir=$base_dir/result-$dir-mysql-$clone-$target/$DATE mkdir -p $run_dir $res_dir - rm -rf $res_dir/* $run_dir/* - - conf=`choose_conf $dir` - count=`count_hosts $conf` - avail_hosts=`filter /tmp/filter_hosts.$$ $hosts` - avail=`echo $avail_hosts | wc -w` - if [ $count -gt $avail ] + rm -rf $res_dir/* + cd $run_dir + + if [ "$config" ] then + rm -rf $run_dir/* + + conf=`choose_conf $dir` + count=`count_hosts $conf` + avail_hosts=`filter /tmp/filter_hosts.$$ $hosts` + avail=`echo $avail_hosts | wc -w` + if [ $count -gt $avail ] + then echo "Not enough hosts" echo "Needs: $count available: $avail ($avail_hosts)" break; - fi + fi - run_hosts=`echo $avail_hosts|awk '{for(i=1;i<='$count';i++)print $i;}'` - echo $run_hosts >> /tmp/filter_hosts.$$ + run_hosts=`echo $avail_hosts| \ + awk '{for(i=1;i<='$count';i++)print $i;}'` + echo $run_hosts >> /tmp/filter_hosts.$$ - cd $run_dir - choose $conf $run_hosts > d.tmp - $mkconfig d.tmp - start $dir-mysql-$clone-$target $dir $res_dir & + choose $conf $run_hosts > d.tmp + $mkconfig d.tmp + fi + + if [ "$run_test" ] + then + start $dir-mysql-$clone-$target $dir $res_dir & + fi done cd $p rm /tmp/filter_hosts.$$ diff --git a/ndb/test/tools/hugoLoad.cpp b/ndb/test/tools/hugoLoad.cpp index 7d9d0dafaff..1a229169650 100644 --- a/ndb/test/tools/hugoLoad.cpp +++ b/ndb/test/tools/hugoLoad.cpp @@ -30,10 +30,12 @@ int main(int argc, const char** argv){ const char* _tabname = NULL; int _help = 0; int _batch = 512; - + const char* db = 0; + struct getargs args[] = { { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, + { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); @@ -59,7 +61,7 @@ int main(int argc, const char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, "TEST_DB" ); + Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); diff --git a/ndb/test/tools/hugoPkUpdate.cpp b/ndb/test/tools/hugoPkUpdate.cpp index 6e7ff39f903..7d46ae95c29 100644 --- a/ndb/test/tools/hugoPkUpdate.cpp +++ b/ndb/test/tools/hugoPkUpdate.cpp @@ -33,7 +33,7 @@ int main(int argc, const char** argv){ int _loops = 1; int _abort = 0; int _batch = 0; - const char* _tabname = NULL; + const char* _tabname = NULL, *db = 0; int _help = 0; struct getargs args[] = { @@ -41,7 +41,8 @@ int main(int argc, const char** argv){ { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, // { "batch", 'b', arg_integer, &_batch, "batch value", "batch" }, { "records", 'r', arg_integer, &_records, "Number of records", "records" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } + { "usage", '?', arg_flag, &_help, "Print help", "" }, + { "database", 'd', arg_string, &db, "Database", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; @@ -62,7 +63,7 @@ int main(int argc, const char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, "TEST_DB" ); + Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp index 4f76362ecab..a345bb88d0e 100644 --- a/ndb/test/tools/hugoScanRead.cpp +++ b/ndb/test/tools/hugoScanRead.cpp @@ -33,7 +33,7 @@ int main(int argc, const char** argv){ int _loops = 1; int _abort = 0; int _parallelism = 1; - const char* _tabname = NULL; + const char* _tabname = NULL, *db = 0; int _help = 0; int lock = NdbOperation::LM_Read; int sorted = 0; @@ -45,7 +45,8 @@ int main(int argc, const char** argv){ { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, { "usage", '?', arg_flag, &_help, "Print help", "" }, { "lock", 'm', arg_integer, &lock, "lock mode", "" }, - { "sorted", 's', arg_flag, &sorted, "sorted", "" } + { "sorted", 's', arg_flag, &sorted, "sorted", "" }, + { "database", 'd', arg_string, &db, "Database", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; @@ -66,7 +67,7 @@ int main(int argc, const char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, "TEST_DB" ); + Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); diff --git a/ndb/test/tools/hugoScanUpdate.cpp b/ndb/test/tools/hugoScanUpdate.cpp index 88c343f8fd3..6960fa44b96 100644 --- a/ndb/test/tools/hugoScanUpdate.cpp +++ b/ndb/test/tools/hugoScanUpdate.cpp @@ -33,7 +33,7 @@ int main(int argc, const char** argv){ int _loops = 1; int _parallelism = 1; int _ver2 = 0; - const char* _tabname = NULL; + const char* _tabname = NULL, *db = 0; int _help = 0; struct getargs args[] = { @@ -42,7 +42,8 @@ int main(int argc, const char** argv){ { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, { "ver2", '2', arg_flag, &_ver2, "Use version 2 of scanUpdateRecords", "" }, { "ver2", '1', arg_negative_flag, &_ver2, "Use version 1 of scanUpdateRecords (default)", "" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } + { "usage", '?', arg_flag, &_help, "Print help", "" }, + { "database", 'd', arg_string, &db, "Database", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; @@ -63,7 +64,7 @@ int main(int argc, const char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, "TEST_DB" ); + Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); @@ -100,6 +101,7 @@ int main(int argc, const char** argv){ return NDBT_ProgramExit(NDBT_FAILED); } i++; + //NdbSleep_MilliSleep(300); } return NDBT_ProgramExit(NDBT_OK); diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index c350fb0a141..1008b166dfc 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -30,7 +30,8 @@ ndb_restore_SOURCES = restore/restore_main.cpp \ restore/consumer.cpp \ restore/consumer_restore.cpp \ restore/consumer_printer.cpp \ - restore/Restore.cpp + restore/Restore.cpp \ + ../test/src/NDBT_ResultRow.cpp $(tools_common_sources) include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapitools.mk.am diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp index fa616ee8fee..b53255820db 100644 --- a/ndb/tools/restore/Restore.cpp +++ b/ndb/tools/restore/Restore.cpp @@ -765,6 +765,7 @@ RestoreLogIterator::RestoreLogIterator(const RestoreMetaData & md) setLogFile(md, 0); m_count = 0; + m_last_gci = 0; } const LogEntry * @@ -772,7 +773,6 @@ RestoreLogIterator::getNextLogEntry(int & res) { // Read record length typedef BackupFormat::LogFile::LogEntry LogE; - Uint32 gcp= 0; LogE * logE= 0; Uint32 len= ~0; const Uint32 stopGCP = m_metaData.getStopGCP(); @@ -802,10 +802,10 @@ RestoreLogIterator::getNextLogEntry(int & res) { if(hasGcp){ len--; - gcp = ntohl(logE->Data[len-2]); + m_last_gci = ntohl(logE->Data[len-2]); } - } while(gcp > stopGCP + 1); - + } while(m_last_gci > stopGCP + 1); + m_logEntry.m_table = m_metaData.getTable(logE->TableId); switch(logE->TriggerEvent){ case TriggerEvent::TE_INSERT: @@ -925,19 +925,12 @@ operator<<(NdbOut& ndbout, const LogEntry& logE) return ndbout; } +#include NdbOut & operator<<(NdbOut& ndbout, const TableS & table){ - ndbout << endl << "Table: " << table.getTableName() << endl; - for (int j = 0; j < table.getNoOfAttributes(); j++) - { - const AttributeDesc * desc = table[j]; - ndbout << desc->m_column->getName() << ": " - << (Uint32) desc->m_column->getType(); - ndbout << " key: " << (Uint32) desc->m_column->getPrimaryKey(); - ndbout << " array: " << desc->arraySize; - ndbout << " size: " << desc->size << endl; - } // for + + ndbout << (* (NDBT_Table*)table.m_dictTable) << endl; return ndbout; } diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp index d7f6e3b7799..85793baf9df 100644 --- a/ndb/tools/restore/Restore.hpp +++ b/ndb/tools/restore/Restore.hpp @@ -361,6 +361,7 @@ private: const RestoreMetaData & m_metaData; Uint32 m_count; + Uint32 m_last_gci; LogEntry m_logEntry; public: RestoreLogIterator(const RestoreMetaData &); diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index d72b82569e2..b20f9fd3204 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -526,7 +526,14 @@ BackupRestore::logEntry(const LogEntry & tup) << " Exiting..."; exit(-1); } + + if (check != 0) + { + err << "Error defining op: " << trans->getNdbError() << endl; + exit(-1); + } // if + Bitmask<4096> keys; for (Uint32 i= 0; i < tup.size(); i++) { const AttributeS * attr = tup[i]; @@ -539,9 +546,21 @@ BackupRestore::logEntry(const LogEntry & tup) const Uint32 length = (size / 8) * arraySize; if (attr->Desc->m_column->getPrimaryKey()) - op->equal(attr->Desc->attrId, dataPtr, length); + { + if(!keys.get(attr->Desc->attrId)) + { + keys.set(attr->Desc->attrId); + check= op->equal(attr->Desc->attrId, dataPtr, length); + } + } else - op->setValue(attr->Desc->attrId, dataPtr, length); + check= op->setValue(attr->Desc->attrId, dataPtr, length); + + if (check != 0) + { + err << "Error defining op: " << trans->getNdbError() << endl; + exit(-1); + } // if } const int ret = trans->execute(NdbTransaction::Commit); @@ -550,18 +569,25 @@ BackupRestore::logEntry(const LogEntry & tup) // Both insert update and delete can fail during log running // and it's ok // TODO: check that the error is either tuple exists or tuple does not exist? + bool ok= false; + NdbError errobj= trans->getNdbError(); switch(tup.m_type) { case LogEntry::LE_INSERT: + if(errobj.status == NdbError::PermanentError && + errobj.classification == NdbError::ConstraintViolation) + ok= true; break; case LogEntry::LE_UPDATE: - break; case LogEntry::LE_DELETE: + if(errobj.status == NdbError::PermanentError && + errobj.classification == NdbError::NoDataFound) + ok= true; break; } - if (false) + if (!ok) { - err << "execute failed: " << trans->getNdbError() << endl; + err << "execute failed: " << errobj << endl; exit(-1); } } diff --git a/netware/BUILD/compile-linux-tools b/netware/BUILD/compile-linux-tools index c21857146e0..c85fced5739 100755 --- a/netware/BUILD/compile-linux-tools +++ b/netware/BUILD/compile-linux-tools @@ -30,6 +30,10 @@ rm -f */*.linux # build tools only make clean all-local + +# Create mysql_version.h which was deleted my previous step +./config.status include/mysql_version.h + (cd dbug; make libdbug.a) (cd strings; make libmystrings.a) (cd mysys; make libmysys.a) @@ -56,3 +60,5 @@ cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux cp sql/gen_lex_hash sql/gen_lex_hash.linux cp strings/conf_to_src strings/conf_to_src.linux +# Delete mysql_version.h +rm -f include/mysql_version.h diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index 2bd59f97114..60ef428b2a9 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -22,6 +22,11 @@ rm -rf Makefile.in.bk # run auto tools . $path/compile-AUTOTOOLS +# For NetWare there is no comp_err but comp_err.linux +sed -e "s/comp_err/comp_err.linux/g" extra/Makefile.am > extra/Makefile.am.$$ +sed -e "s/replace comp_err.linux/replace comp_err/g" extra/Makefile.am.$$ > extra/Makefile.am +rm extra/Makefile.am.$$ + # configure ./configure $base_configs $extra_configs diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index 0acfd3aaf8f..7f89a8faf7f 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -6,7 +6,7 @@ # the default is "F:/mydev" export MYDEV="F:/mydev" -export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.1.4;$MYDEV" +export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.1.4;$MYDEV/mysql-VERSION/include;$MYDEV" export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.1.4;$MYDEV/openssl;$MYDEV/mysql-VERSION/netware/BUILD" export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a;neb.imp;zPublics.imp;knetware.imp" @@ -19,9 +19,9 @@ export AR='mwldnlm' export AR_FLAGS='-type library -o' export AS='mwasmnlm' export CC='mwccnlm -gccincludes' -export CFLAGS='-O3 -align 8 -proc 686 -relax_pointers -dialect c' +export CFLAGS='-enum int -O3 -align 8 -proc 686 -relax_pointers -dialect c' export CXX='mwccnlm -gccincludes' -export CXXFLAGS='-O3 -align 8 -proc 686 -relax_pointers -dialect c++ -bool on -wchar_t on -D_WCHAR_T' +export CXXFLAGS='-enum int -O3 -align 8 -proc 686 -relax_pointers -dialect c++ -bool on -wchar_t on -D_WCHAR_T' export LD='mwldnlm' export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -map -flags pseudopreemption' export RANLIB=: diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index d8cfb79c1cb..45b7c4719fb 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -1162,6 +1162,8 @@ void setup(char *file) setenv("MYSQL_TCP_PORT", "3306", 1); snprintf(file_path, PATH_MAX*2, "%s/mysql_client_test --no-defaults --testcase--user=root --port=%u ", bin_dir, master_port); setenv("MYSQL_CLIENT_TEST",file_path,1); + snprintf(file_path, PATH_MAX*2, "%s/mysql --no-defaults --user=root --port=%u ", bin_dir, master_port); + setenv("MYSQL",file_path,1); } /****************************************************************************** diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c index a307b52bb7e..3a1672fdf61 100644 --- a/netware/mysqld_safe.c +++ b/netware/mysqld_safe.c @@ -666,7 +666,6 @@ void mysql_start(int argc, char *argv[]) if (!strnicmp(argv[i], private_options[j], strlen(private_options[j]))) { skip= TRUE; - consoleprintf("The argument skipped is %s\n", argv[i]); break; } } @@ -674,7 +673,6 @@ void mysql_start(int argc, char *argv[]) if (!skip) { add_arg(&al, "%s", argv[i]); - consoleprintf("The final argument is %s\n", argv[i]); } } // spawn diff --git a/scripts/Makefile.am b/scripts/Makefile.am index b2fef9acadf..225e8bdccbb 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -33,8 +33,6 @@ bin_SCRIPTS = @server_scripts@ \ mysql_explain_log \ mysql_tableinfo \ mysqld_multi \ - make_win_src_distribution \ - make_win_binary_distribution \ mysql_create_system_tables EXTRA_SCRIPTS = make_binary_distribution.sh \ @@ -86,6 +84,7 @@ CLEANFILES = @server_scripts@ \ mysqldumpslow \ mysqld_multi \ make_win_src_distribution \ + make_win_binary_distribution \ mysql_create_system_tables DISTCLEANFILES = mysqlbug diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 064c5e63f40..74734f4dd5f 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -226,7 +226,7 @@ $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \ $BASE/mysql-test/std_data $CP mysql-test/t/*.test mysql-test/t/*.disabled mysql-test/t/*.opt \ - mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t + mysql-test/t/*.slave-mi mysql-test/t/*.sh mysql-test/t/*.sql $BASE/mysql-test/t $CP mysql-test/r/*.result mysql-test/r/*.require \ $BASE/mysql-test/r diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 632174dc41a..1c5cd6a4faf 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -746,9 +746,15 @@ sub record_log_pos { my ($file,$position) = get_row( $dbh, "show master status" ); die "master status is undefined" if !defined $file || !defined $position; - my ($master_host, undef, undef, undef, $log_file, $log_pos ) - = get_row( $dbh, "show slave status" ); - + my $row_hash = get_row_hash( $dbh, "show slave status" ); + my ($master_host, $log_file, $log_pos ); + if ( $dbh->{mysql_serverinfo} =~ /^3\.23/ ) { + ($master_host, $log_file, $log_pos ) + = @{$row_hash}{ qw / Master_Host Log_File Pos / }; + } else { + ($master_host, $log_file, $log_pos ) + = @{$row_hash}{ qw / Master_Host Master_Log_File Read_Master_Log_Pos / }; + } my $hostname = hostname(); $dbh->do( qq{ replace into $table_name @@ -773,6 +779,14 @@ sub get_row { return $sth->fetchrow_array(); } +sub get_row_hash { + my ( $dbh, $sql ) = @_; + + my $sth = $dbh->prepare($sql); + $sth->execute; + return $sth->fetchrow_hashref(); +} + sub scan_raid_dir { my ( $r_db_files, $data_dir, @raid_dir ) = @_; diff --git a/server-tools/instance-manager/buffer.h b/server-tools/instance-manager/buffer.h index a94047b11a5..e63d725f508 100644 --- a/server-tools/instance-manager/buffer.h +++ b/server-tools/instance-manager/buffer.h @@ -52,7 +52,7 @@ public: ~Buffer() { - free(buffer); + my_free(buffer, MYF(0)); } public: diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc index 77c26fd28de..b5d88873054 100644 --- a/server-tools/instance-manager/commands.cc +++ b/server-tools/instance-manager/commands.cc @@ -203,15 +203,14 @@ int Show_instance_status::execute(struct st_net *net, if (!(instance= instance_map->find(instance_name, strlen(instance_name)))) goto err; if (instance->is_running()) - { store_to_string(&send_buff, (char*) "online", &position); - store_to_string(&send_buff, "unknown", &position); - } else - { store_to_string(&send_buff, (char*) "offline", &position); + + if (instance->options.mysqld_version) + store_to_string(&send_buff, instance->options.mysqld_version, &position); + else store_to_string(&send_buff, (char*) "unknown", &position); - } if (send_buff.is_error() || @@ -645,10 +644,6 @@ Set_option::Set_option(Instance_map *instance_map_arg, { strmake(option, option_arg, option_len_arg); strmake(option_value, option_value_arg, option_value_len_arg); -/* strncpy(option, option_arg, option_len_arg); - option[option_len_arg]= 0; - strncpy(option_value, option_value_arg, option_value_len_arg); - option_value[option_value_len_arg]= 0; */ } else { diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 615f16f9e22..2b25c74439e 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -326,8 +326,8 @@ int Instance::init(const char *name_arg) int Instance::complete_initialization(Instance_map *instance_map_arg, const char *mysqld_path, - int only_instance) + uint instance_type) { instance_map= instance_map_arg; - return options.complete_initialization(mysqld_path, only_instance); + return options.complete_initialization(mysqld_path, instance_type); } diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h index 14ef5cfcfb9..39a2b8ee846 100644 --- a/server-tools/instance-manager/instance.h +++ b/server-tools/instance-manager/instance.h @@ -33,7 +33,7 @@ public: ~Instance(); int init(const char *name); int complete_initialization(Instance_map *instance_map_arg, - const char *mysqld_path, int only_instance= 0); + const char *mysqld_path, uint instance_type); bool is_running(); int start(); diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc index 792ffff5fb6..fa8a5d58114 100644 --- a/server-tools/instance-manager/instance_map.cc +++ b/server-tools/instance-manager/instance_map.cc @@ -202,14 +202,14 @@ int Instance_map::complete_initialization() hash_free should handle it's deletion => goto err, not err_instance. */ - if (instance->complete_initialization(this, mysqld_path, 1)) + if (instance->complete_initialization(this, mysqld_path, DEFAULT_SINGLE_INSTANCE)) goto err; } else while (i < hash.records) { instance= (Instance *) hash_element(&hash, i); - if (instance->complete_initialization(this, mysqld_path)) + if (instance->complete_initialization(this, mysqld_path, USUAL_INSTANCE)) goto err; i++; } diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index c8288c35a6f..0ae364e5b2d 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -27,6 +27,39 @@ #include #include +#ifdef __WIN__ +#define NEWLINE_LEN 2 +#else +#define NEWLINE_LEN 1 +#endif + + +/* Create "mysqld ..." command in the buffer */ + +static inline int create_mysqld_command(Buffer *buf, + const char *mysqld_path_str, + uint mysqld_path_len, + const char *option, + uint option_len) +{ + int position= 0; + + if (buf->get_size()) /* malloc succeeded */ + { + buf->append(position, mysqld_path_str, mysqld_path_len); + position+= mysqld_path_len; + /* here the '\0' character is copied from the option string */ + buf->append(position, option, option_len); + + if (buf->is_error()) + return 1; + } + else + return 1; + + return 0; +} + /* Get compiled-in value of default_option @@ -50,25 +83,19 @@ int Instance_options::get_default_option(char *result, size_t result_len, const char *option_name) { - int position= 0; int rc= 1; char verbose_option[]= " --no-defaults --verbose --help"; - Buffer cmd(strlen(mysqld_path) + sizeof(verbose_option) + 1); - if (cmd.get_size()) /* malloc succeeded */ - { - cmd.append(position, mysqld_path, strlen(mysqld_path)); - position+= strlen(mysqld_path); - cmd.append(position, verbose_option, sizeof(verbose_option) - 1); - position+= sizeof(verbose_option) - 1; - cmd.append(position, "\0", 1); + /* reserve space fot the path + option + final '\0' */ + Buffer cmd(mysqld_path_len + sizeof(verbose_option)); - if (cmd.is_error()) - goto err; - /* get the value from "mysqld --help --verbose" */ - rc= parse_output_and_get_value(cmd.buffer, option_name + 2, - result, result_len); - } + if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len, + verbose_option, sizeof(verbose_option))) + goto err; + + /* +2 eats first "--" from the option string (E.g. "--datadir") */ + rc= parse_output_and_get_value(cmd.buffer, option_name + 2, + result, result_len, GET_VALUE); return rc; err: @@ -77,17 +104,61 @@ err: /* - Get compiled-in value of default_option + Fill mysqld_version option (used at initialization stage) SYNOPSYS - get_default_option() - result buffer to put found value - result_len buffer size - option_name the name of the option, prefixed with "--" + fill_instance_version() DESCRIPTION - Get compile-in value of requested option from server + Get mysqld version string from "mysqld --version" output. + + RETURN + 0 - ok + 1 - error occured +*/ + +int Instance_options::fill_instance_version() +{ + enum { MAX_VERSION_STRING_LENGTH= 160 }; + char result[MAX_VERSION_STRING_LENGTH]; + char version_option[]= " --no-defaults --version"; + int rc= 1; + Buffer cmd(mysqld_path_len + sizeof(version_option)); + + if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len, + version_option, sizeof(version_option))) + goto err; + + rc= parse_output_and_get_value(cmd.buffer, mysqld_path, + result, MAX_VERSION_STRING_LENGTH, + GET_LINE); + + if (*result != '\0') + { + /* chop the newline from the end of the version string */ + result[strlen(result) - NEWLINE_LEN]= '\0'; + mysqld_version= strdup_root(&alloc, result); + } + + return rc; + +err: + return 1; +} + + +/* + Fill various log options + + SYNOPSYS + fill_log_options() + + DESCRIPTION + + Compute paths to enabled log files. If the path is not specified in the + instance explicitly (I.e. log=/home/user/mysql.log), we try to guess the + file name and placement. RETURN 0 - ok @@ -126,8 +197,8 @@ int Instance_options::fill_log_options() goto err; } else /* below is safe, as --datadir always has a value */ - strncpy(datadir, strchr(mysqld_datadir, '=') + 1, - MAX_LOG_OPTION_LENGTH); + strmake(datadir, strchr(mysqld_datadir, '=') + 1, + MAX_LOG_OPTION_LENGTH - 1); if (gethostname(hostname,sizeof(hostname)-1) < 0) strmov(hostname, "mysql"); @@ -160,7 +231,7 @@ int Instance_options::fill_log_options() if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) > strlen(log_files->default_suffix)) { - strcpy(full_name + strlen(full_name), + strmov(full_name + strlen(full_name), log_files->default_suffix); } else @@ -266,7 +337,7 @@ pid_t Instance_options::get_pid() int Instance_options::complete_initialization(const char *default_path, - int only_instance) + uint instance_type) { const char *tmp; @@ -276,6 +347,8 @@ int Instance_options::complete_initialization(const char *default_path, goto err; } + mysqld_path_len= strlen(mysqld_path); + if (mysqld_port) mysqld_port_val= atoi(strchr(mysqld_port, '=') + 1); @@ -295,18 +368,23 @@ int Instance_options::complete_initialization(const char *default_path, found, we would like to model mysqld pid file values. */ if (!gethostname(hostname, sizeof(hostname) - 1)) - (only_instance == 0) ? - strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name, "-", - hostname, ".pid", NullS): - strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", hostname, - ".pid", NullS); - + { + if (instance_type & DEFAULT_SINGLE_INSTANCE) + strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", hostname, + ".pid", NullS); + else + strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name, + "-", hostname, ".pid", NullS); + } else - (only_instance == 0) ? - strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name, - ".pid", NullS): - strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", "mysql", - ".pid", NullS); + { + if (instance_type & DEFAULT_SINGLE_INSTANCE) + strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", "mysql", + ".pid", NullS); + else + strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name, + ".pid", NullS); + } add_option(pidfilename); } @@ -330,7 +408,8 @@ int Instance_options::complete_initialization(const char *default_path, options_array.elements*sizeof(char*)); argv[filled_default_options + options_array.elements]= 0; - fill_log_options(); + if (fill_log_options() || fill_instance_version()) + goto err; return 0; diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h index ebeeaa1978e..9dac8b39bdc 100644 --- a/server-tools/instance-manager/instance_options.h +++ b/server-tools/instance-manager/instance_options.h @@ -34,18 +34,21 @@ don't have to synchronize between threads. */ +#define USUAL_INSTANCE 0 +#define DEFAULT_SINGLE_INSTANCE 1 + class Instance_options { public: Instance_options() : - mysqld_socket(0), mysqld_datadir(0), + mysqld_version(0), mysqld_socket(0), mysqld_datadir(0), mysqld_bind_address(0), mysqld_pid_file(0), mysqld_port(0), mysqld_port_val(0), mysqld_path(0), nonguarded(0), shutdown_delay(0), shutdown_delay_val(0), filled_default_options(0) {} ~Instance_options(); /* fills in argv */ - int complete_initialization(const char *default_path, int only_instance); + int complete_initialization(const char *default_path, uint instance_type); int add_option(const char* option); int init(const char *instance_name_arg); @@ -64,6 +67,11 @@ public: enum { MEM_ROOT_BLOCK_SIZE= 512 }; char pid_file_with_path[MAX_PATH_LEN]; char **argv; + /* + Here we cache the version string, obtained from mysqld --version. + In the case when mysqld binary is not found we get NULL here. + */ + const char *mysqld_version; /* We need the some options, so we store them as a separate pointers */ const char *mysqld_socket; const char *mysqld_datadir; @@ -74,6 +82,7 @@ public: const char *instance_name; uint instance_name_len; const char *mysqld_path; + uint mysqld_path_len; const char *nonguarded; const char *shutdown_delay; uint shutdown_delay_val; @@ -84,6 +93,7 @@ public: DYNAMIC_ARRAY options_array; private: int fill_log_options(); + int fill_instance_version(); int add_to_argv(const char *option); int get_default_option(char *result, size_t result_len, const char *option_name); diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 98f5b64ca92..4aed18c753d 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -163,7 +163,7 @@ void Listener_thread::run() unix_socket_address.sun_family= AF_UNIX; strmake(unix_socket_address.sun_path, options.socket_file_name, sizeof(unix_socket_address.sun_path)); - unlink(unix_socket_address.sun_path); // in case we have stale socket file + unlink(unix_socket_address.sun_path); /* in case we have stale socket file */ { /* diff --git a/server-tools/instance-manager/log.cc b/server-tools/instance-manager/log.cc index 88d777eeeb6..3c18d2816bf 100644 --- a/server-tools/instance-manager/log.cc +++ b/server-tools/instance-manager/log.cc @@ -76,7 +76,7 @@ static inline void log(FILE *file, const char *format, va_list args) if (buff_msg == 0) { strmake(buff_stack, "log(): message is too big, my_malloc() failed", - sizeof(buff_stack)); + sizeof(buff_stack) - 1); buff_msg= buff_stack; break; } diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc index 28899940e47..e44e4c6ff34 100644 --- a/server-tools/instance-manager/options.cc +++ b/server-tools/instance-manager/options.cc @@ -224,10 +224,10 @@ int Options::load(int argc, char **argv) /* config-file options are prepended to command-line ones */ load_defaults("my", default_groups, &argc, &argv); + Options::saved_argv= argv; if ((rc= handle_options(&argc, &argv, my_long_options, get_one_option)) != 0) return rc; - Options::saved_argv= argv; return 0; } diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index d6adb8079ce..e83a75c6778 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -16,10 +16,11 @@ #include #include "parse.h" +#include "parse_output.h" #include #include -#include +#include /* @@ -28,14 +29,17 @@ SYNOPSYS parse_output_and_get_value() - command the command to execue with popen. - word the word to look for (usually an option name) - result the buffer to store the next word (option value) - result_len self-explanatory + command the command to execue with popen. + word the word to look for (usually an option name) + result the buffer to store the next word (option value) + input_buffer_len self-explanatory + flag this equals to GET_LINE if we want to get all the line after + the matched word and GET_VALUE otherwise. DESCRIPTION Parse output of the "command". Find the "word" and return the next one + if flag is GET_VALUE. Return the rest of the parsed string otherwise. RETURN 0 - ok @@ -43,7 +47,8 @@ */ int parse_output_and_get_value(const char *command, const char *word, - char *result, size_t result_len) + char *result, size_t input_buffer_len, + uint flag) { FILE *output; uint wordlen; @@ -64,7 +69,7 @@ int parse_output_and_get_value(const char *command, const char *word, while (fgets(linebuf, sizeof(linebuf) - 1, output)) { - uint lineword_len= 0; + uint found_word_len= 0; char *linep= linebuf; linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */ @@ -73,19 +78,25 @@ int parse_output_and_get_value(const char *command, const char *word, Get the word, which might contain non-alphanumeric characters. (Usually these are '/', '-' and '.' in the path expressions and filenames) */ - get_word((const char **) &linep, &lineword_len, NONSPACE); + get_word((const char **) &linep, &found_word_len, NONSPACE); if (!strncmp(word, linep, wordlen)) { /* - If we have found the word, return the next one. This is usually - an option value. + If we have found the word, return the next one (this is usually + an option value) or the whole line (if flag) */ - linep+= lineword_len; /* swallow the previous one */ - get_word((const char **) &linep, &lineword_len, NONSPACE); - if (result_len <= lineword_len) - goto err; - strncpy(result, linep, lineword_len); - result[lineword_len]= '\0'; + linep+= found_word_len; /* swallow the previous one */ + if (flag & GET_VALUE) + { + get_word((const char **) &linep, &found_word_len, NONSPACE); + if (input_buffer_len <= found_word_len) + goto err; + strmake(result, linep, found_word_len); + } + else /* currently there are only two options */ + { + strmake(result, linep, input_buffer_len - 1); + } goto pclose; } } diff --git a/server-tools/instance-manager/parse_output.h b/server-tools/instance-manager/parse_output.h index 48fd2ae4068..6a84fabbf17 100644 --- a/server-tools/instance-manager/parse_output.h +++ b/server-tools/instance-manager/parse_output.h @@ -16,7 +16,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define GET_VALUE 1 +#define GET_LINE 2 + int parse_output_and_get_value(const char *command, const char *word, - char *result, size_t result_len); + char *result, size_t input_buffer_len, + uint flag); #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H */ diff --git a/sql-bench/limits/mysql-4.1.cfg b/sql-bench/limits/mysql-4.1.cfg new file mode 100644 index 00000000000..64f91f07363 --- /dev/null +++ b/sql-bench/limits/mysql-4.1.cfg @@ -0,0 +1,7056 @@ +#This file is automaticly generated by crash-me 1.61 + +NEG=yes # update of column= -column + ###< create table crash_q (a integer) + ###> OK + ###< insert into crash_q values(10) + ###> OK + ###< update crash_q set a=-a + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +Need_cast_for_null=no # Need to cast NULL for arithmetic + ### Check if numeric_null (NULL) is 'NULL' +alter_add_col=yes # Alter table add column + ###< alter table crash_q add d integer + ###> OK + ### + ###As far as all queries returned OK, result is YES +alter_add_constraint=yes # Alter table add constraint + ###< alter table crash_q add constraint c2 check(a > b) + ###> OK + ### + ###As far as all queries returned OK, result is YES +alter_add_foreign_key=no # Alter table add foreign key + ###< alter table crash_q add constraint f1 foreign key(c1) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 + ###< references crash_q1(c1) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'references crash_q1(c1)' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +alter_add_multi_col=yes # Alter table add many columns + ###< alter table crash_q add (f integer,g integer) + ###> OK +alter_add_primary_key=with constraint # Alter table add primary key + ###< alter table crash_q1 add constraint p1 primary key(c1) + ###> OK +alter_add_unique=yes # Alter table add unique + ###< alter table crash_q add constraint u1 unique(c1) + ###> OK + ### + ###As far as all queries returned OK, result is YES +alter_alter_col=yes # Alter table alter column default + ###< alter table crash_q alter b set default 10 + ###> OK + ### + ###As far as all queries returned OK, result is YES +alter_change_col=yes # Alter table change column + ###< alter table crash_q change a e char(50) + ###> OK + ### + ###As far as all queries returned OK, result is YES +alter_drop_col=yes # Alter table drop column + ###< alter table crash_q drop column b + ###> OK +alter_drop_constraint=no # Alter table drop constraint + ###< alter table crash_q drop constraint c2 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2' at line 1 + ### + ###< alter table crash_q drop constraint c2 restrict + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2 restrict' at line 1 +alter_drop_foreign_key=with drop foreign key # Alter table drop foreign key + ###< alter table crash_q drop constraint f1 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1' at line 1 + ### + ###< alter table crash_q drop constraint f1 restrict + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1 restrict' at line 1 + ### + ###< alter table crash_q drop foreign key f1 + ###> OK +alter_drop_primary_key=drop primary key # Alter table drop primary key + ###< alter table crash_q1 drop constraint p1 restrict + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint p1 restrict' at line 1 + ### + ###< alter table crash_q1 drop primary key + ###> OK +alter_drop_unique=with drop key # Alter table drop unique + ###< alter table crash_q drop constraint u1 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1' at line 1 + ### + ###< alter table crash_q drop constraint u1 restrict + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1 restrict' at line 1 + ### + ###< alter table crash_q drop key u1 + ###> OK +alter_modify_col=yes # Alter table modify column + ###< alter table crash_q modify c1 CHAR(20) + ###> OK +alter_rename_table=yes # Alter table rename table + ###< alter table crash_q rename to crash_q1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +atomic_updates=no # atomic updates + ###< create table crash_q (a integer not null,primary key (a)) + ###> OK + ###< insert into crash_q values (2) + ###> OK + ###< insert into crash_q values (3) + ###> OK + ###< insert into crash_q values (1) + ###> OK + ###< update crash_q set a=a+1 + ###> execute error:Duplicate entry '3' for key 1 + ###< drop table crash_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +automatic_rowid=_rowid # Automatic row id + ###< create table crash_q (a int not null, primary key(a)) + ###> OK + ###< insert into crash_q values (1) + ###> OK + ###< select _rowid from crash_q + ###> OK + ###< drop table crash_q + ###> OK +binary_numbers=no # binary numbers (0b1001) + ###< select 0b1001 + ###> execute error:Unknown column '0b1001' in 'field list' + ### + ###As far as some queries didnt return OK, result is NO +binary_strings=no # binary strings (b'0110') + ###< select b'0110' + ###> execute error:Unknown column 'b' in 'field list' + ### + ###As far as some queries didnt return OK, result is NO +case_insensitive_strings=yes # Case insensitive compare + ### + ###aa + ###We expected 'a a ' but got 'aa' +column_alias=yes # Column alias + ###< select a as ab from crash_me + ###> OK + ### + ###As far as all queries returned OK, result is YES +columns_in_group_by=+64 # number of columns in group by + ###We are trying (example with N=5): + ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer) + ###insert into crash_q values(1,1,1,1,1) + ###insert into crash_q values(1,1,1,1,1) + ###select q1,q2,q3,q4,q5 from crash_q group by q1,q2,q3,q4,q5 +columns_in_order_by=+64 # number of columns in order by + ###We are trying (example with N=5): + ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer) + ###insert into crash_q values(1,1,1,1,1) + ###insert into crash_q values(1,1,1,1,1) + ###select * from crash_q order by q1,q2,q3,q4,q5 +comment_#=yes # # as comment + ###< select * from crash_me # Testing of comments + ###> OK + ### + ###As far as all queries returned OK, result is YES +comment_--=yes # -- as comment (ANSI) + ###< select * from crash_me -- Testing of comments + ###> OK + ### + ###As far as all queries returned OK, result is YES +comment_/**/=yes # /* */ as comment + ###< select * from crash_me /* Testing of comments */ + ###> OK + ### + ###As far as all queries returned OK, result is YES +comment_//=no # // as comment + ###< select * from crash_me // Testing of comments + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '// Testing of comments' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +compute=no # Compute + ###< select a from crash_me order by a compute sum(a) by a + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'compute sum(a) by a' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +connections=101 # Simultaneous connections (installation default) +constraint_check=syntax only # Column constraints + ###< create table crash_q (a int check (a>0)) + ###> OK + ### + ###< insert into crash_q values(0) + ###> OK + ### + ###< drop table crash_q + ###> OK +constraint_check_named=syntax only # Named constraints + ###< create table crash_q (a int ,b int, constraint abc check (a>b)) + ###> OK + ### + ###< insert into crash_q values(0,0) + ###> OK + ### + ###< drop table crash_q + ###> OK +constraint_check_table=syntax only # Table constraints + ###< create table crash_q (a int ,b int, check (a>b)) + ###> OK + ### + ###< insert into crash_q values(0,0) + ###> OK + ### + ###< drop table crash_q + ###> OK +constraint_null=yes # NULL constraint (SyBase style) + ###< create table crash_q (a int null) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +crash_me_safe=yes # crash me safe +crash_me_version=1.61 # crash me version +create_default=yes # default value for column + ###< create table crash_q (q integer default 10 not null) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +create_default_func=no # default value function for column + ###< create table crash_q (q integer not null,q1 integer default (1+1)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1+1))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +create_if_not_exists=yes # create table if not exists + ###< create table crash_q (q integer) + ###> OK + ###< create table if not exists crash_q (q integer) + ###> OK + ### + ###As far as all queries returned OK, result is YES +create_index=yes # create index + ###< create index crash_q on crash_me (a) + ###> OK +create_schema=no # Create SCHEMA + ###< create schema crash_schema create table crash_q (a int) create table crash_q2(b int) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema create table crash_q (a int) create table c + ###< drop schema crash_schema cascade + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema cascade' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +create_table_select=yes # create table from select + ###< create table crash_q SELECT * from crash_me + ###> OK +cross_join=yes # cross join (same as from a,b) + ###< select crash_me.a from crash_me cross join crash_me3 + ###> OK + ### + ###As far as all queries returned OK, result is YES +date_as_string=yes # String functions on date columns + ###< create table crash_me2 (a date not null) + ###> OK + ###< insert into crash_me2 values ('1998-03-03') + ###> OK + ### + ###0000-00-00 + ###We expected '1963-08-16' but got '0000-00-00' + ### + ###< delete from crash_me_d + ###> OK +date_format_EUR_with_date=error # Supports DATE 'DD.MM.YYYY' (EUR) format + ###< insert into crash_me_d(a) values (DATE '16.08.1963') + ###> OK + ### + ###1963-08-16 + ### + ###< delete from crash_me_d + ###> OK +date_format_ISO_with_date=yes # Supports DATE 'YYYY-MM-DD' (ISO) format + ###< insert into crash_me_d(a) values (DATE '1963-08-16') + ###> OK + ### + ###0000-00-00 + ###We expected '1963-08-16' but got '0000-00-00' + ### + ###< delete from crash_me_d + ###> OK +date_format_USA_with_date=error # Supports DATE 'MM/DD/YYYY' format + ###< insert into crash_me_d(a) values (DATE '08/16/1963') + ###> OK + ### + ###1963-08-16 + ### + ###< delete from crash_me_d + ###> OK +date_format_YYYYMMDD_with_date=yes # Supports DATE 'YYYYMMDD' format + ###< insert into crash_me_d(a) values (DATE '19630816') + ###> OK + ### + ###0000-00-00 + ###We expected 'infinity' but got '0000-00-00' + ### + ###< drop table crash_me2 + ###> OK +date_last=yes # Supports 9999-12-31 dates + ###< create table crash_me2 (a date not null) + ###> OK + ###< insert into crash_me2 values ('9999-12-31') + ###> OK + ### + ###0001-01-01 + ### + ###< drop table crash_me2 + ###> OK +date_with_YY=yes # Supports YY-MM-DD 2000 compilant dates + ###< create table crash_me2 (a date not null) + ###> OK + ###< insert into crash_me2 values ('98-03-03') + ###> OK + ### + ###2010-03-03 + ### + ###< drop table crash_me2 + ###> OK +date_zero=yes # Supports 0000-00-00 dates + ###< create table crash_me2 (a date not null) + ###> OK + ###< insert into crash_me2 values ('0000-00-00') + ###> OK + ### + ###Walker's +drop_if_exists=yes # drop table if exists + ###< create table crash_q (q integer) + ###> OK + ###< drop table if exists crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +drop_index=with 'ON' # drop index + ###< drop index crash_q + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 + ### + ###< drop index crash_q from crash_me + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'from crash_me' at line 1 + ### + ###< drop index crash_q on crash_me + ###> OK +drop_requires_cascade=no # drop table require cascade/restrict + ###< create table crash_me (a integer not null) + ###> OK + ###< drop table crash_me + ###> OK +drop_restrict=yes # drop table with cascade/restrict + ###< create table crash_q (a int) + ###> OK + ###< drop table crash_q restrict + ###> OK + ### + ###As far as all queries returned OK, result is YES +end_colon=yes # allows end ';' + ###< select * from crash_me; + ###> OK + ### + ###As far as all queries returned OK, result is YES +except=no # except + ###< select * from crash_me except select * from crash_me3 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +except_all=no # except all + ###< select * from crash_me except all select * from crash_me3 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +except_all_incompat=no # except all (incompatible lists) + ###< select * from crash_me except all select * from crash_me2 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +except_incompat=no # except (incompatible lists) + ###< select * from crash_me except select * from crash_me2 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +field_name_case=yes # case independent field names + ###< create table crash_q (q integer) + ###> OK + ###< insert into crash_q(Q) values (1) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +float_int_expr=yes # mixing of integer and float in expression + ###< select 1+1.0 + ###> OK + ### + ###As far as all queries returned OK, result is YES +foreign_key=syntax only # foreign keys + ###< create table crash_me_qf (a integer not null,primary key (a)) + ###> OK + ### + ###< create table crash_me_qf2 (a integer not null,foreign key (a) references crash_me_qf (a)) + ###> OK + ### + ###< insert into crash_me_qf values (1) + ###> OK + ### + ###< insert into crash_me_qf2 values (2) + ###> OK + ### + ###< drop table crash_me_qf2 + ###> OK + ### + ###< drop table crash_me_qf + ###> OK +full_outer_join=no # full outer join + ###< select crash_me.a from crash_me full join crash_me2 ON + ### crash_me.a=crash_me2.a + ###> execute error:Unknown table 'crash_me' in field list + ### + ###As far as some queries didnt return OK, result is NO +func_extra_!=yes # Function NOT as '!' in SELECT + ### + ###3 +func_extra_&=yes # Function & (bitwise and) + ### + ###1 +func_extra_<>=yes # Function <> in SELECT + ### + ###1 +func_extra_add_months=no # Function ADD_MONTHS + ### + ###2002-12-04 +func_extra_addtime=yes # Function ADDTIME + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ',2)' at line 1 +func_extra_and_or=yes # Function AND and OR in SELECT + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1 +func_extra_ascii_code=no # Function ASCII_CODE + ### + ###97 + ###We expected 'a' but got '97' +func_extra_atn2=no # Function ATN2 + ### + ###a2 +func_extra_auto_string2num=yes # Function automatic string->num convert + ### + ###1 +func_extra_binary_shifts=yes # Function << and >> (bitwise shifts) + ### + ###2 +func_extra_ceil=yes # Function CEIL + ### + ### execute failed:Unknown column 'EUR' in 'field list' +func_extra_charindex=no # Function CHARINDEX + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1 +func_extra_chr_str=no # Function CHR (any type to string) + ### + ###0 + ###We expected 'abcdef' but got '0' +func_extra_concat_list=yes # Function CONCAT(list) + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '5)' at line 1 +func_extra_cosh=no # Function COSH + ### + ###1963-08-16 +func_extra_date_format=yes # Function DATE_FORMAT + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(day,3,'1997-11-30') from crash_me_d' at line 1 +func_extra_datediff=no # Function DATEDIFF + ### + ###3 +func_extra_datename=no # Function DATENAME + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(month,'July 20 1997') from crash_me_d' at line 1 +func_extra_day=yes # Function DAY + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1,'S-103',2,'Leopard',3)' at line 1 +func_extra_ebcdic_string=no # Function EBCDIC in string cast + ### + ###TWO +func_extra_encrypt=yes # Function ENCRYPT + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd',6)' at line 1 +func_extra_field=yes # Function FIELD + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6666,10,2)' at line 1 +func_extra_float=no # Function FLOAT + ### + ###1,234.56 +func_extra_from_days=yes # Function FROM_DAYS + ### + ###1970-01-01 02:00:00 +func_extra_getdate=no # Function GETDATE + ### + ###HARRY +func_extra_hex=yes # Function HEX + ### + ###6 +func_extra_in_num=yes # Function IN on numbers in SELECT + ### + ###1 +func_extra_index=no # Function INDEX + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('the soap')' at line 1 +func_extra_instr=yes # Function LOCATE as INSTR + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '3,2)' at line 1 +func_extra_instrb=no # Function INSTRB + ### + ###5 +func_extra_last_day=yes # Function LAST_DAY + ### + ###0 +func_extra_least=yes # Function LEAST + ### + ###1 + ###We expected '2' but got '1' +func_extra_lengthb=no # Function LENGTHB + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd','.',6)' at line 1 +func_extra_like=yes # Function LIKE in SELECT + ### + ###1 +func_extra_ln=yes # Function LN + ### + ###2.000000 +func_extra_logn=no # Function LOGN + ### + ###??hi +func_extra_ltrim2arg=no # Function LTRIM (2 arg) + ### + ###1963-08-16 +func_extra_maketime=yes # Function MAKETIME + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ')' at line 1 +func_extra_mdy=no # Function MDY + ### + ###110000 +func_extra_mid=yes # Function SUBSTRING as MID + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1997-02-02','1997-01-01') from crash_me_d' at line 1 +func_extra_noround=no # Function NOROUND + ###< select noround(22.6) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(22.6)' at line 1 +func_extra_not=yes # Function NOT in SELECT + ### + ###0 +func_extra_not_like=yes # Function NOT LIKE in SELECT + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('2123')' at line 1 +func_extra_odbc_convert=no # Function ODBC CONVERT + ### + ###*6B4F89A54E2D27ECD7E8DA05B4AB8FD9D1D8B119 +func_extra_paste=no # Function PASTE + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('%a%','crash')' at line 1 +func_extra_period_add=yes # Function PERIOD_ADD + ### + ###13 +func_extra_pow=yes # Function POW + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a)' at line 1 +func_extra_regexp=yes # Function REGEXP in SELECT + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 +func_extra_replicate=no # Function REPLICATE + ### + ###dcba +func_extra_rfill3arg=no # Function RFILL (3 arg) + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(4)' at line 1 +func_extra_round1=yes # Function ROUND(1 arg) + ### + ###hi?? +func_extra_rpad4arg=no # Function RPAD (4 arg) + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1 +func_extra_sec_to_time=yes # Function SEC_TO_TIME + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1 +func_extra_str=no # Function STR + ### + ###-1 +func_extra_stuff=no # Function STUFF + ### + ###2002-12-01 +func_extra_substr2arg=yes # Function SUBSTR (2 arg) + ### + ###bc +func_extra_substrb=no # Function SUBSTRB + ### + ###tcx.se +func_extra_subtime=yes # Function SUBTIME + ### + ###2004-04-06 13:49:05 +func_extra_tail=no # Function TAIL + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1 +func_extra_time=yes # Function TIME + ### + ###5001 +func_extra_timediff=yes # Function TIMEDIFF + ### + ###1963-08-16 20:02:12 + ###We expected '19630816200212000000' but got '1963-08-16 20:02:12' +func_extra_to_days=yes # Function TO_DAYS + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','bc','de')' at line 1 +func_extra_trim1arg=yes # Function TRIM (1 arg) + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1 +func_extra_trim_many_char=error # Function TRIM; Many char extension + ### + ###abc +func_extra_trunc=no # Function TRUNC + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6)' at line 1 +func_extra_uid=no # Function UID + ### + ###1081248545 +func_extra_userenv=no # Function USERENV + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(NULL,'WALRUS')' at line 1 +func_extra_version=yes # Function VERSION + ### + ###5 +func_extra_weekofyear=yes # Function WEEKOFYEAR + ### + ###3 +func_extra_||=yes # Function OR as '||' + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '~* 'HI'' at line 1 +func_odbc_abs=yes # Function ABS + ### + ###1.570796 +func_odbc_ascii=yes # Function ASCII + ### + ###1.570796 +func_odbc_atan=yes # Function ATAN + ### + ###1.570796 +func_odbc_ceiling=yes # Function CEILING + ### + ###A +func_odbc_concat=yes # Function CONCAT(2 arg) + ### + ###1.000000 +func_odbc_cot=yes # Function COT + ### + ###2004-04-06 +func_odbc_curtime=yes # Function CURTIME + ### + ###test +func_odbc_dayname=yes # Function DAYNAME + ###< insert into crash_me_d values('1997-02-01') + ### + ###1 +func_odbc_dayofweek=yes # Function DAYOFWEEK + ###< insert into crash_me_d values('1997-02-01') + ### + ###32 +func_odbc_degrees=yes # Function DEGREES + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','abe')' at line 1 + ### + ###2.718282 +func_odbc_floor=yes # Function FLOOR + ### + ###c +func_odbc_hour=yes # Function HOUR + ###< insert into crash_me_t values(20:08:16) + ### + ###12 +func_odbc_ifnull=yes # Function IFNULL + ### + ###aefd +func_odbc_lcase=yes # Function LCASE + ### + ###ab +func_odbc_length=yes # Function REAL LENGTH + ### + ###5 + ###We expected '4' but got '5' + ### + ###2 +func_odbc_locate_3=yes # Function LOCATE(3 arg) + ### + ###0.693147 +func_odbc_log10=yes # Function LOG10 + ### + ###abcd +func_odbc_minute=yes # Function MINUTE + ###< insert into crash_me_t values(20:08:16) + ### + ###4 +func_odbc_month=yes # Function MONTH + ###< insert into crash_me_d values('1997-02-01') + ### + ###February +func_odbc_now=yes # Function NOW + ### + ###3.141593 +func_odbc_power=yes # Function POWER + ### + ###1 +func_odbc_radians=yes # Function RADIANS + ### + ###0.40540353712198 +func_odbc_repeat=yes # Function REPEAT + ### + ###bababa +func_odbc_right=yes # Function RIGHT + ### + ###5.63 +func_odbc_rtrim=yes # Function RTRIM + ### + ###14 +func_odbc_sign=yes # Function SIGN + ### + ###0.841471 +func_odbc_soundex=yes # Function SOUNDEX + ### + ### +func_odbc_sqrt=yes # Function SQRT + ### + ###cd +func_odbc_tan=yes # Function TAN + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')' at line 1 + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')' + ### + ###10 +func_odbc_ucase=yes # Function UCASE + ### + ###monty@localhost +func_odbc_week=USA # WEEK + ###1997 +func_sql_+=yes # Function +, -, * and / + ### + ###24 +func_sql_cast=yes # Function CAST + ### + ###1 + ###We expected '10' but got '1' +func_sql_char_length(constant)=yes # Function CHAR_LENGTH(constant) + ### + ###4 +func_sql_coalesce=yes # Function COALESCE + ### + ###0 + ###We expected 'abcdef' but got '0' +func_sql_current_date=yes # Function CURRENT_DATE + ### + ###13:49:04 +func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP + ### + ###43 +func_sql_localtime=yes # Function LOCALTIME + ### + ###2004-04-06 13:49:04 +func_sql_lower=yes # Function LOWER + ### + ### +func_sql_nullif_string=yes # Function NULLIF with strings + ### + ###3 +func_sql_position=yes # Function POSITION + ### + ### 2 then 'false' when 2 > 1 then 'true' end + ###>true +func_sql_session_user=with_parenthesis # SESSION_USER + ###< select SESSION_USER + ###> execute error:Unknown column 'SESSION_USER' in 'field list' + ### + ###< select SESSION_USER() + ###> OK +func_sql_simple_case=yes # Function simple CASE + ### + ###bc +func_sql_system_user=with_parenthesis # SYSTEM_USER + ###< select SYSTEM_USER + ###> execute error:Unknown column 'SYSTEM_USER' in 'field list' + ### + ###< select SYSTEM_USER() + ###> OK +func_sql_trim=yes # Function TRIM + ### + ###ABC +func_sql_user=with_parenthesis # USER + ###< select USER + ###> execute error:Unknown column 'USER' in 'field list' + ### + ###< select USER() + ###> OK +func_where_between=yes # Function BETWEEN + ### + ###1 +func_where_eq_any=yes # Function = ANY + ### + ###1 +func_where_exists=yes # Function EXISTS + ### + ###1 +func_where_like=yes # Function LIKE + ### + ###1 +func_where_match=no # Function MATCH + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'match unique (select a from crash_me)' at line 1 +func_where_matches=no # Function MATCHES + ### + ###1 +func_where_not_exists=yes # Function NOT EXISTS + ### + ###1 +func_where_not_unique=no # Function NOT UNIQUE + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'unique (select * from crash_me)' at line 1 +functions=yes # Functions + ###< select 1+1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +group_by=yes # Group by + ###< select a from crash_me group by a + ###> OK + ### + ###As far as all queries returned OK, result is YES +group_by_alias=yes # Group by alias + ###< select a as ab from crash_me group by ab + ###> OK + ### + ###As far as all queries returned OK, result is YES +group_by_null=yes # Group on column with null values + ###< create table crash_q (s char(10)) + ###> OK + ###< insert into crash_q values(null) + ###> OK + ###< insert into crash_q values(null) + ###> OK + ### + ###1 +group_func_extra_bit_or=yes # Group function BIT_OR + ### + ###1 +group_func_extra_std=yes # Group function STD + ### + ###0.0000 +group_func_extra_variance=yes # Group function VARIANCE + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1 +group_func_sql_avg=yes # Group function AVG + ### + ###1 +group_func_sql_count_column=yes # Group function COUNT column name + ### + ###1 +group_func_sql_every=no # Group function EVERY + ### + ###1 +group_func_sql_max_str=yes # Group function MAX on strings + ### + ###1 +group_func_sql_min_str=yes # Group function MIN on strings + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1 +group_func_sql_sum=yes # Group function SUM + ### + ### 0 + ###>1 + ### + ###a +index_in_create=yes # index in create table + ###< create table crash_q (q integer not null,index (q)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +index_namespace=yes # different namespace for index + ###< create index crash_me on crash_me (b) + ###> OK + ###< drop index crash_me on crash_me + ###> OK + ### + ###As far as all queries returned OK, result is YES +index_parts=yes # index on column part (extension) + ###< create index crash_q on crash_me (b(5)) + ###> OK + ###< drop index crash_q on crash_me + ###> OK + ### + ###As far as all queries returned OK, result is YES +inner_join=yes # inner join + ###< select crash_me.a from crash_me inner join crash_me2 ON crash_me.a=crash_me2.a + ###> OK + ### + ###As far as all queries returned OK, result is YES +insert_default_values=no # INSERT DEFAULT VALUES + ###< create table crash_me_q (a int) + ###> OK + ###< insert into crash_me_q DEFAULT VALUES + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1 + ###< drop table crash_me_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +insert_empty_string=yes # insert empty string + ###< create table crash_q (a char(10) not null,b char(10)) + ###> OK + ###< insert into crash_q values ('','') + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +insert_multi_value=yes # INSERT with Value lists + ###< create table crash_q (s char(10)) + ###> OK + ###< insert into crash_q values ('a'),('b') + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +insert_select=yes # insert INTO ... SELECT ... + ###< create table crash_q (a int) + ###> OK + ###< insert into crash_q (a) SELECT crash_me.a from crash_me + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +insert_with_default=yes # INSERT with DEFAULT + ###< create table crash_me_q (a int) + ###> OK + ###< insert into crash_me_q (a) values (DEFAULT) + ###> OK + ###< drop table crash_me_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +insert_with_empty_value_list=no # INSERT with empty value list + ###< create table crash_me_q (a int) + ###> OK + ###< insert into crash_me_q (a) values () + ###> execute error:Column count doesn't match value count at row 1 + ###< drop table crash_me_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +insert_with_set=yes # INSERT with set syntax + ###< create table crash_q (a integer) + ###> OK + ###< insert into crash_q SET a=1 + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +intersect=no # intersect + ###< select * from crash_me intersect select * from crash_me3 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +intersect_all=no # intersect all + ###< select * from crash_me intersect all select * from crash_me3 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +intersect_all_incompat=no # intersect all (incompatible lists) + ###< select * from crash_me intersect all select * from crash_me2 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +intersect_incompat=no # intersect (incompatible lists) + ###< select * from crash_me intersect select * from crash_me2 + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +join_tables=61 # tables in join + ###We are trying (example with N=5): + ###select crash_me.a,t0.a,t1.a,t2.a,t3.a,t4.a from crash_me,crash_me t0,crash_me t1,crash_me t2,crash_me t3,crash_me t4 + ### 32:OK 48:OK 56:OK 60:OK 62:FAIL 61:FAIL +left_outer_join=yes # left outer join + ###< select crash_me.a from crash_me left join crash_me2 ON crash_me.a=crash_me2.a + ###> OK + ### + ###As far as all queries returned OK, result is YES +left_outer_join_using=yes # left outer join using + ###< select c1 from crash_me left join crash_me2 using (a) + ###> OK + ### + ###As far as all queries returned OK, result is YES +length_of_varchar_field=actual length # CHARACTER_LENGTH(varchar_field) + ###< CREATE TABLE crash_me1 (S1 VARCHAR(100)) + ###> OK + ###< INSERT INTO crash_me1 VALUES ('X') + ###> OK + ### + ###< SELECT CHARACTER_LENGTH(S1) FROM crash_me1 + ### > 1 + ###< drop table crash_me1 + ###> OK +like_with_column=yes # column LIKE column + ###< create table crash_q (a char(10),b char(10)) + ###> OK + ###< insert into crash_q values('abc','abc') + ###> OK + ###< select * from crash_q where a like b + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +like_with_number=yes # LIKE on numbers + ###< create table crash_q (a int,b int) + ###> OK + ###< insert into crash_q values(10,10) + ###> OK + ###< select * from crash_q where a like '10' + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +lock_tables=yes # lock table + ###< lock table crash_me READ + ###> OK + ###< unlock tables + ###> OK + ### + ###As far as all queries returned OK, result is YES +logical_value=1 # Value of logical operation (1=1) + ###2 +multi_drop=yes # many tables to drop table + ###< create table crash_q (a int) + ###> OK + ###< create table crash_q2 (a int) + ###> OK + ###< drop table crash_q,crash_q2 + ###> OK + ### + ###As far as all queries returned OK, result is YES +multi_null_in_unique=yes # null in unique index + ###< create table crash_q (q integer, x integer,unique (q)) + ###> OK + ###< insert into crash_q(x) values(1) + ###> OK + ###< insert into crash_q(x) values(2) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +multi_strings=yes # Multiple line strings + ### + ###a + ### + ###< drop table crash_q + ###> OK +natural_join=yes # natural join + ###< select * from crash_me natural join crash_me3 + ###> OK + ### + ###As far as all queries returned OK, result is YES +natural_join_incompat=yes # natural join (incompatible lists) + ###< select c1 from crash_me natural join crash_me2 + ###> OK + ### + ###As far as all queries returned OK, result is YES +natural_left_outer_join=yes # natural left outer join + ###< select c1 from crash_me natural left join crash_me2 + ###> OK + ### + ###As far as all queries returned OK, result is YES +no_primary_key=yes # Tables without primary key + ###< create table crash_me (a integer not null,b char(10) not null) + ###> OK + ###< insert into crash_me (a,b) values (1,'a') + ###> OK +not_id_between=no # NOT ID BETWEEN interprets as ID NOT BETWEEN + ###< create table crash_me_b (i int) + ###> OK + ###< insert into crash_me_b values(2) + ###> OK + ###< insert into crash_me_b values(5) + ###> OK + ### + ### +null_in_index=yes # null in index + ###< create table crash_q (a char(10),index (a)) + ###> OK + ###< insert into crash_q values (NULL) + ###> OK + ### + ### +nulls_in_unique=yes # null combination in unique index + ###< create table crash_q (q integer,q1 integer,unique (q,q1)) + ###> OK + ###< insert into crash_q (q,q1) values(1,NULL) + ###> OK + ###< insert into crash_q (q,q1) values(1,NULL) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +odbc_left_outer_join=yes # left outer join odbc style + ###< select crash_me.a from { oj crash_me left outer join crash_me2 ON crash_me.a=crash_me2.a } + ###> OK + ### + ###As far as all queries returned OK, result is YES +operating_system=Linux 2.4.21-199-smp4G i686 # crash-me tested on +order_by=yes # Order by + ###< select a from crash_me order by a + ###> OK + ### + ###As far as all queries returned OK, result is YES +order_by_alias=yes # Order by alias + ###< select a as ab from crash_me order by ab + ###> OK + ### + ###As far as all queries returned OK, result is YES +order_by_function=yes # Order by function + ###< select a from crash_me order by a+1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +order_by_position=yes # Order by position + ###< select a from crash_me order by 1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +order_on_unused=yes # Order by on unused column + ###< select b from crash_me order by a + ###> OK + ### + ###As far as all queries returned OK, result is YES +position_of_null=first # Where is null values in sorted recordset + ###< insert into crash_me_n (i) values(1) + ###> OK + ###< insert into crash_me_n values(2,2) + ###> OK + ###< insert into crash_me_n values(3,3) + ###> OK + ###< insert into crash_me_n values(4,4) + ###> OK + ###< insert into crash_me_n (i) values(5) + ###> OK + ### + ###< select r from crash_me_n order by r + ###> + ###> + ###> 2 + ###> 3 + ###> 4 +position_of_null_desc=last # Where is null values in sorted recordset (DESC) + ###< select r from crash_me_n order by r desc + ###> 4 + ###> 3 + ###> 2 + ###> + ###> +primary_key_in_create=yes # primary key in create table + ###< create table crash_q (q integer not null,primary key (q)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +psm_functions=no # PSM functions (ANSI SQL) + ###< create table crash_q (a int) + ###> OK + ###< create function crash_func(in a1 int, in b1 int) returns int language sql deterministic contains sql begin return a1 * b1; end + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(in a1 int, in b1 int) returns int language sql deterministic c + ###< insert into crash_q values(crash_func(2,4)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(2,4))' at line 1 + ###< select a,crash_func(a,2) from crash_q + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a,2) from crash_q' at line 1 + ###< drop function crash_func cascade + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cascade' at line 1 + ###< drop table crash_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +psm_modules=no # PSM modules (ANSI SQL) + ###< create table crash_q (a int,b int) + ###> OK + ###< create module crash_m declare procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end; declare procedure crash_proc2(INOUT a int, in b int) contains sql set a = b + 10; end module + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m declare procedure crash_proc(in a1 int, in b1 in + ###< call crash_proc(1,10) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1 + ###< drop module crash_m cascade + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m cascade' at line 1 + ###< drop table crash_q cascade + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +psm_procedures=no # PSM procedures (ANSI SQL) + ###< create table crash_q (a int,b int) + ###> OK + ###< create procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc(in a1 int, in b1 int) language sql modifie + ###< call crash_proc(1,10) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1 + ###< drop procedure crash_proc + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc' at line 1 + ###< drop table crash_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +psm_trigger=no # Triggers (ANSI SQL) + ###< create table crash_q (a int ,b int) + ###> OK + ###< create trigger crash_trigger after insert on crash_q referencing new table as new_a when (localtime > time '18:00:00') begin atomic end + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger after insert on crash_q referencing new t + ###< insert into crash_q values(1,2) + ###> OK + ###< drop trigger crash_trigger + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger' at line 1 + ###< drop table crash_q + ###> OK + ### + ###As far as some queries didnt return OK, result is NO +query_size=1048574 # query size +quote_ident_with_"=error # " as identifier quote (ANSI SQL) + ### + ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '[A] from crash_me' at line 1 +quote_ident_with_`=yes # ` as identifier quote + ### + ###hello + ###We expected 'hello ' but got 'hello' + ### + ###< drop table crash_q + ###> OK +remember_end_space_varchar=no # Remembers end space in varchar() + ###< create table crash_q (a varchar(10)) + ###> OK + ###< insert into crash_q values('hello ') + ###> OK + ### + ###0 + ###We expected '1' but got '0' +select_constants=yes # Select constants + ###< select 1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +select_limit=with LIMIT # LIMIT number of rows + ###< select * from crash_me limit 1 + ###> OK +select_limit2=yes # SELECT with LIMIT #,# + ###< select * from crash_me limit 1,1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +select_limit3=yes # SELECT with LIMIT # OFFSET # + ###< select * from crash_me limit 1 offset 1 + ###> OK + ### + ###As far as all queries returned OK, result is YES +select_string_size=1048565 # constant string size in SELECT + ###We are trying (example with N=5): + ###select 'aaaaa' +select_table_update=yes # Update with sub select + ###< create table crash_q (a integer,b char(10)) + ###> OK + ###< insert into crash_q values(1,'c') + ###> OK + ###< update crash_q set b= (select b from crash_me where crash_q.a = crash_me.a) + ###> OK + ### + ###1.1 + ### + ###< drop table crash_q + ###> OK + ### + ###< create table crash_q (q1 float(4,1)) + ###> OK + ###< insert into crash_q values(1.16) + ###> OK + ### + ###1.1 + ### + ###< drop table crash_q + ###> OK + ### + ###< create table crash_q (q1 float(4,1)) + ###> OK + ###< insert into crash_q values(1.16) + ###> OK + ### + ###00:00:20 + ###We expected '20:08:16' but got '00:00:20' + ### + ###< delete from crash_me_t + ###> OK +time_format_HHHHMMSS=yes # Supports HHHHmmSS time format + ###< insert into crash_me_t(a) values ('00200816') + ###> OK + ### + ###20:08:16 + ### + ###< delete from crash_me_t + ###> OK +time_format_USA=error # Supports HH:MM:SS (AM|PM) time format + ###< insert into crash_me_t(a) values ('08:08:16 PM') + ###> OK + ### + ###1 + ###We expected '' but got '1' +truncate_table=yes # truncate + ###< create table crash_q (a integer, b integer,c1 CHAR(10)) + ###> OK + ###< truncate table crash_q + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_abstime=no # Type abstime + ###< create table crash_q (q abstime) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'abstime)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_bfile=no # Type bfile + ###< create table crash_q (q bfile) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'bfile)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_blob=yes # Type blob + ###< create table crash_q (q blob) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_bool=yes # Type bool + ###< create table crash_q (q bool) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_box=no # Type box + ###< create table crash_q (q box) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'box)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_byte=no # Type byte + ###< create table crash_q (q byte) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'byte)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_char(1_arg)_binary=yes # Type char(1 arg) binary + ###< create table crash_q (q char(10) binary) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_cidr=no # Type cidr + ###< create table crash_q (q cidr) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cidr)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_circle=no # Type circle + ###< create table crash_q (q circle) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'circle)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_clob=no # Type clob + ###< create table crash_q (q clob) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'clob)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_datetime=yes # Type datetime + ###< create table crash_q (q datetime) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_double=yes # Type double + ###< create table crash_q (q double) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_enum(1_arg)=yes # Type enum(1 arg) + ###< create table crash_q (q enum('red')) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_float(2_arg)=yes # Type float(2 arg) + ###< create table crash_q (q float(6,2)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_float4=yes # Type float4 + ###< create table crash_q (q float4) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_float8=yes # Type float8 + ###< create table crash_q (q float8) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_image=no # Type image + ###< create table crash_q (q image) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'image)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_inet=no # Type inet + ###< create table crash_q (q inet) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'inet)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_int(1_arg)_zerofill=yes # Type int(1 arg) zerofill + ###< create table crash_q (q int(5) zerofill) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int1=yes # Type int1 + ###< create table crash_q (q int1) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int2=yes # Type int2 + ###< create table crash_q (q int2) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int3=yes # Type int3 + ###< create table crash_q (q int3) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int4=yes # Type int4 + ###< create table crash_q (q int4) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int8=yes # Type int8 + ###< create table crash_q (q int8) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int_auto_increment=yes # Type int not null auto_increment + ###< create table crash_q (q int not null auto_increment,unique(q)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_int_identity=no # Type int not null identity + ###< create table crash_q (q int not null identity,unique(q)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'identity,unique(q))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_int_unsigned=yes # Type int unsigned + ###< create table crash_q (q int unsigned) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_interval=no # Type interval + ###< create table crash_q (q interval) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_line=no # Type line + ###< create table crash_q (q line) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'line)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_long=yes # Type long + ###< create table crash_q (q long) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_long_raw=no # Type long raw + ###< create table crash_q (q long raw) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_long_varbinary=yes # Type long varbinary + ###< create table crash_q (q long varbinary) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg) + ###< create table crash_q (q long varchar(1)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_lseg=no # Type lseg + ###< create table crash_q (q lseg) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'lseg)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_macaddr=no # Type macaddr + ###< create table crash_q (q macaddr) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'macaddr)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_mediumint=yes # Type mediumint + ###< create table crash_q (q mediumint) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_mediumtext=yes # Type mediumtext + ###< create table crash_q (q mediumtext) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_middleint=yes # Type middleint + ###< create table crash_q (q middleint) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_mlslabel=no # Type mlslabel + ###< create table crash_q (q mlslabel) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'mlslabel)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_money=no # Type money + ###< create table crash_q (q money) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'money)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_nclob=no # Type nclob + ###< create table crash_q (q nclob) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nclob)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_number=no # Type number + ###< create table crash_q (q number) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_number(1_arg)=no # Type number(1 arg) + ###< create table crash_q (q number(9)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_number(2_arg)=no # Type number(2 arg) + ###< create table crash_q (q number(9,2)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9,2))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg) + ###< create table crash_q (q nvarchar2(16)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nvarchar2(16))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_path=no # Type path + ###< create table crash_q (q path) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'path)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_point=yes # Type point + ###< create table crash_q (q point) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_polygon=yes # Type polygon + ###< create table crash_q (q polygon) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_raw(1_arg)=no # Type raw(1 arg) + ###< create table crash_q (q raw(16)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw(16))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_reltime=no # Type reltime + ###< create table crash_q (q reltime) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'reltime)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_rowid=no # Type rowid + ###< create table crash_q (q rowid) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'rowid)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_serial=yes # Type serial + ###< create table crash_q (q serial) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_set(1_arg)=yes # Type set(1 arg) + ###< create table crash_q (q set('red')) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_smalldatetime=no # Type smalldatetime + ###< create table crash_q (q smalldatetime) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smalldatetime)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_smallfloat=no # Type smallfloat + ###< create table crash_q (q smallfloat) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallfloat)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_smallmoney=no # Type smallmoney + ###< create table crash_q (q smallmoney) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallmoney)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_text=yes # Type text + ###< create table crash_q (q text) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_text(1_arg)=yes # Type text(1 arg) + ###< create table crash_q (q text(10)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_extra_timespan=no # Type timespan + ###< create table crash_q (q timespan) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'timespan)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_uint=no # Type uint + ###< create table crash_q (q uint) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'uint)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_varchar2(1_arg)=no # Type varchar2(1 arg) + ###< create table crash_q (q varchar2(257)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar2(257))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_extra_year=yes # Type year + ###< create table crash_q (q year) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_odbc_bigint=yes # Type bigint + ###< create table crash_q (q bigint) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_odbc_binary(1_arg)=yes # Type binary(1 arg) + ###< create table crash_q (q binary(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_odbc_datetime=yes # Type datetime + ###< create table crash_q (q datetime) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_odbc_tinyint=yes # Type tinyint + ###< create table crash_q (q tinyint) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg) + ###< create table crash_q (q varbinary(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_bit=yes # Type bit + ###< create table crash_q (q bit) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_bit(1_arg)=yes # Type bit(1 arg) + ###< create table crash_q (q bit(2)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg) + ###< create table crash_q (q bit varying(2)) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varying(2))' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_boolean=yes # Type boolean + ###< create table crash_q (q boolean) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_char(1_arg)=yes # Type char(1 arg) + ###< create table crash_q (q char(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_char_varying(1_arg)=yes # Type char varying(1 arg) + ###< create table crash_q (q char varying(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_character(1_arg)=yes # Type character(1 arg) + ###< create table crash_q (q character(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_character_varying(1_arg)=yes # Type character varying(1 arg) + ###< create table crash_q (q character varying(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_date=yes # Type date + ###< create table crash_q (q date) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_dec(2_arg)=yes # Type dec(2 arg) + ###< create table crash_q (q dec(6,2)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_decimal(2_arg)=yes # Type decimal(2 arg) + ###< create table crash_q (q decimal(6,2)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_double_precision=yes # Type double precision + ###< create table crash_q (q double precision) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_float=yes # Type float + ###< create table crash_q (q float) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_float(1_arg)=yes # Type float(1 arg) + ###< create table crash_q (q float(8)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_int=yes # Type int + ###< create table crash_q (q int) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_integer=yes # Type integer + ###< create table crash_q (q integer) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_interval_day=no # Type interval day + ###< create table crash_q (q interval day) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_day_to_hour=no # Type interval day to hour + ###< create table crash_q (q interval day to hour) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to hour)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_day_to_minute=no # Type interval day to minute + ###< create table crash_q (q interval day to minute) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to minute)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_day_to_second=no # Type interval day to second + ###< create table crash_q (q interval day to second) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to second)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_hour=no # Type interval hour + ###< create table crash_q (q interval hour) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_hour_to_minute=no # Type interval hour to minute + ###< create table crash_q (q interval hour to minute) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to minute)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_hour_to_second=no # Type interval hour to second + ###< create table crash_q (q interval hour to second) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to second)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_minute=no # Type interval minute + ###< create table crash_q (q interval minute) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_minute_to_second=no # Type interval minute to second + ###< create table crash_q (q interval minute to second) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute to second)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_month=no # Type interval month + ###< create table crash_q (q interval month) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval month)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_second=no # Type interval second + ###< create table crash_q (q interval second) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval second)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_year=no # Type interval year + ###< create table crash_q (q interval year) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_interval_year_to_month=no # Type interval year to month + ###< create table crash_q (q interval year to month) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year to month)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg) + ###< create table crash_q (q national char varying(20)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_national_character(1_arg)=yes # Type national character(1 arg) + ###< create table crash_q (q national character(20)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg) + ###< create table crash_q (q national character varying(20)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_nchar(1_arg)=yes # Type nchar(1 arg) + ###< create table crash_q (q nchar(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg) + ###< create table crash_q (q nchar varying(20)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_numeric(2_arg)=yes # Type numeric(2 arg) + ###< create table crash_q (q numeric(9,2)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_real=yes # Type real + ###< create table crash_q (q real) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_smallint=yes # Type smallint + ###< create table crash_q (q smallint) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_time=yes # Type time + ###< create table crash_q (q time) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_timestamp=yes # Type timestamp + ###< create table crash_q (q timestamp) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +type_sql_timestamp_with_time_zone=no # Type timestamp with time zone + ###< create table crash_q (q timestamp with time zone) + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'with time zone)' at line 1 + ###< drop table crash_q + ###> execute error:Unknown table 'crash_q' + ### + ###As far as some queries didnt return OK, result is NO +type_sql_varchar(1_arg)=yes # Type varchar(1 arg) + ###< create table crash_q (q varchar(1)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +union=yes # union + ###< select * from crash_me union select a,b from crash_me3 + ###> OK + ### + ###As far as all queries returned OK, result is YES +union_all=yes # union all + ###< select * from crash_me union all select a,b from crash_me3 + ###> OK + ### + ###As far as all queries returned OK, result is YES +union_all_incompat=yes # union all (incompatible lists) + ###< select * from crash_me union all select a,b from crash_me2 + ###> OK + ### + ###As far as all queries returned OK, result is YES +union_incompat=yes # union (incompatible lists) + ###< select * from crash_me union select a,b from crash_me2 + ###> OK + ### + ###As far as all queries returned OK, result is YES +unique_in_create=yes # unique in create table + ###< create table crash_q (q integer not null,unique (q)) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +unique_null_in_create=yes # unique null in create + ###< create table crash_q (q integer,unique (q)) + ###> OK + ###< insert into crash_q (q) values (NULL) + ###> OK + ###< insert into crash_q (q) values (NULL) + ###> OK + ###< insert into crash_q (q) values (1) + ###> OK + ###< drop table crash_q + ###> OK + ### + ###As far as all queries returned OK, result is YES +value_of_false=0 # Value of FALSE + ###1 +views=no # views + ###< create view crash_q as select a from crash_me + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q as select a from crash_me' at line 1 + ###< drop view crash_q + ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q' at line 1 + ### + ###As far as some queries didnt return OK, result is NO +where_string_size=1048539 # constant string size in where + ###We are trying (example with N=5): + ###select a from crash_me where b >='11111' diff --git a/sql-bench/limits/mysql.cfg b/sql-bench/limits/mysql.cfg index 64f91f07363..76565cb16ff 100644 --- a/sql-bench/limits/mysql.cfg +++ b/sql-bench/limits/mysql.cfg @@ -1,7056 +1,1119 @@ #This file is automaticly generated by crash-me 1.61 NEG=yes # update of column= -column - ###< create table crash_q (a integer) - ###> OK - ###< insert into crash_q values(10) - ###> OK - ###< update crash_q set a=-a - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES Need_cast_for_null=no # Need to cast NULL for arithmetic - ### Check if numeric_null (NULL) is 'NULL' alter_add_col=yes # Alter table add column - ###< alter table crash_q add d integer - ###> OK - ### - ###As far as all queries returned OK, result is YES alter_add_constraint=yes # Alter table add constraint - ###< alter table crash_q add constraint c2 check(a > b) - ###> OK - ### - ###As far as all queries returned OK, result is YES -alter_add_foreign_key=no # Alter table add foreign key - ###< alter table crash_q add constraint f1 foreign key(c1) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 - ###< references crash_q1(c1) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'references crash_q1(c1)' at line 1 - ### - ###As far as some queries didnt return OK, result is NO +alter_add_foreign_key=yes # Alter table add foreign key alter_add_multi_col=yes # Alter table add many columns - ###< alter table crash_q add (f integer,g integer) - ###> OK alter_add_primary_key=with constraint # Alter table add primary key - ###< alter table crash_q1 add constraint p1 primary key(c1) - ###> OK alter_add_unique=yes # Alter table add unique - ###< alter table crash_q add constraint u1 unique(c1) - ###> OK - ### - ###As far as all queries returned OK, result is YES alter_alter_col=yes # Alter table alter column default - ###< alter table crash_q alter b set default 10 - ###> OK - ### - ###As far as all queries returned OK, result is YES alter_change_col=yes # Alter table change column - ###< alter table crash_q change a e char(50) - ###> OK - ### - ###As far as all queries returned OK, result is YES alter_drop_col=yes # Alter table drop column - ###< alter table crash_q drop column b - ###> OK alter_drop_constraint=no # Alter table drop constraint - ###< alter table crash_q drop constraint c2 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2' at line 1 - ### - ###< alter table crash_q drop constraint c2 restrict - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2 restrict' at line 1 alter_drop_foreign_key=with drop foreign key # Alter table drop foreign key - ###< alter table crash_q drop constraint f1 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1' at line 1 - ### - ###< alter table crash_q drop constraint f1 restrict - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1 restrict' at line 1 - ### - ###< alter table crash_q drop foreign key f1 - ###> OK alter_drop_primary_key=drop primary key # Alter table drop primary key - ###< alter table crash_q1 drop constraint p1 restrict - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint p1 restrict' at line 1 - ### - ###< alter table crash_q1 drop primary key - ###> OK alter_drop_unique=with drop key # Alter table drop unique - ###< alter table crash_q drop constraint u1 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1' at line 1 - ### - ###< alter table crash_q drop constraint u1 restrict - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1 restrict' at line 1 - ### - ###< alter table crash_q drop key u1 - ###> OK alter_modify_col=yes # Alter table modify column - ###< alter table crash_q modify c1 CHAR(20) - ###> OK alter_rename_table=yes # Alter table rename table - ###< alter table crash_q rename to crash_q1 - ###> OK - ### - ###As far as all queries returned OK, result is YES atomic_updates=no # atomic updates - ###< create table crash_q (a integer not null,primary key (a)) - ###> OK - ###< insert into crash_q values (2) - ###> OK - ###< insert into crash_q values (3) - ###> OK - ###< insert into crash_q values (1) - ###> OK - ###< update crash_q set a=a+1 - ###> execute error:Duplicate entry '3' for key 1 - ###< drop table crash_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO automatic_rowid=_rowid # Automatic row id - ###< create table crash_q (a int not null, primary key(a)) - ###> OK - ###< insert into crash_q values (1) - ###> OK - ###< select _rowid from crash_q - ###> OK - ###< drop table crash_q - ###> OK -binary_numbers=no # binary numbers (0b1001) - ###< select 0b1001 - ###> execute error:Unknown column '0b1001' in 'field list' - ### - ###As far as some queries didnt return OK, result is NO -binary_strings=no # binary strings (b'0110') - ###< select b'0110' - ###> execute error:Unknown column 'b' in 'field list' - ### - ###As far as some queries didnt return OK, result is NO +binary_numbers=yes # binary numbers (0b1001) +binary_strings=yes # binary strings (b'0110') case_insensitive_strings=yes # Case insensitive compare - ### - ###aa - ###We expected 'a a ' but got 'aa' column_alias=yes # Column alias - ###< select a as ab from crash_me - ###> OK - ### - ###As far as all queries returned OK, result is YES columns_in_group_by=+64 # number of columns in group by - ###We are trying (example with N=5): - ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer) - ###insert into crash_q values(1,1,1,1,1) - ###insert into crash_q values(1,1,1,1,1) - ###select q1,q2,q3,q4,q5 from crash_q group by q1,q2,q3,q4,q5 columns_in_order_by=+64 # number of columns in order by - ###We are trying (example with N=5): - ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer) - ###insert into crash_q values(1,1,1,1,1) - ###insert into crash_q values(1,1,1,1,1) - ###select * from crash_q order by q1,q2,q3,q4,q5 comment_#=yes # # as comment - ###< select * from crash_me # Testing of comments - ###> OK - ### - ###As far as all queries returned OK, result is YES comment_--=yes # -- as comment (ANSI) - ###< select * from crash_me -- Testing of comments - ###> OK - ### - ###As far as all queries returned OK, result is YES comment_/**/=yes # /* */ as comment - ###< select * from crash_me /* Testing of comments */ - ###> OK - ### - ###As far as all queries returned OK, result is YES comment_//=no # // as comment - ###< select * from crash_me // Testing of comments - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '// Testing of comments' at line 1 - ### - ###As far as some queries didnt return OK, result is NO compute=no # Compute - ###< select a from crash_me order by a compute sum(a) by a - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'compute sum(a) by a' at line 1 - ### - ###As far as some queries didnt return OK, result is NO connections=101 # Simultaneous connections (installation default) constraint_check=syntax only # Column constraints - ###< create table crash_q (a int check (a>0)) - ###> OK - ### - ###< insert into crash_q values(0) - ###> OK - ### - ###< drop table crash_q - ###> OK constraint_check_named=syntax only # Named constraints - ###< create table crash_q (a int ,b int, constraint abc check (a>b)) - ###> OK - ### - ###< insert into crash_q values(0,0) - ###> OK - ### - ###< drop table crash_q - ###> OK constraint_check_table=syntax only # Table constraints - ###< create table crash_q (a int ,b int, check (a>b)) - ###> OK - ### - ###< insert into crash_q values(0,0) - ###> OK - ### - ###< drop table crash_q - ###> OK constraint_null=yes # NULL constraint (SyBase style) - ###< create table crash_q (a int null) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES crash_me_safe=yes # crash me safe crash_me_version=1.61 # crash me version create_default=yes # default value for column - ###< create table crash_q (q integer default 10 not null) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES create_default_func=no # default value function for column - ###< create table crash_q (q integer not null,q1 integer default (1+1)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1+1))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO create_if_not_exists=yes # create table if not exists - ###< create table crash_q (q integer) - ###> OK - ###< create table if not exists crash_q (q integer) - ###> OK - ### - ###As far as all queries returned OK, result is YES create_index=yes # create index - ###< create index crash_q on crash_me (a) - ###> OK create_schema=no # Create SCHEMA - ###< create schema crash_schema create table crash_q (a int) create table crash_q2(b int) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema create table crash_q (a int) create table c - ###< drop schema crash_schema cascade - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema cascade' at line 1 - ### - ###As far as some queries didnt return OK, result is NO create_table_select=yes # create table from select - ###< create table crash_q SELECT * from crash_me - ###> OK cross_join=yes # cross join (same as from a,b) - ###< select crash_me.a from crash_me cross join crash_me3 - ###> OK - ### - ###As far as all queries returned OK, result is YES date_as_string=yes # String functions on date columns - ###< create table crash_me2 (a date not null) - ###> OK - ###< insert into crash_me2 values ('1998-03-03') - ###> OK - ### - ###0000-00-00 - ###We expected '1963-08-16' but got '0000-00-00' - ### - ###< delete from crash_me_d - ###> OK date_format_EUR_with_date=error # Supports DATE 'DD.MM.YYYY' (EUR) format - ###< insert into crash_me_d(a) values (DATE '16.08.1963') - ###> OK - ### - ###1963-08-16 - ### - ###< delete from crash_me_d - ###> OK date_format_ISO_with_date=yes # Supports DATE 'YYYY-MM-DD' (ISO) format - ###< insert into crash_me_d(a) values (DATE '1963-08-16') - ###> OK - ### - ###0000-00-00 - ###We expected '1963-08-16' but got '0000-00-00' - ### - ###< delete from crash_me_d - ###> OK date_format_USA_with_date=error # Supports DATE 'MM/DD/YYYY' format - ###< insert into crash_me_d(a) values (DATE '08/16/1963') - ###> OK - ### - ###1963-08-16 - ### - ###< delete from crash_me_d - ###> OK date_format_YYYYMMDD_with_date=yes # Supports DATE 'YYYYMMDD' format - ###< insert into crash_me_d(a) values (DATE '19630816') - ###> OK - ### - ###0000-00-00 - ###We expected 'infinity' but got '0000-00-00' - ### - ###< drop table crash_me2 - ###> OK date_last=yes # Supports 9999-12-31 dates - ###< create table crash_me2 (a date not null) - ###> OK - ###< insert into crash_me2 values ('9999-12-31') - ###> OK - ### - ###0001-01-01 - ### - ###< drop table crash_me2 - ###> OK date_with_YY=yes # Supports YY-MM-DD 2000 compilant dates - ###< create table crash_me2 (a date not null) - ###> OK - ###< insert into crash_me2 values ('98-03-03') - ###> OK - ### - ###2010-03-03 - ### - ###< drop table crash_me2 - ###> OK date_zero=yes # Supports 0000-00-00 dates - ###< create table crash_me2 (a date not null) - ###> OK - ###< insert into crash_me2 values ('0000-00-00') - ###> OK - ### - ###Walker's drop_if_exists=yes # drop table if exists - ###< create table crash_q (q integer) - ###> OK - ###< drop table if exists crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES drop_index=with 'ON' # drop index - ###< drop index crash_q - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 - ### - ###< drop index crash_q from crash_me - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'from crash_me' at line 1 - ### - ###< drop index crash_q on crash_me - ###> OK drop_requires_cascade=no # drop table require cascade/restrict - ###< create table crash_me (a integer not null) - ###> OK - ###< drop table crash_me - ###> OK drop_restrict=yes # drop table with cascade/restrict - ###< create table crash_q (a int) - ###> OK - ###< drop table crash_q restrict - ###> OK - ### - ###As far as all queries returned OK, result is YES end_colon=yes # allows end ';' - ###< select * from crash_me; - ###> OK - ### - ###As far as all queries returned OK, result is YES except=no # except - ###< select * from crash_me except select * from crash_me3 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1 - ### - ###As far as some queries didnt return OK, result is NO except_all=no # except all - ###< select * from crash_me except all select * from crash_me3 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1 - ### - ###As far as some queries didnt return OK, result is NO except_all_incompat=no # except all (incompatible lists) - ###< select * from crash_me except all select * from crash_me2 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1 - ### - ###As far as some queries didnt return OK, result is NO except_incompat=no # except (incompatible lists) - ###< select * from crash_me except select * from crash_me2 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1 - ### - ###As far as some queries didnt return OK, result is NO field_name_case=yes # case independent field names - ###< create table crash_q (q integer) - ###> OK - ###< insert into crash_q(Q) values (1) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES float_int_expr=yes # mixing of integer and float in expression - ###< select 1+1.0 - ###> OK - ### - ###As far as all queries returned OK, result is YES foreign_key=syntax only # foreign keys - ###< create table crash_me_qf (a integer not null,primary key (a)) - ###> OK - ### - ###< create table crash_me_qf2 (a integer not null,foreign key (a) references crash_me_qf (a)) - ###> OK - ### - ###< insert into crash_me_qf values (1) - ###> OK - ### - ###< insert into crash_me_qf2 values (2) - ###> OK - ### - ###< drop table crash_me_qf2 - ###> OK - ### - ###< drop table crash_me_qf - ###> OK full_outer_join=no # full outer join - ###< select crash_me.a from crash_me full join crash_me2 ON - ### crash_me.a=crash_me2.a - ###> execute error:Unknown table 'crash_me' in field list - ### - ###As far as some queries didnt return OK, result is NO func_extra_!=yes # Function NOT as '!' in SELECT - ### - ###3 func_extra_&=yes # Function & (bitwise and) - ### - ###1 func_extra_<>=yes # Function <> in SELECT - ### - ###1 func_extra_add_months=no # Function ADD_MONTHS - ### - ###2002-12-04 func_extra_addtime=yes # Function ADDTIME - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ',2)' at line 1 func_extra_and_or=yes # Function AND and OR in SELECT - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1 func_extra_ascii_code=no # Function ASCII_CODE - ### - ###97 - ###We expected 'a' but got '97' func_extra_atn2=no # Function ATN2 - ### - ###a2 func_extra_auto_string2num=yes # Function automatic string->num convert - ### - ###1 func_extra_binary_shifts=yes # Function << and >> (bitwise shifts) - ### - ###2 func_extra_ceil=yes # Function CEIL - ### - ### execute failed:Unknown column 'EUR' in 'field list' func_extra_charindex=no # Function CHARINDEX - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1 func_extra_chr_str=no # Function CHR (any type to string) - ### - ###0 - ###We expected 'abcdef' but got '0' func_extra_concat_list=yes # Function CONCAT(list) - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '5)' at line 1 func_extra_cosh=no # Function COSH - ### - ###1963-08-16 func_extra_date_format=yes # Function DATE_FORMAT - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(day,3,'1997-11-30') from crash_me_d' at line 1 func_extra_datediff=no # Function DATEDIFF - ### - ###3 func_extra_datename=no # Function DATENAME - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(month,'July 20 1997') from crash_me_d' at line 1 func_extra_day=yes # Function DAY - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1,'S-103',2,'Leopard',3)' at line 1 func_extra_ebcdic_string=no # Function EBCDIC in string cast - ### - ###TWO func_extra_encrypt=yes # Function ENCRYPT - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd',6)' at line 1 func_extra_field=yes # Function FIELD - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6666,10,2)' at line 1 func_extra_float=no # Function FLOAT - ### - ###1,234.56 func_extra_from_days=yes # Function FROM_DAYS - ### - ###1970-01-01 02:00:00 func_extra_getdate=no # Function GETDATE - ### - ###HARRY func_extra_hex=yes # Function HEX - ### - ###6 func_extra_in_num=yes # Function IN on numbers in SELECT - ### - ###1 func_extra_index=no # Function INDEX - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('the soap')' at line 1 func_extra_instr=yes # Function LOCATE as INSTR - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '3,2)' at line 1 func_extra_instrb=no # Function INSTRB - ### - ###5 func_extra_last_day=yes # Function LAST_DAY - ### - ###0 func_extra_least=yes # Function LEAST - ### - ###1 - ###We expected '2' but got '1' func_extra_lengthb=no # Function LENGTHB - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd','.',6)' at line 1 func_extra_like=yes # Function LIKE in SELECT - ### - ###1 func_extra_ln=yes # Function LN - ### - ###2.000000 func_extra_logn=no # Function LOGN - ### - ###??hi func_extra_ltrim2arg=no # Function LTRIM (2 arg) - ### - ###1963-08-16 func_extra_maketime=yes # Function MAKETIME - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ')' at line 1 func_extra_mdy=no # Function MDY - ### - ###110000 func_extra_mid=yes # Function SUBSTRING as MID - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1997-02-02','1997-01-01') from crash_me_d' at line 1 func_extra_noround=no # Function NOROUND - ###< select noround(22.6) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(22.6)' at line 1 func_extra_not=yes # Function NOT in SELECT - ### - ###0 func_extra_not_like=yes # Function NOT LIKE in SELECT - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('2123')' at line 1 func_extra_odbc_convert=no # Function ODBC CONVERT - ### - ###*6B4F89A54E2D27ECD7E8DA05B4AB8FD9D1D8B119 func_extra_paste=no # Function PASTE - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('%a%','crash')' at line 1 func_extra_period_add=yes # Function PERIOD_ADD - ### - ###13 func_extra_pow=yes # Function POW - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a)' at line 1 func_extra_regexp=yes # Function REGEXP in SELECT - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 func_extra_replicate=no # Function REPLICATE - ### - ###dcba func_extra_rfill3arg=no # Function RFILL (3 arg) - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(4)' at line 1 func_extra_round1=yes # Function ROUND(1 arg) - ### - ###hi?? func_extra_rpad4arg=no # Function RPAD (4 arg) - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1 func_extra_sec_to_time=yes # Function SEC_TO_TIME - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1 func_extra_str=no # Function STR - ### - ###-1 func_extra_stuff=no # Function STUFF - ### - ###2002-12-01 func_extra_substr2arg=yes # Function SUBSTR (2 arg) - ### - ###bc func_extra_substrb=no # Function SUBSTRB - ### - ###tcx.se func_extra_subtime=yes # Function SUBTIME - ### - ###2004-04-06 13:49:05 func_extra_tail=no # Function TAIL - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1 func_extra_time=yes # Function TIME - ### - ###5001 func_extra_timediff=yes # Function TIMEDIFF - ### - ###1963-08-16 20:02:12 - ###We expected '19630816200212000000' but got '1963-08-16 20:02:12' func_extra_to_days=yes # Function TO_DAYS - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','bc','de')' at line 1 func_extra_trim1arg=yes # Function TRIM (1 arg) - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1 func_extra_trim_many_char=error # Function TRIM; Many char extension - ### - ###abc func_extra_trunc=no # Function TRUNC - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6)' at line 1 func_extra_uid=no # Function UID - ### - ###1081248545 func_extra_userenv=no # Function USERENV - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(NULL,'WALRUS')' at line 1 func_extra_version=yes # Function VERSION - ### - ###5 func_extra_weekofyear=yes # Function WEEKOFYEAR - ### - ###3 func_extra_||=yes # Function OR as '||' - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '~* 'HI'' at line 1 func_odbc_abs=yes # Function ABS - ### - ###1.570796 func_odbc_ascii=yes # Function ASCII - ### - ###1.570796 func_odbc_atan=yes # Function ATAN - ### - ###1.570796 func_odbc_ceiling=yes # Function CEILING - ### - ###A func_odbc_concat=yes # Function CONCAT(2 arg) - ### - ###1.000000 func_odbc_cot=yes # Function COT - ### - ###2004-04-06 func_odbc_curtime=yes # Function CURTIME - ### - ###test func_odbc_dayname=yes # Function DAYNAME - ###< insert into crash_me_d values('1997-02-01') - ### - ###1 func_odbc_dayofweek=yes # Function DAYOFWEEK - ###< insert into crash_me_d values('1997-02-01') - ### - ###32 func_odbc_degrees=yes # Function DEGREES - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','abe')' at line 1 - ### - ###2.718282 func_odbc_floor=yes # Function FLOOR - ### - ###c func_odbc_hour=yes # Function HOUR - ###< insert into crash_me_t values(20:08:16) - ### - ###12 func_odbc_ifnull=yes # Function IFNULL - ### - ###aefd func_odbc_lcase=yes # Function LCASE - ### - ###ab func_odbc_length=yes # Function REAL LENGTH - ### - ###5 - ###We expected '4' but got '5' - ### - ###2 func_odbc_locate_3=yes # Function LOCATE(3 arg) - ### - ###0.693147 func_odbc_log10=yes # Function LOG10 - ### - ###abcd func_odbc_minute=yes # Function MINUTE - ###< insert into crash_me_t values(20:08:16) - ### - ###4 func_odbc_month=yes # Function MONTH - ###< insert into crash_me_d values('1997-02-01') - ### - ###February func_odbc_now=yes # Function NOW - ### - ###3.141593 func_odbc_power=yes # Function POWER - ### - ###1 func_odbc_radians=yes # Function RADIANS - ### - ###0.40540353712198 func_odbc_repeat=yes # Function REPEAT - ### - ###bababa func_odbc_right=yes # Function RIGHT - ### - ###5.63 func_odbc_rtrim=yes # Function RTRIM - ### - ###14 func_odbc_sign=yes # Function SIGN - ### - ###0.841471 func_odbc_soundex=yes # Function SOUNDEX - ### - ### func_odbc_sqrt=yes # Function SQRT - ### - ###cd func_odbc_tan=yes # Function TAN - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')' at line 1 - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')' - ### - ###10 func_odbc_ucase=yes # Function UCASE - ### - ###monty@localhost func_odbc_week=USA # WEEK - ###1997 func_sql_+=yes # Function +, -, * and / - ### - ###24 func_sql_cast=yes # Function CAST - ### - ###1 - ###We expected '10' but got '1' func_sql_char_length(constant)=yes # Function CHAR_LENGTH(constant) - ### - ###4 func_sql_coalesce=yes # Function COALESCE - ### - ###0 - ###We expected 'abcdef' but got '0' func_sql_current_date=yes # Function CURRENT_DATE - ### - ###13:49:04 func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP - ### - ###43 func_sql_localtime=yes # Function LOCALTIME - ### - ###2004-04-06 13:49:04 func_sql_lower=yes # Function LOWER - ### - ### func_sql_nullif_string=yes # Function NULLIF with strings - ### - ###3 func_sql_position=yes # Function POSITION - ### - ### 2 then 'false' when 2 > 1 then 'true' end - ###>true func_sql_session_user=with_parenthesis # SESSION_USER - ###< select SESSION_USER - ###> execute error:Unknown column 'SESSION_USER' in 'field list' - ### - ###< select SESSION_USER() - ###> OK func_sql_simple_case=yes # Function simple CASE - ### - ###bc func_sql_system_user=with_parenthesis # SYSTEM_USER - ###< select SYSTEM_USER - ###> execute error:Unknown column 'SYSTEM_USER' in 'field list' - ### - ###< select SYSTEM_USER() - ###> OK func_sql_trim=yes # Function TRIM - ### - ###ABC func_sql_user=with_parenthesis # USER - ###< select USER - ###> execute error:Unknown column 'USER' in 'field list' - ### - ###< select USER() - ###> OK func_where_between=yes # Function BETWEEN - ### - ###1 func_where_eq_any=yes # Function = ANY - ### - ###1 func_where_exists=yes # Function EXISTS - ### - ###1 func_where_like=yes # Function LIKE - ### - ###1 func_where_match=no # Function MATCH - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'match unique (select a from crash_me)' at line 1 func_where_matches=no # Function MATCHES - ### - ###1 func_where_not_exists=yes # Function NOT EXISTS - ### - ###1 func_where_not_unique=no # Function NOT UNIQUE - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'unique (select * from crash_me)' at line 1 functions=yes # Functions - ###< select 1+1 - ###> OK - ### - ###As far as all queries returned OK, result is YES group_by=yes # Group by - ###< select a from crash_me group by a - ###> OK - ### - ###As far as all queries returned OK, result is YES group_by_alias=yes # Group by alias - ###< select a as ab from crash_me group by ab - ###> OK - ### - ###As far as all queries returned OK, result is YES group_by_null=yes # Group on column with null values - ###< create table crash_q (s char(10)) - ###> OK - ###< insert into crash_q values(null) - ###> OK - ###< insert into crash_q values(null) - ###> OK - ### - ###1 group_func_extra_bit_or=yes # Group function BIT_OR - ### - ###1 group_func_extra_std=yes # Group function STD - ### - ###0.0000 group_func_extra_variance=yes # Group function VARIANCE - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1 group_func_sql_avg=yes # Group function AVG - ### - ###1 group_func_sql_count_column=yes # Group function COUNT column name - ### - ###1 group_func_sql_every=no # Group function EVERY - ### - ###1 group_func_sql_max_str=yes # Group function MAX on strings - ### - ###1 group_func_sql_min_str=yes # Group function MIN on strings - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1 group_func_sql_sum=yes # Group function SUM - ### - ### 0 - ###>1 - ### - ###a index_in_create=yes # index in create table - ###< create table crash_q (q integer not null,index (q)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES index_namespace=yes # different namespace for index - ###< create index crash_me on crash_me (b) - ###> OK - ###< drop index crash_me on crash_me - ###> OK - ### - ###As far as all queries returned OK, result is YES index_parts=yes # index on column part (extension) - ###< create index crash_q on crash_me (b(5)) - ###> OK - ###< drop index crash_q on crash_me - ###> OK - ### - ###As far as all queries returned OK, result is YES inner_join=yes # inner join - ###< select crash_me.a from crash_me inner join crash_me2 ON crash_me.a=crash_me2.a - ###> OK - ### - ###As far as all queries returned OK, result is YES insert_default_values=no # INSERT DEFAULT VALUES - ###< create table crash_me_q (a int) - ###> OK - ###< insert into crash_me_q DEFAULT VALUES - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1 - ###< drop table crash_me_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO insert_empty_string=yes # insert empty string - ###< create table crash_q (a char(10) not null,b char(10)) - ###> OK - ###< insert into crash_q values ('','') - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES insert_multi_value=yes # INSERT with Value lists - ###< create table crash_q (s char(10)) - ###> OK - ###< insert into crash_q values ('a'),('b') - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES insert_select=yes # insert INTO ... SELECT ... - ###< create table crash_q (a int) - ###> OK - ###< insert into crash_q (a) SELECT crash_me.a from crash_me - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES insert_with_default=yes # INSERT with DEFAULT - ###< create table crash_me_q (a int) - ###> OK - ###< insert into crash_me_q (a) values (DEFAULT) - ###> OK - ###< drop table crash_me_q - ###> OK - ### - ###As far as all queries returned OK, result is YES insert_with_empty_value_list=no # INSERT with empty value list - ###< create table crash_me_q (a int) - ###> OK - ###< insert into crash_me_q (a) values () - ###> execute error:Column count doesn't match value count at row 1 - ###< drop table crash_me_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO insert_with_set=yes # INSERT with set syntax - ###< create table crash_q (a integer) - ###> OK - ###< insert into crash_q SET a=1 - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES intersect=no # intersect - ###< select * from crash_me intersect select * from crash_me3 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1 - ### - ###As far as some queries didnt return OK, result is NO intersect_all=no # intersect all - ###< select * from crash_me intersect all select * from crash_me3 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1 - ### - ###As far as some queries didnt return OK, result is NO intersect_all_incompat=no # intersect all (incompatible lists) - ###< select * from crash_me intersect all select * from crash_me2 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1 - ### - ###As far as some queries didnt return OK, result is NO intersect_incompat=no # intersect (incompatible lists) - ###< select * from crash_me intersect select * from crash_me2 - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1 - ### - ###As far as some queries didnt return OK, result is NO join_tables=61 # tables in join - ###We are trying (example with N=5): - ###select crash_me.a,t0.a,t1.a,t2.a,t3.a,t4.a from crash_me,crash_me t0,crash_me t1,crash_me t2,crash_me t3,crash_me t4 - ### 32:OK 48:OK 56:OK 60:OK 62:FAIL 61:FAIL left_outer_join=yes # left outer join - ###< select crash_me.a from crash_me left join crash_me2 ON crash_me.a=crash_me2.a - ###> OK - ### - ###As far as all queries returned OK, result is YES left_outer_join_using=yes # left outer join using - ###< select c1 from crash_me left join crash_me2 using (a) - ###> OK - ### - ###As far as all queries returned OK, result is YES length_of_varchar_field=actual length # CHARACTER_LENGTH(varchar_field) - ###< CREATE TABLE crash_me1 (S1 VARCHAR(100)) - ###> OK - ###< INSERT INTO crash_me1 VALUES ('X') - ###> OK - ### - ###< SELECT CHARACTER_LENGTH(S1) FROM crash_me1 - ### > 1 - ###< drop table crash_me1 - ###> OK like_with_column=yes # column LIKE column - ###< create table crash_q (a char(10),b char(10)) - ###> OK - ###< insert into crash_q values('abc','abc') - ###> OK - ###< select * from crash_q where a like b - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES like_with_number=yes # LIKE on numbers - ###< create table crash_q (a int,b int) - ###> OK - ###< insert into crash_q values(10,10) - ###> OK - ###< select * from crash_q where a like '10' - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES lock_tables=yes # lock table - ###< lock table crash_me READ - ###> OK - ###< unlock tables - ###> OK - ### - ###As far as all queries returned OK, result is YES logical_value=1 # Value of logical operation (1=1) - ###2 multi_drop=yes # many tables to drop table - ###< create table crash_q (a int) - ###> OK - ###< create table crash_q2 (a int) - ###> OK - ###< drop table crash_q,crash_q2 - ###> OK - ### - ###As far as all queries returned OK, result is YES multi_null_in_unique=yes # null in unique index - ###< create table crash_q (q integer, x integer,unique (q)) - ###> OK - ###< insert into crash_q(x) values(1) - ###> OK - ###< insert into crash_q(x) values(2) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES multi_strings=yes # Multiple line strings - ### - ###a - ### - ###< drop table crash_q - ###> OK natural_join=yes # natural join - ###< select * from crash_me natural join crash_me3 - ###> OK - ### - ###As far as all queries returned OK, result is YES natural_join_incompat=yes # natural join (incompatible lists) - ###< select c1 from crash_me natural join crash_me2 - ###> OK - ### - ###As far as all queries returned OK, result is YES natural_left_outer_join=yes # natural left outer join - ###< select c1 from crash_me natural left join crash_me2 - ###> OK - ### - ###As far as all queries returned OK, result is YES no_primary_key=yes # Tables without primary key - ###< create table crash_me (a integer not null,b char(10) not null) - ###> OK - ###< insert into crash_me (a,b) values (1,'a') - ###> OK -not_id_between=no # NOT ID BETWEEN interprets as ID NOT BETWEEN - ###< create table crash_me_b (i int) - ###> OK - ###< insert into crash_me_b values(2) - ###> OK - ###< insert into crash_me_b values(5) - ###> OK - ### - ### null_in_index=yes # null in index - ###< create table crash_q (a char(10),index (a)) - ###> OK - ###< insert into crash_q values (NULL) - ###> OK - ### - ### nulls_in_unique=yes # null combination in unique index - ###< create table crash_q (q integer,q1 integer,unique (q,q1)) - ###> OK - ###< insert into crash_q (q,q1) values(1,NULL) - ###> OK - ###< insert into crash_q (q,q1) values(1,NULL) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES odbc_left_outer_join=yes # left outer join odbc style - ###< select crash_me.a from { oj crash_me left outer join crash_me2 ON crash_me.a=crash_me2.a } - ###> OK - ### - ###As far as all queries returned OK, result is YES -operating_system=Linux 2.4.21-199-smp4G i686 # crash-me tested on +operating_system=Linux 2.6.8-my i686 # crash-me tested on order_by=yes # Order by - ###< select a from crash_me order by a - ###> OK - ### - ###As far as all queries returned OK, result is YES order_by_alias=yes # Order by alias - ###< select a as ab from crash_me order by ab - ###> OK - ### - ###As far as all queries returned OK, result is YES order_by_function=yes # Order by function - ###< select a from crash_me order by a+1 - ###> OK - ### - ###As far as all queries returned OK, result is YES order_by_position=yes # Order by position - ###< select a from crash_me order by 1 - ###> OK - ### - ###As far as all queries returned OK, result is YES order_on_unused=yes # Order by on unused column - ###< select b from crash_me order by a - ###> OK - ### - ###As far as all queries returned OK, result is YES position_of_null=first # Where is null values in sorted recordset - ###< insert into crash_me_n (i) values(1) - ###> OK - ###< insert into crash_me_n values(2,2) - ###> OK - ###< insert into crash_me_n values(3,3) - ###> OK - ###< insert into crash_me_n values(4,4) - ###> OK - ###< insert into crash_me_n (i) values(5) - ###> OK - ### - ###< select r from crash_me_n order by r - ###> - ###> - ###> 2 - ###> 3 - ###> 4 position_of_null_desc=last # Where is null values in sorted recordset (DESC) - ###< select r from crash_me_n order by r desc - ###> 4 - ###> 3 - ###> 2 - ###> - ###> primary_key_in_create=yes # primary key in create table - ###< create table crash_q (q integer not null,primary key (q)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES psm_functions=no # PSM functions (ANSI SQL) - ###< create table crash_q (a int) - ###> OK - ###< create function crash_func(in a1 int, in b1 int) returns int language sql deterministic contains sql begin return a1 * b1; end - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(in a1 int, in b1 int) returns int language sql deterministic c - ###< insert into crash_q values(crash_func(2,4)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(2,4))' at line 1 - ###< select a,crash_func(a,2) from crash_q - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a,2) from crash_q' at line 1 - ###< drop function crash_func cascade - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cascade' at line 1 - ###< drop table crash_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO psm_modules=no # PSM modules (ANSI SQL) - ###< create table crash_q (a int,b int) - ###> OK - ###< create module crash_m declare procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end; declare procedure crash_proc2(INOUT a int, in b int) contains sql set a = b + 10; end module - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m declare procedure crash_proc(in a1 int, in b1 in - ###< call crash_proc(1,10) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1 - ###< drop module crash_m cascade - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m cascade' at line 1 - ###< drop table crash_q cascade - ###> OK - ### - ###As far as some queries didnt return OK, result is NO psm_procedures=no # PSM procedures (ANSI SQL) - ###< create table crash_q (a int,b int) - ###> OK - ###< create procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc(in a1 int, in b1 int) language sql modifie - ###< call crash_proc(1,10) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1 - ###< drop procedure crash_proc - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc' at line 1 - ###< drop table crash_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO psm_trigger=no # Triggers (ANSI SQL) - ###< create table crash_q (a int ,b int) - ###> OK - ###< create trigger crash_trigger after insert on crash_q referencing new table as new_a when (localtime > time '18:00:00') begin atomic end - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger after insert on crash_q referencing new t - ###< insert into crash_q values(1,2) - ###> OK - ###< drop trigger crash_trigger - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger' at line 1 - ###< drop table crash_q - ###> OK - ### - ###As far as some queries didnt return OK, result is NO query_size=1048574 # query size quote_ident_with_"=error # " as identifier quote (ANSI SQL) - ### - ### execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '[A] from crash_me' at line 1 quote_ident_with_`=yes # ` as identifier quote - ### - ###hello - ###We expected 'hello ' but got 'hello' - ### - ###< drop table crash_q - ###> OK -remember_end_space_varchar=no # Remembers end space in varchar() - ###< create table crash_q (a varchar(10)) - ###> OK - ###< insert into crash_q values('hello ') - ###> OK - ### - ###0 - ###We expected '1' but got '0' +safe_decimal_arithmetic=yes # safe decimal arithmetic select_constants=yes # Select constants - ###< select 1 - ###> OK - ### - ###As far as all queries returned OK, result is YES select_limit=with LIMIT # LIMIT number of rows - ###< select * from crash_me limit 1 - ###> OK select_limit2=yes # SELECT with LIMIT #,# - ###< select * from crash_me limit 1,1 - ###> OK - ### - ###As far as all queries returned OK, result is YES select_limit3=yes # SELECT with LIMIT # OFFSET # - ###< select * from crash_me limit 1 offset 1 - ###> OK - ### - ###As far as all queries returned OK, result is YES select_string_size=1048565 # constant string size in SELECT - ###We are trying (example with N=5): - ###select 'aaaaa' select_table_update=yes # Update with sub select - ###< create table crash_q (a integer,b char(10)) - ###> OK - ###< insert into crash_q values(1,'c') - ###> OK - ###< update crash_q set b= (select b from crash_me where crash_q.a = crash_me.a) - ###> OK - ### - ###1.1 - ### - ###< drop table crash_q - ###> OK - ### - ###< create table crash_q (q1 float(4,1)) - ###> OK - ###< insert into crash_q values(1.16) - ###> OK - ### - ###1.1 - ### - ###< drop table crash_q - ###> OK - ### - ###< create table crash_q (q1 float(4,1)) - ###> OK - ###< insert into crash_q values(1.16) - ###> OK - ### - ###00:00:20 - ###We expected '20:08:16' but got '00:00:20' - ### - ###< delete from crash_me_t - ###> OK time_format_HHHHMMSS=yes # Supports HHHHmmSS time format - ###< insert into crash_me_t(a) values ('00200816') - ###> OK - ### - ###20:08:16 - ### - ###< delete from crash_me_t - ###> OK time_format_USA=error # Supports HH:MM:SS (AM|PM) time format - ###< insert into crash_me_t(a) values ('08:08:16 PM') - ###> OK - ### - ###1 - ###We expected '' but got '1' truncate_table=yes # truncate - ###< create table crash_q (a integer, b integer,c1 CHAR(10)) - ###> OK - ###< truncate table crash_q - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_abstime=no # Type abstime - ###< create table crash_q (q abstime) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'abstime)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_bfile=no # Type bfile - ###< create table crash_q (q bfile) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'bfile)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_blob=yes # Type blob - ###< create table crash_q (q blob) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_bool=yes # Type bool - ###< create table crash_q (q bool) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_box=no # Type box - ###< create table crash_q (q box) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'box)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_byte=no # Type byte - ###< create table crash_q (q byte) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'byte)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_char(1_arg)_binary=yes # Type char(1 arg) binary - ###< create table crash_q (q char(10) binary) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_cidr=no # Type cidr - ###< create table crash_q (q cidr) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cidr)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_circle=no # Type circle - ###< create table crash_q (q circle) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'circle)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_clob=no # Type clob - ###< create table crash_q (q clob) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'clob)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_datetime=yes # Type datetime - ###< create table crash_q (q datetime) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_double=yes # Type double - ###< create table crash_q (q double) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_enum(1_arg)=yes # Type enum(1 arg) - ###< create table crash_q (q enum('red')) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_float(2_arg)=yes # Type float(2 arg) - ###< create table crash_q (q float(6,2)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_float4=yes # Type float4 - ###< create table crash_q (q float4) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_float8=yes # Type float8 - ###< create table crash_q (q float8) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_image=no # Type image - ###< create table crash_q (q image) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'image)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_inet=no # Type inet - ###< create table crash_q (q inet) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'inet)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_int(1_arg)_zerofill=yes # Type int(1 arg) zerofill - ###< create table crash_q (q int(5) zerofill) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int1=yes # Type int1 - ###< create table crash_q (q int1) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int2=yes # Type int2 - ###< create table crash_q (q int2) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int3=yes # Type int3 - ###< create table crash_q (q int3) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int4=yes # Type int4 - ###< create table crash_q (q int4) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int8=yes # Type int8 - ###< create table crash_q (q int8) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int_auto_increment=yes # Type int not null auto_increment - ###< create table crash_q (q int not null auto_increment,unique(q)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_int_identity=no # Type int not null identity - ###< create table crash_q (q int not null identity,unique(q)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'identity,unique(q))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_int_unsigned=yes # Type int unsigned - ###< create table crash_q (q int unsigned) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_interval=no # Type interval - ###< create table crash_q (q interval) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_line=no # Type line - ###< create table crash_q (q line) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'line)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_long=yes # Type long - ###< create table crash_q (q long) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_long_raw=no # Type long raw - ###< create table crash_q (q long raw) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_long_varbinary=yes # Type long varbinary - ###< create table crash_q (q long varbinary) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg) - ###< create table crash_q (q long varchar(1)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_lseg=no # Type lseg - ###< create table crash_q (q lseg) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'lseg)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_macaddr=no # Type macaddr - ###< create table crash_q (q macaddr) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'macaddr)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_mediumint=yes # Type mediumint - ###< create table crash_q (q mediumint) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_mediumtext=yes # Type mediumtext - ###< create table crash_q (q mediumtext) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_middleint=yes # Type middleint - ###< create table crash_q (q middleint) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_mlslabel=no # Type mlslabel - ###< create table crash_q (q mlslabel) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'mlslabel)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_money=no # Type money - ###< create table crash_q (q money) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'money)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_nclob=no # Type nclob - ###< create table crash_q (q nclob) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nclob)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_number=no # Type number - ###< create table crash_q (q number) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_number(1_arg)=no # Type number(1 arg) - ###< create table crash_q (q number(9)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_number(2_arg)=no # Type number(2 arg) - ###< create table crash_q (q number(9,2)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9,2))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg) - ###< create table crash_q (q nvarchar2(16)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nvarchar2(16))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_path=no # Type path - ###< create table crash_q (q path) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'path)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_point=yes # Type point - ###< create table crash_q (q point) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_polygon=yes # Type polygon - ###< create table crash_q (q polygon) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_raw(1_arg)=no # Type raw(1 arg) - ###< create table crash_q (q raw(16)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw(16))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_reltime=no # Type reltime - ###< create table crash_q (q reltime) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'reltime)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_rowid=no # Type rowid - ###< create table crash_q (q rowid) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'rowid)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_serial=yes # Type serial - ###< create table crash_q (q serial) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_set(1_arg)=yes # Type set(1 arg) - ###< create table crash_q (q set('red')) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_smalldatetime=no # Type smalldatetime - ###< create table crash_q (q smalldatetime) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smalldatetime)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_smallfloat=no # Type smallfloat - ###< create table crash_q (q smallfloat) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallfloat)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_smallmoney=no # Type smallmoney - ###< create table crash_q (q smallmoney) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallmoney)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_text=yes # Type text - ###< create table crash_q (q text) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_text(1_arg)=yes # Type text(1 arg) - ###< create table crash_q (q text(10)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_extra_timespan=no # Type timespan - ###< create table crash_q (q timespan) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'timespan)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_uint=no # Type uint - ###< create table crash_q (q uint) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'uint)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_varchar2(1_arg)=no # Type varchar2(1 arg) - ###< create table crash_q (q varchar2(257)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar2(257))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_extra_year=yes # Type year - ###< create table crash_q (q year) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_odbc_bigint=yes # Type bigint - ###< create table crash_q (q bigint) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_odbc_binary(1_arg)=yes # Type binary(1 arg) - ###< create table crash_q (q binary(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_odbc_datetime=yes # Type datetime - ###< create table crash_q (q datetime) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_odbc_tinyint=yes # Type tinyint - ###< create table crash_q (q tinyint) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg) - ###< create table crash_q (q varbinary(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_bit=yes # Type bit - ###< create table crash_q (q bit) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_bit(1_arg)=yes # Type bit(1 arg) - ###< create table crash_q (q bit(2)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg) - ###< create table crash_q (q bit varying(2)) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varying(2))' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_boolean=yes # Type boolean - ###< create table crash_q (q boolean) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_char(1_arg)=yes # Type char(1 arg) - ###< create table crash_q (q char(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_char_varying(1_arg)=yes # Type char varying(1 arg) - ###< create table crash_q (q char varying(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_character(1_arg)=yes # Type character(1 arg) - ###< create table crash_q (q character(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_character_varying(1_arg)=yes # Type character varying(1 arg) - ###< create table crash_q (q character varying(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_date=yes # Type date - ###< create table crash_q (q date) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_dec(2_arg)=yes # Type dec(2 arg) - ###< create table crash_q (q dec(6,2)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_decimal(2_arg)=yes # Type decimal(2 arg) - ###< create table crash_q (q decimal(6,2)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_double_precision=yes # Type double precision - ###< create table crash_q (q double precision) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_float=yes # Type float - ###< create table crash_q (q float) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_float(1_arg)=yes # Type float(1 arg) - ###< create table crash_q (q float(8)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_int=yes # Type int - ###< create table crash_q (q int) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_integer=yes # Type integer - ###< create table crash_q (q integer) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_interval_day=no # Type interval day - ###< create table crash_q (q interval day) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_day_to_hour=no # Type interval day to hour - ###< create table crash_q (q interval day to hour) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to hour)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_day_to_minute=no # Type interval day to minute - ###< create table crash_q (q interval day to minute) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to minute)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_day_to_second=no # Type interval day to second - ###< create table crash_q (q interval day to second) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to second)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_hour=no # Type interval hour - ###< create table crash_q (q interval hour) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_hour_to_minute=no # Type interval hour to minute - ###< create table crash_q (q interval hour to minute) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to minute)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_hour_to_second=no # Type interval hour to second - ###< create table crash_q (q interval hour to second) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to second)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_minute=no # Type interval minute - ###< create table crash_q (q interval minute) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_minute_to_second=no # Type interval minute to second - ###< create table crash_q (q interval minute to second) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute to second)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_month=no # Type interval month - ###< create table crash_q (q interval month) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval month)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_second=no # Type interval second - ###< create table crash_q (q interval second) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval second)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_year=no # Type interval year - ###< create table crash_q (q interval year) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_interval_year_to_month=no # Type interval year to month - ###< create table crash_q (q interval year to month) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year to month)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg) - ###< create table crash_q (q national char varying(20)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_national_character(1_arg)=yes # Type national character(1 arg) - ###< create table crash_q (q national character(20)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg) - ###< create table crash_q (q national character varying(20)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_nchar(1_arg)=yes # Type nchar(1 arg) - ###< create table crash_q (q nchar(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg) - ###< create table crash_q (q nchar varying(20)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_numeric(2_arg)=yes # Type numeric(2 arg) - ###< create table crash_q (q numeric(9,2)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_real=yes # Type real - ###< create table crash_q (q real) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_smallint=yes # Type smallint - ###< create table crash_q (q smallint) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_time=yes # Type time - ###< create table crash_q (q time) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_timestamp=yes # Type timestamp - ###< create table crash_q (q timestamp) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES type_sql_timestamp_with_time_zone=no # Type timestamp with time zone - ###< create table crash_q (q timestamp with time zone) - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'with time zone)' at line 1 - ###< drop table crash_q - ###> execute error:Unknown table 'crash_q' - ### - ###As far as some queries didnt return OK, result is NO type_sql_varchar(1_arg)=yes # Type varchar(1 arg) - ###< create table crash_q (q varchar(1)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES union=yes # union - ###< select * from crash_me union select a,b from crash_me3 - ###> OK - ### - ###As far as all queries returned OK, result is YES union_all=yes # union all - ###< select * from crash_me union all select a,b from crash_me3 - ###> OK - ### - ###As far as all queries returned OK, result is YES union_all_incompat=yes # union all (incompatible lists) - ###< select * from crash_me union all select a,b from crash_me2 - ###> OK - ### - ###As far as all queries returned OK, result is YES union_incompat=yes # union (incompatible lists) - ###< select * from crash_me union select a,b from crash_me2 - ###> OK - ### - ###As far as all queries returned OK, result is YES unique_in_create=yes # unique in create table - ###< create table crash_q (q integer not null,unique (q)) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES unique_null_in_create=yes # unique null in create - ###< create table crash_q (q integer,unique (q)) - ###> OK - ###< insert into crash_q (q) values (NULL) - ###> OK - ###< insert into crash_q (q) values (NULL) - ###> OK - ###< insert into crash_q (q) values (1) - ###> OK - ###< drop table crash_q - ###> OK - ### - ###As far as all queries returned OK, result is YES value_of_false=0 # Value of FALSE - ###1 -views=no # views - ###< create view crash_q as select a from crash_me - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q as select a from crash_me' at line 1 - ###< drop view crash_q - ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q' at line 1 - ### - ###As far as some queries didnt return OK, result is NO +views=yes # views where_string_size=1048539 # constant string size in where - ###We are trying (example with N=5): - ###select a from crash_me where b >='11111' diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index 4f0cfb91d20..93cedcbf251 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -14,8 +14,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index 66d1a801333..9da297ccd1f 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -63,8 +63,6 @@ -Brian */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 6ca7f67ef66..a030960d08a 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -38,8 +38,6 @@ TODO: -Brian */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/field.cc b/sql/field.cc index 7e2e32083e1..89ef25475ff 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -19,8 +19,6 @@ ** This file implements classes defined in field.h *****************************************************************************/ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -984,6 +982,39 @@ Item_result Field::result_merge_type(enum_field_types field_type) Static help functions *****************************************************************************/ + +/* + Check whether a field type can be partially indexed by a key + + This is a static method, rather than a virtual function, because we need + to check the type of a non-Field in mysql_alter_table(). + + SYNOPSIS + type_can_have_key_part() + type field type + + RETURN + TRUE Type can have a prefixed key + FALSE Type can not have a prefixed key +*/ + +bool Field::type_can_have_key_part(enum enum_field_types type) +{ + switch (type) { + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + return TRUE; + default: + return FALSE; + } +} + + /* Numeric fields base class constructor */ @@ -2448,7 +2479,7 @@ int Field_new_decimal::store(longlong nr) int err; if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, - nr, unsigned_flag, &decimal_value))) + nr, false, &decimal_value))) { if (check_overflow(err)) set_value_on_overflow(&decimal_value, decimal_value.sign()); @@ -7835,7 +7866,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) int Field_bit::store(double nr) { - return (Field_bit::store((longlong) nr)); + return store((longlong) nr); } @@ -8018,7 +8049,8 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) (delta == 0 && bits && (uint) (uchar) *from >= (uint) (1 << bits))) { memset(ptr, 0xff, field_length); - *ptr&= ((1 << bits) - 1); /* set first byte */ + if (bits) + *ptr&= ((1 << bits) - 1); /* set first byte */ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; } diff --git a/sql/field.h b/sql/field.h index d58746b6068..a522558a8d7 100644 --- a/sql/field.h +++ b/sql/field.h @@ -119,6 +119,7 @@ public: virtual Item_result result_type () const=0; virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cast_to_int_type () const { return result_type(); } + static bool type_can_have_key_part(enum_field_types); static enum_field_types field_type_merge(enum_field_types, enum_field_types); static Item_result result_merge_type(enum_field_types); bool eq(Field *field) diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 46f510bb905..16cbd782f0c 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -47,13 +47,12 @@ */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" + #ifdef HAVE_BERKELEY_DB #include #include diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 00128d3d3b6..6abbe983f48 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -15,14 +15,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation // gcc: Class implementation +#pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" - #ifdef HAVE_BLACKHOLE_DB #include "ha_blackhole.h" diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index c76034c7986..89210a2f3cd 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -345,12 +345,11 @@ */ -#ifdef __GNUC__ +#include "mysql_priv.h" +#ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif -#include "mysql_priv.h" - #ifdef HAVE_FEDERATED_DB #include "ha_federated.h" #define MAX_REMOTE_SIZE IO_SIZE diff --git a/sql/ha_federated.h b/sql/ha_federated.h index 22fc03e9eec..f084976718c 100644 --- a/sql/ha_federated.h +++ b/sql/ha_federated.h @@ -21,7 +21,7 @@ that you can implement. */ -#ifdef __GNUC__ +#ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 3581b26a585..cd655eeb0a9 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -15,8 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 5d50270ec5b..2aa065e0d96 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -57,6 +57,7 @@ public: } const key_map *keys_to_use_for_scanning() { return &btree_keys; } uint max_supported_keys() const { return MAX_KEY; } + uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } double scan_time() { return (double) (records+deleted) / 20.0+10; } double read_time(uint index, uint ranges, ha_rows rows) { return (double) rows / 20.0+1; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d956e692152..4ed005874f1 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -27,8 +27,6 @@ have disables the InnoDB inlining in this file. */ in Windows? */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -3223,6 +3221,23 @@ no_commit: } } + /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate + key error themselves, and we must update the autoinc counter if we are + performing those statements. */ + + if (error == DB_DUPLICATE_KEY && auto_inc_used + && (user_thd->lex->sql_command == SQLCOM_REPLACE + || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT + || (user_thd->lex->sql_command == SQLCOM_LOAD + && user_thd->lex->duplicates == DUP_REPLACE))) { + + auto_inc = table->next_number_field->val_int(); + + if (auto_inc != 0) { + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 3b17512c6c2..1352fd84d9d 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -15,8 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index d4dc365a163..0796ded3ac0 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -15,8 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4785bf7bd49..b727609f7ef 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -20,10 +20,8 @@ NDB Cluster */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation // gcc: Class implementation +#pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" @@ -5592,8 +5590,8 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index; const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation(); NdbIndexScanOperation* scanOp= 0; - for(; multi_range_currs->reclength; const NdbOperation* op= m_current_multi_operation; - for(;multi_range_curr < m_multi_range_defined; multi_range_curr++) + for (;multi_range_curr < m_multi_range_defined; multi_range_curr++) { if (multi_range_curr->range_flag & UNIQUE_RANGE) { diff --git a/sql/handler.cc b/sql/handler.cc index ffd6fbc5916..1973cd71d46 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -17,8 +17,6 @@ /* Handler-calling-functions */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -597,6 +595,27 @@ int ha_commit_trans(THD *thd, bool all) handlerton **ht= trans->ht; my_xid xid= thd->transaction.xid.get_my_xid(); DBUG_ENTER("ha_commit_trans"); + + if (thd->transaction.in_sub_stmt) + { + /* + Since we don't support nested statement transactions in 5.0, + we can't commit or rollback stmt transactions while we are inside + stored functions or triggers. So we simply do nothing now. + TODO: This should be fixed in later ( >= 5.1) releases. + */ + if (!all) + DBUG_RETURN(0); + /* + We assume that all statements which commit or rollback main transaction + are prohibited inside of stored functions or triggers. So they should + bail out with error even before ha_commit_trans() call. To be 100% safe + let us throw error in non-debug builds. + */ + DBUG_ASSERT(0); + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + DBUG_RETURN(2); + } #ifdef USING_TRANSACTIONS if (trans->nht) { @@ -691,6 +710,19 @@ int ha_rollback_trans(THD *thd, bool all) THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; bool is_real_trans=all || thd->transaction.all.nht == 0; DBUG_ENTER("ha_rollback_trans"); + if (thd->transaction.in_sub_stmt) + { + /* + If we are inside stored function or trigger we should not commit or + rollback current statement transaction. See comment in ha_commit_trans() + call for more information. + */ + if (!all) + DBUG_RETURN(0); + DBUG_ASSERT(0); + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + DBUG_RETURN(1); + } #ifdef USING_TRANSACTIONS if (trans->nht) { diff --git a/sql/hash_filo.cc b/sql/hash_filo.cc index 34f3cd6b035..ec200768222 100644 --- a/sql/hash_filo.cc +++ b/sql/hash_filo.cc @@ -20,8 +20,6 @@ ** to usage. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/item.cc b/sql/item.cc index a9c1ef7198e..680b771f908 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -15,12 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif - #include "mysql_priv.h" #include #include "my_dir.h" @@ -2248,9 +2245,8 @@ bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) SELECT_LEX_UNIT::item set only for subqueries, so test of it presence can be barrier to stop before derived table SELECT or very outer SELECT */ - for(; - cursel->master_unit()->item; - cursel= cursel->outer_select()) + for (; cursel->master_unit()->item; + cursel= cursel->outer_select()) { Item_subselect *subselect_item= cursel->master_unit()->item; subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; @@ -2530,9 +2526,8 @@ void mark_select_range_as_dependent(THD *thd, resolving) */ SELECT_LEX *previous_select= current_sel; - for(; - previous_select->outer_select() != last_select; - previous_select= previous_select->outer_select()) + for (; previous_select->outer_select() != last_select; + previous_select= previous_select->outer_select()) { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; @@ -4419,8 +4414,7 @@ bool Item_direct_ref::val_bool() bool Item_direct_ref::is_null() { - (void) (*ref)->val_int(); - return (*ref)->null_value; + return (*ref)->is_null(); } diff --git a/sql/item.h b/sql/item.h index 4f5ed9934c5..1fe90a41e3a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -284,7 +284,9 @@ public: Item(THD *thd, Item *item); virtual ~Item() { +#ifdef EXTRA_DEBUG name=0; +#endif } /*lint -e1509 */ void set_name(const char *str,uint length, CHARSET_INFO *cs); void rename(char *new_name); @@ -334,6 +336,11 @@ public: If value is not null null_value flag will be reset to FALSE. */ virtual longlong val_int()=0; + /* + This is just a shortcut to avoid the cast. You should still use + unsigned_flag to check the sign of the item. + */ + inline ulonglong val_uint() { return (ulonglong) val_int(); } /* Return string representation of this item object. @@ -978,10 +985,10 @@ public: longlong value; Item_int(int32 i,uint length=11) :value((longlong) i) { max_length=length; fixed= 1; } -#ifdef HAVE_LONG_LONG Item_int(longlong i,uint length=21) :value(i) { max_length=length; fixed= 1; } -#endif + Item_int(ulonglong i, uint length= 21) :value((longlong)i) + { max_length=length; fixed= 1; unsigned_flag= 1; } Item_int(const char *str_arg,longlong i,uint length) :value(i) { max_length=length; name=(char*) str_arg; fixed= 1; } Item_int(const char *str_arg, uint length=64); @@ -1019,9 +1026,8 @@ class Item_uint :public Item_int { public: Item_uint(const char *str_arg, uint length); + Item_uint(uint32 i) :Item_int((ulonglong) i, 10) {} Item_uint(const char *str_arg, longlong i, uint length); - Item_uint(uint32 i) :Item_int((longlong) i, 10) - { unsigned_flag= 1; } double val_real() { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); } String *val_str(String*); @@ -1501,7 +1507,7 @@ class Item_str_buff :public Item_buff Item *item; String value,tmp_value; public: - Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {} + Item_str_buff(THD *thd, Item *arg); bool cmp(void); ~Item_str_buff(); // Deallocate String:s }; @@ -1870,7 +1876,7 @@ void mark_select_range_as_dependent(THD *thd, Field *found_field, Item *found_item, Item_ident *resolved_item); -extern Item_buff *new_Item_buff(Item *item); +extern Item_buff *new_Item_buff(THD *thd, Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item); extern bool field_is_equal_to_item(Field *field,Item *item); diff --git a/sql/item_buff.cc b/sql/item_buff.cc index af17d377e31..688e4cca846 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -23,14 +23,14 @@ ** Create right type of item_buffer for an item */ -Item_buff *new_Item_buff(Item *item) +Item_buff *new_Item_buff(THD *thd, Item *item) { if (item->type() == Item::FIELD_ITEM && !(((Item_field *) item)->field->flags & BLOB_FLAG)) return new Item_field_buff((Item_field *) item); switch (item->result_type()) { case STRING_RESULT: - return new Item_str_buff((Item_field *) item); + return new Item_str_buff(thd, (Item_field *) item); case INT_RESULT: return new Item_int_buff((Item_field *) item); case REAL_RESULT: @@ -51,12 +51,17 @@ Item_buff::~Item_buff() {} ** Return true if values have changed */ +Item_str_buff::Item_str_buff(THD *thd, Item *arg) + :item(arg), value(min(arg->max_length, thd->variables.max_sort_length)) +{} + bool Item_str_buff::cmp(void) { String *res; bool tmp; res=item->val_str(&tmp_value); + res->length(min(res->length(), value.alloced_length())); if (null_value != item->null_value) { if ((null_value= item->null_value)) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3f25d473792..b5b37efaf07 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -17,8 +17,6 @@ /* This file defines all compare functions */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -1111,12 +1109,14 @@ void Item_func_between::print(String *str) void Item_func_ifnull::fix_length_and_dec() { + agg_result_type(&hybrid_type, args, 2); maybe_null=args[1]->maybe_null; decimals= max(args[0]->decimals, args[1]->decimals); - max_length= (max(args[0]->max_length - args[0]->decimals, - args[1]->max_length - args[1]->decimals) + - decimals); - agg_result_type(&hybrid_type, args, 2); + max_length= (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) ? + (max(args[0]->max_length - args[0]->decimals, + args[1]->max_length - args[1]->decimals) + decimals) : + max(args[0]->max_length, args[1]->max_length); + switch (hybrid_type) { case STRING_RESULT: agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV); @@ -1227,16 +1227,7 @@ Item_func_if::fix_length_and_dec() { maybe_null=args[1]->maybe_null || args[2]->maybe_null; decimals= max(args[1]->decimals, args[2]->decimals); - if (decimals == NOT_FIXED_DEC) - { - max_length= max(args[1]->max_length, args[2]->max_length); - } - else - { - max_length= (max(args[1]->max_length - args[1]->decimals, - args[2]->max_length - args[2]->decimals) + - decimals); - } + enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); bool null1=args[1]->const_item() && args[1]->null_value; @@ -1265,6 +1256,11 @@ Item_func_if::fix_length_and_dec() collation.set(&my_charset_bin); // Number } } + max_length= + (cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ? + (max(args[1]->max_length - args[1]->decimals, + args[2]->max_length - args[2]->decimals) + decimals) : + max(args[1]->max_length, args[2]->max_length); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 4a12c6529e6..c926a7589ac 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -17,8 +17,6 @@ /* This file defines all numerical functions */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -213,15 +211,16 @@ void Item_func::set_arguments(List &list) { allowed_arg_cols= 1; arg_count=list.elements; - if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) + args= tmp_arg; // If 2 arguments + if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) { - uint i=0; List_iterator_fast li(list); Item *item; + Item **save_args= args; while ((item=li++)) { - args[i++]= item; + *(save_args++)= item; with_sum_func|=item->with_sum_func; } } @@ -1877,7 +1876,8 @@ void Item_func_round::fix_length_and_dec() max_length= float_length(decimals); break; case INT_RESULT: - if (truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)) + if ((decimals_to_set==0) && + (truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS))) { /* Here we can keep INT_RESULT */ hybrid_type= INT_RESULT; @@ -1891,18 +1891,12 @@ void Item_func_round::fix_length_and_dec() hybrid_type= DECIMAL_RESULT; int decimals_delta= args[0]->decimals - decimals_to_set; int precision= args[0]->decimal_precision(); - if (decimals_delta > 0) - { - int length_increase= truncate ? 0:1; - precision-= decimals_delta - length_increase; - decimals= decimals_to_set; - } - else - /* Decimals to set is bigger that the original scale */ - /* we keep original decimals value */ - decimals= args[0]->decimals; + int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1; + + precision-= decimals_delta - length_increase; + decimals= decimals_to_set; max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + unsigned_flag); break; } default: @@ -2372,7 +2366,7 @@ longlong Item_func_field::val_int() return 0; for (uint i=1; i < arg_count ; i++) { - if (!args[i]->is_null() && val == args[i]->val_int()) + if (val == args[i]->val_int() && !args[i]->null_value) return (longlong) (i); } } @@ -2385,7 +2379,7 @@ longlong Item_func_field::val_int() for (uint i=1; i < arg_count; i++) { dec_arg= args[i]->val_decimal(&dec_arg_buf); - if (!args[i]->is_null() && !my_decimal_cmp(dec_arg, dec)) + if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec)) return (longlong) (i); } } @@ -2396,7 +2390,7 @@ longlong Item_func_field::val_int() return 0; for (uint i=1; i < arg_count ; i++) { - if (!args[i]->is_null() && val == args[i]->val_real()) + if (val == args[i]->val_real() && !args[i]->null_value) return (longlong) (i); } } @@ -4734,7 +4728,6 @@ Item_func_sp::func_name() const Field * Item_func_sp::sp_result_field(void) const { - Field *field; DBUG_ENTER("Item_func_sp::sp_result_field"); if (!m_sp) @@ -4799,6 +4792,7 @@ Item_func_sp::execute(Item **itp) THD *thd= current_thd; ulong old_client_capabilites; int res; + bool save_in_sub_stmt= thd->transaction.in_sub_stmt; #ifndef NO_EMBEDDED_ACCESS_CHECKS st_sp_security_context save_ctx; #endif @@ -4841,9 +4835,11 @@ Item_func_sp::execute(Item **itp) problem). */ tmp_disable_binlog(thd); /* don't binlog the substatements */ + thd->transaction.in_sub_stmt= TRUE; res= m_sp->execute_function(thd, args, arg_count, itp); + thd->transaction.in_sub_stmt= save_in_sub_stmt; reenable_binlog(thd); if (res && mysql_bin_log.is_open() && (m_sp->m_chistics->daccess == SP_CONTAINS_SQL || diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 3173994f90f..4a6ceb4bf7d 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -17,14 +17,11 @@ /* This file defines all spatial functions */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" - #ifdef HAVE_SPATIAL #include diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4808159fe98..539bed58e66 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -20,8 +20,6 @@ ** (This shouldn't be needed) */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -902,7 +900,7 @@ void Item_func_insert::fix_length_and_dec() } -String *Item_func_lcase::val_str(String *str) +String *Item_str_conv::val_str(String *str) { DBUG_ASSERT(fixed == 1); String *res; @@ -912,24 +910,25 @@ String *Item_func_lcase::val_str(String *str) return 0; /* purecov: inspected */ } null_value=0; - res=copy_if_not_alloced(str,res,res->length()); - res->casedn(); - return res; -} - - -String *Item_func_ucase::val_str(String *str) -{ - DBUG_ASSERT(fixed == 1); - String *res; - if (!(res=args[0]->val_str(str))) + if (multiply == 1) { - null_value=1; /* purecov: inspected */ - return 0; /* purecov: inspected */ + uint len; + res= copy_if_not_alloced(str,res,res->length()); + len= converter(collation.collation, (char*) res->ptr(), res->length(), + (char*) res->ptr(), res->length()); + DBUG_ASSERT(len <= res->length()); + res->length(len); + } + else + { + uint len= res->length() * multiply; + tmp_value.alloc(len); + tmp_value.set_charset(collation.collation); + len= converter(collation.collation, (char*) res->ptr(), res->length(), + (char*) tmp_value.ptr(), len); + tmp_value.length(len); + res= &tmp_value; } - null_value=0; - res=copy_if_not_alloced(str,res,res->length()); - res->caseup(); return res; } @@ -1669,22 +1668,36 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) String *Item_func_format::val_str(String *str) { - DBUG_ASSERT(fixed == 1); - double nr= args[0]->val_real(); - uint32 length,str_length,dec; + uint32 length, str_length ,dec; int diff; - if ((null_value=args[0]->null_value)) - return 0; /* purecov: inspected */ - nr= my_double_round(nr, decimals, FALSE); + DBUG_ASSERT(fixed == 1); dec= decimals ? decimals+1 : 0; - /* Here default_charset() is right as this is not an automatic conversion */ - str->set(nr,decimals, default_charset()); - if (isnan(nr)) - return str; - str_length=str->length(); - if (nr < 0) - str_length--; // Don't count sign + if (args[0]->result_type() == DECIMAL_RESULT || + args[0]->result_type() == INT_RESULT) + { + my_decimal dec_val, rnd_dec, *res; + res= args[0]->val_decimal(&dec_val); + my_decimal_round(E_DEC_FATAL_ERROR, res, decimals, false, &rnd_dec); + my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str); + str_length= str->length(); + if (rnd_dec.sign()) + str_length--; + } + else + { + double nr= args[0]->val_real(); + if ((null_value=args[0]->null_value)) + return 0; /* purecov: inspected */ + nr= my_double_round(nr, decimals, FALSE); + /* Here default_charset() is right as this is not an automatic conversion */ + str->set(nr,decimals, default_charset()); + if (isnan(nr)) + return str; + str_length=str->length(); + if (nr < 0) + str_length--; // Don't count sign + } /* We need this test to handle 'nan' values */ if (str_length >= dec+4) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 95979408ccb..6df90cebdff 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -133,13 +133,14 @@ public: class Item_str_conv :public Item_str_func { +protected: + uint multiply; + uint (*converter)(CHARSET_INFO *cs, char *src, uint srclen, + char *dst, uint dstlen); + String tmp_value; public: Item_str_conv(Item *item) :Item_str_func(item) {} - void fix_length_and_dec() - { - collation.set(args[0]->collation); - max_length = args[0]->max_length; - } + String *val_str(String *); }; @@ -147,16 +148,28 @@ class Item_func_lcase :public Item_str_conv { public: Item_func_lcase(Item *item) :Item_str_conv(item) {} - String *val_str(String *); const char *func_name() const { return "lcase"; } + void fix_length_and_dec() + { + collation.set(args[0]->collation); + multiply= collation.collation->casedn_multiply; + converter= collation.collation->cset->casedn; + max_length= args[0]->max_length * multiply; + } }; class Item_func_ucase :public Item_str_conv { public: Item_func_ucase(Item *item) :Item_str_conv(item) {} - String *val_str(String *); const char *func_name() const { return "ucase"; } + void fix_length_and_dec() + { + collation.set(args[0]->collation); + multiply= collation.collation->caseup_multiply; + converter= collation.collation->cset->caseup; + max_length= args[0]->max_length * multiply; + } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4f1e5b9a290..7a72b78b6f4 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -22,8 +22,6 @@ SUBSELECT TODO: (sql_select.h/sql_select.cc) */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -602,8 +600,8 @@ void Item_exists_subselect::fix_length_and_dec() decimals= 0; max_length= 1; max_columns= engine->cols(); - /* We need only 1 row to determinate existence */ - unit->global_parameters->select_limit= 1; + /* We need only 1 row to determine existence */ + unit->global_parameters->select_limit= new Item_int((int32) 1); } double Item_exists_subselect::val_real() @@ -772,9 +770,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, Comp_creator *func) { Item_subselect::trans_res result= RES_ERROR; - DBUG_ENTER("Item_in_subselect::single_value_transformer"); - SELECT_LEX *select_lex= join->select_lex; + DBUG_ENTER("Item_in_subselect::single_value_transformer"); /* Check that the right part of the subselect contains no more than one @@ -1646,7 +1643,7 @@ void subselect_uniquesubquery_engine::exclude() table_map subselect_engine::calc_const_tables(TABLE_LIST *table) { table_map map= 0; - for(; table; table= table->next_leaf) + for (; table; table= table->next_leaf) { TABLE *tbl= table->table; if (tbl && tbl->const_table) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index af3828ab2c6..f7a158ceb5a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -17,8 +17,6 @@ /* Sum functions (COUNT, MIN...) */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -242,8 +240,12 @@ Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) case REAL_RESULT: sum= item->sum; break; - case STRING_RESULT: // This can happen with ROLLUP. Note that the value is already - break; // copied at function call. + case STRING_RESULT: + /* + This can happen with ROLLUP. Note that the value is already + copied at function call. + */ + break; case ROW_RESULT: default: DBUG_ASSERT(0); @@ -2613,7 +2615,6 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1, Item_func_group_concat* grp_item= (Item_func_group_concat*)arg; TABLE *table= grp_item->table; Item **field_item, **end; - char *record= (char*) table->record[0] + table->s->null_bytes; for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field; field_item < end; @@ -2628,7 +2629,7 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1, if (field) { int res; - uint offset= (uint) (field->ptr - record); + uint offset= field->offset() - table->s->null_bytes; if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset))) return res; } @@ -2647,7 +2648,6 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) Item_func_group_concat* grp_item= (Item_func_group_concat*) arg; ORDER **order_item, **end; TABLE *table= grp_item->table; - char *record= (char*) table->record[0] + table->s->null_bytes; for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order; order_item < end; @@ -2664,7 +2664,7 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) if (field) { int res; - uint offset= (uint) (field->ptr - record); + uint offset= field->offset() - table->s->null_bytes; if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset))) return (*order_item)->asc ? res : -res; } @@ -2705,8 +2705,9 @@ int dump_leaf_key(byte* key, element_count count __attribute__((unused)), Item_func_group_concat *item) { TABLE *table= item->table; - char *record= (char*) table->record[0] + table->s->null_bytes; - String tmp((char *)table->record[1], table->s->reclength, default_charset_info), tmp2; + String tmp((char *)table->record[1], table->s->reclength, + default_charset_info); + String tmp2; String *result= &item->result; Item **arg= item->args, **arg_end= item->args + item->arg_count_field; @@ -2728,12 +2729,9 @@ int dump_leaf_key(byte* key, element_count count __attribute__((unused)), because it contains both order and arg list fields. */ Field *field= (*arg)->get_tmp_table_field(); - char *save_ptr= field->ptr; - uint offset= (uint) (save_ptr - record); + uint offset= field->offset() - table->s->null_bytes; DBUG_ASSERT(offset < table->s->reclength); - field->ptr= (char *) key + offset; - res= field->val_str(&tmp,&tmp2); - field->ptr= save_ptr; + res= field->val_str(&tmp, (char *) key + offset); } else res= (*arg)->val_str(&tmp); @@ -2915,12 +2913,8 @@ bool Item_func_group_concat::add() Item *show_item= args[i]; if (!show_item->const_item()) { - /* - Here we use real_item as we want the original field data that should - be written to table->record[0] - */ - Field *f= show_item->real_item()->get_tmp_table_field(); - if (f->is_null()) + Field *f= show_item->get_tmp_table_field(); + if (f->is_null_in_record((const uchar*) table->record[0])) return 0; // Skip row if it contains null } } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0f2c9a2907d..564c5e4b9cc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -17,8 +17,6 @@ /* This file defines all time functions */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -499,7 +497,6 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, timestamp_type type, String *str) { char intbuff[15]; - uint days_i; uint hours_i; uint weekday; ulong length; @@ -602,8 +599,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, break; case 'h': case 'I': - days_i= l_time->hour/24; - hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i; + hours_i= (l_time->hour%24 + 11)%12+1; length= int10_to_str(hours_i, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 2, '0'); break; @@ -624,8 +620,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, str->append_with_prefill(intbuff, length, 1, '0'); break; case 'l': - days_i= l_time->hour/24; - hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i; + hours_i= (l_time->hour%24 + 11)%12+1; length= int10_to_str(hours_i, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 1, '0'); break; @@ -3017,7 +3012,7 @@ String *Item_func_str_to_date::val_str(String *str) bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date) { - if (get_arg0_date(ltime,fuzzy_date)) + if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE)) return 1; uint month_idx= ltime->month-1; ltime->day= days_in_month[month_idx]; diff --git a/sql/item_uniq.cc b/sql/item_uniq.cc index f6cf83ebb10..79b2ca68f4f 100644 --- a/sql/item_uniq.cc +++ b/sql/item_uniq.cc @@ -16,10 +16,8 @@ /* Compability file */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation +#pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" diff --git a/sql/log.cc b/sql/log.cc index db592649d13..e69c0af15bd 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2370,7 +2370,7 @@ void sql_print_information(const char *format, ...) DBUG_VOID_RETURN; } -#ifdef HAVE_MMAP + /********* transaction coordinator log for 2pc - mmap() based solution *******/ /* @@ -2408,13 +2408,17 @@ void sql_print_information(const char *format, ...) new xid is added into it. Removing a xid from a page does not make it dirty - we don't sync removals to disk. */ + +ulong tc_log_page_waits= 0; + +#ifdef HAVE_MMAP + #define TC_LOG_HEADER_SIZE (sizeof(tc_log_magic)+1) static const char tc_log_magic[]={(char) 254, 0x23, 0x05, 0x74}; ulong opt_tc_log_size= TC_LOG_MIN_SIZE; -ulong tc_log_max_pages_used=0, tc_log_page_size=0, - tc_log_page_waits=0, tc_log_cur_pages_used=0; +ulong tc_log_max_pages_used=0, tc_log_page_size=0, tc_log_cur_pages_used=0; int TC_LOG_MMAP::open(const char *opt_name) { diff --git a/sql/log_event.cc b/sql/log_event.cc index d4225b39704..8f109f00c5f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -17,11 +17,10 @@ #ifndef MYSQL_CLIENT -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif + #include "mysql_priv.h" #include "slave.h" #include @@ -708,7 +707,7 @@ failed my_b_read")); Log_event *res= 0; #ifndef max_allowed_packet THD *thd=current_thd; - uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~0; + uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; #endif if (data_len > max_allowed_packet) diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 27fd33cffbe..b65e6aedaa2 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -290,6 +290,11 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d) inline void my_decimal_neg(decimal_t *arg) { + if (decimal_is_zero(arg)) + { + arg->sign= 0; + return; + } decimal_neg(arg); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7adb175ed1b..10ee5483d19 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -53,7 +53,7 @@ inline query_id_t next_query_id() { return query_id++; } /* useful constants */ extern const key_map key_map_empty; -extern const key_map key_map_full; +extern key_map key_map_full; /* Should be threaded as const */ extern const char *primary_key_name; #include "mysql_com.h" @@ -94,7 +94,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define MAX_FIELDS_BEFORE_HASH 32 #define USER_VARS_HASH_SIZE 16 #define STACK_MIN_SIZE 8192 // Abort if less stack during eval. -#define STACK_BUFF_ALLOC 64 // For stack overrun checks +#define STACK_BUFF_ALLOC 256 // For stack overrun checks #ifndef MYSQLD_NET_RETRY_COUNT #define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int. #endif @@ -336,6 +336,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define UNCACHEABLE_SIDEEFFECT 4 // forcing to save JOIN for explain #define UNCACHEABLE_EXPLAIN 8 +/* Don't evaluate subqueries in prepare even if they're not correlated */ +#define UNCACHEABLE_PREPARE 16 #ifdef EXTRA_DEBUG /* @@ -480,7 +482,7 @@ bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); -bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); bool mysql_multi_update_prepare(THD *thd); bool mysql_multi_delete_prepare(THD *thd); bool mysql_insert_select_prepare(THD *thd); @@ -575,6 +577,7 @@ void mysql_init_query(THD *thd, uchar *buf, uint length); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); +bool multi_delete_set_locks_and_link_aux_tables(LEX *lex); void init_max_user_conn(void); void init_update_queries(void); void free_max_user_conn(void); @@ -831,7 +834,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length); void mysql_stmt_free(THD *thd, char *packet); void mysql_stmt_reset(THD *thd, char *packet); void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); -void reset_stmt_for_execute(THD *thd, LEX *lex); +void reinit_stmt_before_use(THD *thd, LEX *lex); void init_stmt_after_parse(THD*, LEX*); /* sql_handler.cc */ @@ -1083,6 +1086,8 @@ extern ulong rpl_recovery_rank, thread_cache_size; extern ulong back_log; extern ulong specialflag, current_pid; extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter; +extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size; +extern ulong tc_log_page_waits; extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb; extern uint test_flags,select_errors,ha_open_options; extern uint protocol_version, mysqld_port, dropping_tables; @@ -1354,7 +1359,8 @@ inline void mark_as_null_row(TABLE *table) inline void table_case_convert(char * name, uint length) { if (lower_case_table_names) - my_casedn(files_charset_info, name, length); + files_charset_info->cset->casedn(files_charset_info, + name, length, name, length); } inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6625696c911..d2989bf9b1b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -381,6 +381,9 @@ char mysql_real_data_home[FN_REFLEN], *opt_init_file, *opt_tc_log_file, def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; +const key_map key_map_empty(0); +key_map key_map_full(0); // Will be initialized later + const char *opt_date_time_formats[3]; char *mysql_data_home= mysql_real_data_home; @@ -4668,9 +4671,11 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, "more than one storage engine, when binary log is disabled)", (gptr*) &opt_tc_log_file, (gptr*) &opt_tc_log_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef HAVE_MMAP {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.", (gptr*) &opt_tc_log_size, (gptr*) &opt_tc_log_size, 0, GET_ULONG, REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0L, 0, TC_LOG_PAGE_SIZE, 0}, +#endif {"log-update", OPT_UPDATE_LOG, "The update log is deprecated since version 5.0, is replaced by the binary \ log and this option justs turns on --log-bin instead.", @@ -5369,7 +5374,7 @@ The minimum value for this variable is 4096.", (gptr*) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG, 6, 2, 8, 0, 1, 0}, {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, - "Depricated option", + "Deprecated option", (gptr*) &global_system_variables.myisam_max_extra_sort_file_size, (gptr*) &max_system_variables.myisam_max_extra_sort_file_size, 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH, @@ -5812,9 +5817,11 @@ struct show_var_st status_vars[]= { #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, +#ifdef HAVE_MMAP {"Tc_log_max_pages_used", (char*) &tc_log_max_pages_used, SHOW_LONG}, {"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG}, {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG}, +#endif {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_created", (char*) &thread_created, SHOW_LONG_CONST}, @@ -5931,7 +5938,8 @@ static void mysql_init_variables(void) bzero((gptr) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list)); bzero((char *) &global_status_var, sizeof(global_status_var)); opt_large_pages= 0; - + key_map_full.set_all(); + /* Character sets */ system_charset_info= &my_charset_utf8_general_ci; files_charset_info= &my_charset_utf8_general_ci; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 95c9fc5035e..b3301d17655 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -36,8 +36,6 @@ QUICK_RANGEs are also created in this step. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -398,7 +396,7 @@ TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree); static int get_index_merge_params(PARAM *param, key_map& needed_reg, SEL_IMERGE *imerge, double *read_time, ha_rows* imerge_rows); -inline double get_index_only_read_time(const PARAM* param, ha_rows records, +static double get_index_only_read_time(const PARAM* param, ha_rows records, int keynr); #ifndef DBUG_OFF @@ -1117,6 +1115,7 @@ int QUICK_ROR_UNION_SELECT::init() val1 First merged select val2 Second merged select */ + int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, byte *val1, byte *val2) { QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg; @@ -1584,7 +1583,7 @@ static int fill_used_fields_bitmap(PARAM *param) KEY_PART_INFO *key_part= param->table->key_info[pk].key_part; KEY_PART_INFO *key_part_end= key_part + param->table->key_info[pk].key_parts; - for(;key_part != key_part_end; ++key_part) + for (;key_part != key_part_end; ++key_part) { bitmap_clear_bit(¶m->needed_fields, key_part->fieldnr); } @@ -1748,18 +1747,20 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, double best_read_time= read_time; if (cond) - tree= get_mm_tree(¶m,cond); - - if (tree && tree->type == SEL_TREE::IMPOSSIBLE) { - records=0L; /* Return -1 from this function. */ - read_time= (double) HA_POS_ERROR; - goto free_mem; + if ((tree= get_mm_tree(¶m,cond))) + { + if (tree->type == SEL_TREE::IMPOSSIBLE) + { + records=0L; /* Return -1 from this function. */ + read_time= (double) HA_POS_ERROR; + goto free_mem; + } + if (tree->type != SEL_TREE::KEY && + tree->type != SEL_TREE::KEY_SMALLER) + goto free_mem; + } } - else if (tree && tree->type != SEL_TREE::KEY && - tree->type != SEL_TREE::KEY_SMALLER) - goto free_mem; - /* Try to construct a QUICK_GROUP_MIN_MAX_SELECT. @@ -2250,7 +2251,7 @@ skip_to_ror_scan: clustered index) */ -inline double get_index_only_read_time(const PARAM* param, ha_rows records, +static double get_index_only_read_time(const PARAM* param, ha_rows records, int keynr) { double read_time; @@ -2296,6 +2297,7 @@ typedef struct st_ror_scan_info param Parameter from test_quick_select function idx Index of key in param->keys sel_arg Set of intervals for a given key + RETURN NULL - out of memory ROR scan structure containing a scan for {idx, sel_arg} @@ -2308,19 +2310,20 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) uchar *bitmap_buf; uint keynr; DBUG_ENTER("make_ror_scan"); + if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root, sizeof(ROR_SCAN_INFO)))) DBUG_RETURN(NULL); ror_scan->idx= idx; ror_scan->keynr= keynr= param->real_keynr[idx]; - ror_scan->key_rec_length= param->table->key_info[keynr].key_length + - param->table->file->ref_length; + ror_scan->key_rec_length= (param->table->key_info[keynr].key_length + + param->table->file->ref_length); ror_scan->sel_arg= sel_arg; ror_scan->records= param->table->quick_rows[keynr]; if (!(bitmap_buf= (uchar*)alloc_root(param->mem_root, - param->fields_bitmap_size))) + param->fields_bitmap_size))) DBUG_RETURN(NULL); if (bitmap_init(&ror_scan->covered_fields, bitmap_buf, @@ -2331,14 +2334,10 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part; KEY_PART_INFO *key_part_end= key_part + param->table->key_info[keynr].key_parts; - uint n_used_covered= 0; for (;key_part != key_part_end; ++key_part) { if (bitmap_is_set(¶m->needed_fields, key_part->fieldnr)) - { - n_used_covered++; bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr); - } } ror_scan->index_read_cost= get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr], @@ -2359,6 +2358,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) 0 a = b 1 a > b */ + static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b) { double val1= rows2double((*a)->records) * (*a)->key_rec_length; @@ -2382,6 +2382,7 @@ static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b) 0 a = b 1 a > b */ + static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b) { if ((*a)->used_fields_covered > (*b)->used_fields_covered) @@ -2399,6 +2400,7 @@ static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b) return 0; } + /* Auxiliary structure for incremental ROR-intersection creation */ typedef struct { @@ -2464,6 +2466,8 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) dst->index_scan_costs= src->index_scan_costs; dst->total_cost= src->total_cost; } + + /* Get selectivity of a ROR scan wrt ROR-intersection. @@ -2481,7 +2485,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) where k_ij may be the same as any k_pq (i.e. keys may have common parts). - A full row is retrieved iff entire cond holds. + A full row is retrieved if entire condition holds. The recursive procedure for finding P(cond) is as follows: @@ -2492,7 +2496,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) Here R may still contain condition(s) equivalent to k_11=c_11. Nevertheless, the following holds: - P(k_11=c_11 AND R) = P(k_11=c_11) * P(R|k_11=c_11). + P(k_11=c_11 AND R) = P(k_11=c_11) * P(R | k_11=c_11). Mark k_11 as fixed field (and satisfied condition) F, save P(F), save R to be cond and proceed to recursion step. @@ -2539,7 +2543,7 @@ void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) ( this is result of application of option b) of the recursion step for parts of a single key). Since it is reasonable to expect that most of the fields are not marked - as fixed, we calcualate (3) as + as fixed, we calculate (3) as n_{i1} n_{i_2} (3) = n_{max_key_part} / ( --------- * --------- * .... ) @@ -2573,33 +2577,32 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, max_range.key= (byte*) key_val; max_range.flag= HA_READ_AFTER_KEY; ha_rows prev_records= info->param->table->file->records; - int i; DBUG_ENTER("ror_intersect_selectivity"); - for(i= 0, sel_arg= scan->sel_arg; sel_arg; - i++, sel_arg= sel_arg->next_key_part) + + for (sel_arg= scan->sel_arg; sel_arg; + sel_arg= sel_arg->next_key_part) { DBUG_PRINT("info",("sel_arg step")); cur_covered= test(bitmap_is_set(&info->covered_fields, - (key_part + i)->fieldnr)); + key_part[sel_arg->part].fieldnr)); if (cur_covered != prev_covered) { /* create (part1val, ..., part{n-1}val) tuple. */ - { - if (!tuple_arg) - { - tuple_arg= scan->sel_arg; - tuple_arg->store_min(key_part->length, &key_ptr, 0); - } - while (tuple_arg->next_key_part != sel_arg) - { - tuple_arg= tuple_arg->next_key_part; - tuple_arg->store_min(key_part->length, &key_ptr, 0); - } - } ha_rows records; + if (!tuple_arg) + { + tuple_arg= scan->sel_arg; + /* Here we use the length of the first key part */ + tuple_arg->store_min(key_part->length, &key_ptr, 0); + } + while (tuple_arg->next_key_part != sel_arg) + { + tuple_arg= tuple_arg->next_key_part; + tuple_arg->store_min(key_part[tuple_arg->part].length, &key_ptr, 0); + } min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val); - records= info->param->table->file-> - records_in_range(scan->keynr, &min_range, &max_range); + records= (info->param->table->file-> + records_in_range(scan->keynr, &min_range, &max_range)); if (cur_covered) { /* uncovered -> covered */ @@ -2627,6 +2630,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, DBUG_RETURN(selectivity_mult); } + /* Check if adding a ROR scan to a ROR-intersection reduces its cost of ROR-intersection and if yes, update parameters of ROR-intersection, @@ -2664,7 +2668,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, */ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, - ROR_SCAN_INFO* ror_scan, bool is_cpk_scan) + ROR_SCAN_INFO* ror_scan, bool is_cpk_scan) { double selectivity_mult= 1.0; @@ -3220,11 +3224,11 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, quick_imerge->records= records; quick_imerge->read_time= read_cost; - for(TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end; - range_scan++) + for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end; + range_scan++) { if (!(quick= (QUICK_RANGE_SELECT*) - ((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))|| + ((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))|| quick_imerge->push_quick_back(quick)) { delete quick; @@ -3253,7 +3257,7 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param, "creating ROR-intersect", first_scan, last_scan);); alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc; - for(; first_scan != last_scan;++first_scan) + for (; first_scan != last_scan;++first_scan) { if (!(quick= get_quick_select(param, (*first_scan)->idx, (*first_scan)->sel_arg, alloc)) || @@ -3295,7 +3299,7 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param, */ if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->thd, param->table))) { - for(scan= first_ror; scan != last_ror; scan++) + for (scan= first_ror; scan != last_ror; scan++) { if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) || quick_roru->push_quick_back(quick)) @@ -4198,7 +4202,7 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) clone_flag=swap_clone_flag(clone_flag); } - // If one of the key is MAYBE_KEY then the found region may be smaller + /* If one of the key is MAYBE_KEY then the found region may be smaller */ if (key2->type == SEL_ARG::MAYBE_KEY) { if (key1->use_count > 1) @@ -5331,8 +5335,8 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts) KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part; KEY_PART_INFO *pk_part_end= pk_part + param->table->key_info[pk_number].key_parts; - for(;(key_part!=key_part_end) && (pk_part != pk_part_end); - ++key_part, ++pk_part) + for (;(key_part!=key_part_end) && (pk_part != pk_part_end); + ++key_part, ++pk_part) { if ((key_part->field != pk_part->field) || (key_part->length != pk_part->length)) @@ -7325,8 +7329,8 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item, DESCRIPTION Test conditions (NGA1, NGA2) from get_best_group_min_max(). Namely, - for each keypart field NGF_i not in GROUP-BY, check that there is a constant - equality predicate among conds with the form (NGF_i = const_ci) or + for each keypart field NGF_i not in GROUP-BY, check that there is a + constant equality predicate among conds with the form (NGF_i = const_ci) or (const_ci = NGF_i). Thus all the NGF_i attributes must fill the 'gap' between the last group-by attribute and the MIN/MAX attribute in the index (if present). If these @@ -7959,7 +7963,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat() max_used_key_length= real_prefix_len; if (min_max_ranges.elements > 0) { - QUICK_RANGE *cur_range= 0; + QUICK_RANGE *cur_range; if (have_min) { /* Check if the right-most range has a lower boundary. */ get_dynamic(&min_max_ranges, (gptr)&cur_range, @@ -7967,7 +7971,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat() if (!(cur_range->flag & NO_MIN_RANGE)) { max_used_key_length+= min_max_arg_len; - ++used_key_parts; + used_key_parts++; return; } } @@ -7977,7 +7981,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat() if (!(cur_range->flag & NO_MAX_RANGE)) { max_used_key_length+= min_max_arg_len; - ++used_key_parts; + used_key_parts++; return; } } @@ -7994,7 +7998,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat() usable key length. */ max_used_key_length+= min_max_arg_len; - ++used_key_parts; + used_key_parts++; } } @@ -8691,7 +8695,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg, char buff[1024]; String tmp(buff,sizeof(buff),&my_charset_bin); tmp.length(0); - for(;start != end; start++) + for (;start != end; start++) { if (tmp.length()) tmp.append(','); diff --git a/sql/opt_range.h b/sql/opt_range.h index b639ba6efa7..37d77033c8d 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -691,10 +691,14 @@ class SQL_SELECT :public Sql_alloc { ~SQL_SELECT(); void cleanup(); bool check_quick(THD *thd, bool force_quick_range, ha_rows limit) - { return test_quick_select(thd, key_map(~(uint)0), 0, limit, force_quick_range) < 0; } + { + key_map tmp; + tmp.set_all(); + return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0; + } inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; } int test_quick_select(THD *thd, key_map keys, table_map prev_tables, - ha_rows limit, bool force_quick_range=0); + ha_rows limit, bool force_quick_range); }; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index ddeeb44c82b..33c8eadc065 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -677,7 +677,8 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, If key_part2 may be NULL, then we want to find the first row that is not null */ - ref->key_buff[ref->key_length++]= 1; + ref->key_buff[ref->key_length]= 1; + ref->key_length+= part->store_length; *range_fl&= ~NO_MIN_RANGE; *range_fl|= NEAR_MIN; // > NULL } diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 6c3a81384a6..7cc563901d2 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -475,7 +475,7 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str) { char *write_pos= str->str; - for(; ptr < eol; ptr++, write_pos++) + for (; ptr < eol; ptr++, write_pos++) { char c= *ptr; if (c == '\\') @@ -635,7 +635,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, File_option *parameter= parameters+first_param, *parameters_end= parameters+required; int len= 0; - for(; parameter < parameters_end; parameter++) + for (; parameter < parameters_end; parameter++) { len= parameter->name.length; // check length diff --git a/sql/procedure.cc b/sql/procedure.cc index 38a043300bc..554e2cd0565 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -17,8 +17,6 @@ /* Procedures (functions with changes output of select) */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/protocol.cc b/sql/protocol.cc index 8019f3a123b..57922cdc677 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -19,8 +19,6 @@ The actual communction is handled by the net_xxx functions in net_serv.cc */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index c38a7cdecae..ed2d0b583d0 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -19,8 +19,6 @@ The actual communction is handled by the net_xxx functions in net_serv.cc */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/set_var.cc b/sql/set_var.cc index 0d743f99b73..b22c0924de1 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -48,8 +48,6 @@ new attribute. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -1618,7 +1616,10 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) if (var->value->result_type() == STRING_RESULT) { if (!(res= var->value->val_str(&str))) + { + strmake(buff, "NULL", 4); goto err; + } var->save_result.ulong_value= ((ulong) find_set(enum_names, res->c_ptr(), res->length(), diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 848cc422dc2..a020cadc084 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5356,3 +5356,5 @@ ER_EXEC_STMT_WITH_OPEN_CURSOR eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it." ER_STMT_HAS_NO_OPEN_CURSOR eng "The statement (%d) has no open cursor." +ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG + eng "Explicit or implicit commit is not allowed in stored function or trigger." diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 83811e76f9b..c8f0ed6ba2d 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -14,11 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation #endif - -#include "mysql_priv.h" #include "sp_cache.h" #include "sp_head.h" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fd5ad67e612..29898437cfb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -14,11 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation #endif - -#include "mysql_priv.h" #include "sp_head.h" #include "sp.h" #include "sp_pcontext.h" @@ -320,7 +319,7 @@ sp_head::sp_head() *sp_lex_sp_key(const byte *ptr, uint *plen, my_bool first); DBUG_ENTER("sp_head::sp_head"); - state= INITIALIZED; + state= INITIALIZED_FOR_SP; m_backpatch.empty(); m_lex.empty(); hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0); @@ -1165,7 +1164,7 @@ sp_head::restore_thd_mem_root(THD *thd) DBUG_ENTER("sp_head::restore_thd_mem_root"); Item *flist= free_list; // The old list set_item_arena(thd); // Get new free_list and mem_root - state= INITIALIZED; + state= INITIALIZED_FOR_SP; DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx", (ulong) &mem_root, (ulong) &thd->mem_root)); @@ -1443,7 +1442,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, implemented at the same time as ability not to store LEX for instruction if it is not really used. */ - reset_stmt_for_execute(thd, m_lex); + reinit_stmt_before_use(thd, m_lex); /* If requested check whenever we have access to tables in LEX's table list @@ -1991,33 +1990,33 @@ sp_instr_copen::execute(THD *thd, uint *nextp) else { sp_lex_keeper *lex_keeper= c->pre_open(thd); - - if (!lex_keeper) + if (!lex_keeper) // cursor already open or OOM { res= -1; *nextp= m_ip+1; } else - res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this); - - /* - Work around the fact that errors in selects are not returned properly - (but instead converted into a warning), so if a condition handler - caught, we have lost the result code. - */ - if (!res) { - uint dummy1, dummy2; + res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this); + /* + Work around the fact that errors in selects are not returned properly + (but instead converted into a warning), so if a condition handler + caught, we have lost the result code. + */ + if (!res) + { + uint dummy1, dummy2; - if (thd->spcont->found_handler(&dummy1, &dummy2)) - res= -1; + if (thd->spcont->found_handler(&dummy1, &dummy2)) + res= -1; + } + c->post_open(thd, res ? FALSE : TRUE); } - c->post_open(thd, (lex_keeper && !res ? TRUE : FALSE)); } - DBUG_RETURN(res); } + int sp_instr_copen::exec_core(THD *thd, uint *nextp) { diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index f95a43eb903..0de7fe212c0 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation #endif @@ -22,7 +23,6 @@ #undef SAFEMALLOC /* Problems with threads */ #endif -#include "mysql_priv.h" #include "sp_pcontext.h" #include "sp_head.h" diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index daca6b38b46..61cd7a9300f 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation #endif @@ -22,7 +23,6 @@ #undef SAFEMALLOC /* Problems with threads */ #endif -#include "mysql_priv.h" #include "mysql.h" #include "sp_head.h" #include "sp_rcontext.h" @@ -169,8 +169,22 @@ sp_rcontext::pop_cursors(uint count) * */ -// We have split this in two to make it easy for sp_instr_copen -// to reuse the sp_instr::exec_stmt() code. +/* + pre_open cursor + + SYNOPSIS + pre_open() + THD Thread handler + + NOTES + We have to open cursor in two steps to make it easy for sp_instr_copen + to reuse the sp_instr::exec_stmt() code. + If this function returns 0, post_open should not be called + + RETURN + 0 ERROR +*/ + sp_lex_keeper* sp_cursor::pre_open(THD *thd) { @@ -180,32 +194,31 @@ sp_cursor::pre_open(THD *thd) MYF(0)); return NULL; } - - bzero((char *)&m_mem_root, sizeof(m_mem_root)); init_alloc_root(&m_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); if ((m_prot= new Protocol_cursor(thd, &m_mem_root)) == NULL) return NULL; - m_oprot= thd->protocol; // Save the original protocol - thd->protocol= m_prot; - + /* Save for execution. Will be restored in post_open */ + m_oprot= thd->protocol; m_nseof= thd->net.no_send_eof; + + /* Change protocol for execution */ + thd->protocol= m_prot; thd->net.no_send_eof= TRUE; return m_lex_keeper; } + void sp_cursor::post_open(THD *thd, my_bool was_opened) { thd->net.no_send_eof= m_nseof; // Restore the originals thd->protocol= m_oprot; - if (was_opened) - { - m_isopen= was_opened; + if ((m_isopen= was_opened)) m_current_row= m_prot->data; - } } + int sp_cursor::close(THD *thd) { @@ -218,6 +231,7 @@ sp_cursor::close(THD *thd) return 0; } + void sp_cursor::destroy() { @@ -226,7 +240,6 @@ sp_cursor::destroy() delete m_prot; m_prot= NULL; free_root(&m_mem_root, MYF(0)); - bzero((char *)&m_mem_root, sizeof(m_mem_root)); } m_isopen= FALSE; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a11871c55dc..04da0dd5eb5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -188,7 +188,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ACL_HOST host; update_hostname(&host.host,get_field(&mem, table->field[0])); host.db= get_field(&mem, table->field[1]); - if (lower_case_table_names) + if (lower_case_table_names && host.db) { /* convert db to lower case and give a warning if the db wasn't @@ -210,7 +210,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) { sql_print_warning("'host' entry '%s|%s' " "ignored in --skip-name-resolve mode.", - host.host.hostname, host.db, host.host.hostname); + host.host.hostname, host.db?host.db:""); continue; } #ifndef TO_BE_REMOVED @@ -278,7 +278,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) { sql_print_warning("'user' entry '%s@%s' " "ignored in --skip-name-resolve mode.", - user.user, user.host.hostname, user.host.hostname); + user.user, user.host.hostname); continue; } @@ -414,7 +414,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) { sql_print_warning("'db' entry '%s %s@%s' " "ignored in --skip-name-resolve mode.", - db.db, db.user, db.host.hostname, db.host.hostname); + db.db, db.user, db.host.hostname); continue; } db.access=get_access(table,3); @@ -3232,7 +3232,7 @@ my_bool grant_init(THD *org_thd) sql_print_warning("'procs_priv' entry '%s %s@%s' " "ignored in --skip-name-resolve mode.", mem_check->tname, mem_check->user, - mem_check->host, mem_check->host); + mem_check->host); continue; } } @@ -5172,7 +5172,7 @@ bool mysql_revoke_all(THD *thd, List &list) grant_proc->db, grant_proc->tname, is_proc, - ~0, 1)) + ~(ulong)0, 1)) { revoked= 1; continue; @@ -5240,7 +5240,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, lex_user.host.length= strlen(grant_proc->host.hostname); if (!replace_routine_table(thd,grant_proc,tables[4].table,lex_user, grant_proc->db, grant_proc->tname, - is_proc, ~0, 1)) + is_proc, ~(ulong)0, 1)) { revoked= 1; continue; @@ -5406,10 +5406,12 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) uint counter; ACL_USER *acl_user; ulong want_access; - char buff[100]; TABLE *table= tables->table; + bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1); + char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%"; DBUG_ENTER("fill_schema_user_privileges"); + for (counter=0 ; counter < acl_users.elements ; counter++) { const char *user,*host, *is_grantable="YES"; @@ -5418,6 +5420,12 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) user= ""; if (!(host=acl_user->host.hostname)) host= ""; + + if (no_global_access && + (strcmp(thd->priv_user, user) || + my_strcasecmp(system_charset_info, curr_host, host))) + continue; + want_access= acl_user->access; if (!(want_access & GRANT_ACL)) is_grantable= "NO"; @@ -5453,6 +5461,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ulong want_access; char buff[100]; TABLE *table= tables->table; + bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1); + char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%"; DBUG_ENTER("fill_schema_schema_privileges"); for (counter=0 ; counter < acl_dbs.elements ; counter++) @@ -5465,6 +5475,11 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) if (!(host=acl_db->host.hostname)) host= ""; + if (no_global_access && + (strcmp(thd->priv_user, user) || + my_strcasecmp(system_charset_info, curr_host, host))) + continue; + want_access=acl_db->access; if (want_access) { @@ -5501,6 +5516,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) uint index; char buff[100]; TABLE *table= tables->table; + bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1); + char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%"; DBUG_ENTER("fill_schema_table_privileges"); for (index=0 ; index < column_priv_hash.records ; index++) @@ -5510,6 +5527,13 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) index); if (!(user=grant_table->user)) user= ""; + + if (no_global_access && + (strcmp(thd->priv_user, user) || + my_strcasecmp(system_charset_info, curr_host, + grant_table->host.hostname))) + continue; + ulong table_access= grant_table->privs; if (table_access) { @@ -5554,6 +5578,8 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) uint index; char buff[100]; TABLE *table= tables->table; + bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1); + char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%"; DBUG_ENTER("fill_schema_table_privileges"); for (index=0 ; index < column_priv_hash.records ; index++) @@ -5563,6 +5589,13 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) index); if (!(user=grant_table->user)) user= ""; + + if (no_global_access && + (strcmp(thd->priv_user, user) || + my_strcasecmp(system_charset_info, curr_host, + grant_table->host.hostname))) + continue; + ulong table_access= grant_table->cols; if (table_access != 0) { diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 55e6dfb3cbe..6706cee8e9d 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -23,8 +23,6 @@ ** - type set is out of optimization yet */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 036a838b6fc..a1887996d00 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -42,7 +42,6 @@ static my_bool open_new_frm(const char *path, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc, MEM_ROOT *mem_root); -static void relink_tables_for_multidelete(THD *thd); extern "C" byte *table_cache_key(const byte *record,uint *length, my_bool not_used __attribute__((unused))) @@ -446,8 +445,12 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived, if (thd->locked_tables || prelocked_mode) { /* - TODO: It is not 100% clear whenever we should do ha_commit_stmt() for - sub-statements. This issue needs additional investigation. + Let us commit transaction for statement. Since in 5.0 we only have + one statement transaction and don't allow several nested statement + transactions this call will do nothing if we are inside of stored + function or trigger (i.e. statement transaction is already active and + does not belong to statement for which we do close_thread_tables()). + TODO: This should be fixed in later releases. */ ha_commit_stmt(thd); @@ -753,7 +756,7 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) t_name= table->table_name; DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); - for(;;) + for (;;) { if (!(res= find_table_in_global_list(table_list, d_name, t_name)) || (!res->table || res->table != table->table) && @@ -2085,7 +2088,6 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) (thd->fill_derived_tables() && mysql_handle_derived(thd->lex, &mysql_derived_filling))) DBUG_RETURN(TRUE); /* purecov: inspected */ - relink_tables_for_multidelete(thd); DBUG_RETURN(0); } @@ -2096,7 +2098,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) SYNOPSIS open_normal_and_derived_tables thd - thread handler - tables - list of tables for open&locking + tables - list of tables for open RETURN FALSE - ok @@ -2115,36 +2117,10 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) if (open_tables(thd, &tables, &counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare)) DBUG_RETURN(TRUE); /* purecov: inspected */ - relink_tables_for_multidelete(thd); // Not really needed, but DBUG_RETURN(0); } -/* - Let us propagate pointers to open tables from global table list - to table lists for multi-delete -*/ - -static void relink_tables_for_multidelete(THD *thd) -{ - if (thd->lex->all_selects_list->next_select_in_list()) - { - for (SELECT_LEX *sl= thd->lex->all_selects_list; - sl; - sl= sl->next_select_in_list()) - { - for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; - cursor; - cursor=cursor->next_local) - { - if (cursor->correspondent_table) - cursor->table= cursor->correspondent_table->table; - } - } - } -} - - /* Mark all real tables in the list as free for reuse. diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 958268fc314..bc1484b4fb0 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -81,7 +81,7 @@ public: if (sizeof(buffer) >= 8) return uint8korr(buffer); DBUG_ASSERT(sizeof(buffer) >= 4); - uint4korr(buffer); + return (ulonglong) uint4korr(buffer); } }; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 862cf940173..165ce61d5d1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -22,8 +22,6 @@ ** *****************************************************************************/ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -716,8 +714,10 @@ int THD::send_explain_fields(select_result *result) CHARSET_INFO *cs= system_charset_info; field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG)); field_list.push_back(new Item_empty_string("select_type", 19, cs)); - field_list.push_back(new Item_empty_string("table", NAME_LEN, cs)); - field_list.push_back(new Item_empty_string("type", 10, cs)); + field_list.push_back(item= new Item_empty_string("table", NAME_LEN, cs)); + item->maybe_null= 1; + field_list.push_back(item= new Item_empty_string("type", 10, cs)); + item->maybe_null= 1; field_list.push_back(item=new Item_empty_string("possible_keys", NAME_LEN*MAX_KEY, cs)); item->maybe_null=1; @@ -729,7 +729,9 @@ int THD::send_explain_fields(select_result *result) field_list.push_back(item=new Item_empty_string("ref", NAME_LEN*MAX_REF_PARTS, cs)); item->maybe_null=1; - field_list.push_back(new Item_return_int("rows", 10, MYSQL_TYPE_LONGLONG)); + field_list.push_back(item= new Item_return_int("rows", 10, + MYSQL_TYPE_LONGLONG)); + item->maybe_null= 1; field_list.push_back(new Item_empty_string("Extra", 255, cs)); return (result->send_fields(field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7c8ead7558e..d2095503fe5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -45,10 +45,6 @@ extern const char **errmesg; #define TC_LOG_PAGE_SIZE 8192 #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE) -extern ulong opt_tc_log_size; -extern ulong tc_log_max_pages_used; -extern ulong tc_log_page_size; -extern ulong tc_log_page_waits; #define TC_HEURISTIC_RECOVER_COMMIT 1 #define TC_HEURISTIC_RECOVER_ROLLBACK 2 @@ -665,8 +661,8 @@ public: #endif enum enum_state { - INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, CONVENTIONAL_EXECUTION= 2, - ERROR= -1 + INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2, + CONVENTIONAL_EXECUTION= 3, EXECUTED= 4, ERROR= -1 }; enum_state state; @@ -695,6 +691,7 @@ public: virtual Type type() const; virtual ~Item_arena() {}; + inline bool is_stmt_prepare() const { return state == INITIALIZED; } inline bool is_stmt_prepare_or_first_sp_execute() const { return (int)state < (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } @@ -1066,6 +1063,8 @@ public: THD_TRANS all; // Trans since BEGIN WORK THD_TRANS stmt; // Trans for current statement bool on; // see ha_enable_transaction() + /* TRUE if we are inside of trigger or stored function. */ + bool in_sub_stmt; XID xid; // transaction identifier enum xa_states xa_state; // used by external XA only /* @@ -1855,7 +1854,8 @@ class multi_delete :public select_result_interceptor ha_rows deleted, found; uint num_of_tables; int error; - bool do_delete, transactional_tables, normal_tables; + bool do_delete, transactional_tables, normal_tables, delete_while_scanning; + public: multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); ~multi_delete(); @@ -1863,7 +1863,7 @@ public: bool send_data(List &items); bool initialize_tables (JOIN *join); void send_error(uint errcode,const char *err); - int do_deletes (bool from_send_error); + int do_deletes(); bool send_eof(); }; diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc index eda7f0f6bbb..f21a109e95d 100644 --- a/sql/sql_crypt.cc +++ b/sql/sql_crypt.cc @@ -23,8 +23,6 @@ needs something like 'ssh'. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index d4a3b6c684e..d782744162d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -410,7 +410,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, num_of_tables(num_of_tables_arg), error(0), do_delete(0), transactional_tables(0), normal_tables(0) { - tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); + tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables); } @@ -440,6 +440,7 @@ multi_delete::initialize_tables(JOIN *join) tables_to_delete_from|= walk->table->map; walk= delete_tables; + delete_while_scanning= 1; for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; tab < end; tab++) @@ -459,10 +460,25 @@ multi_delete::initialize_tables(JOIN *join) else normal_tables= 1; } + else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) && + walk == delete_tables) + { + /* + We are not deleting from the table we are scanning. In this + case send_data() shouldn't delete any rows a we may touch + the rows in the deleted table many times + */ + delete_while_scanning= 0; + } } walk= delete_tables; tempfiles_ptr= tempfiles; - for (walk= walk->next_local ;walk ;walk= walk->next_local) + if (delete_while_scanning) + { + table_being_deleted= delete_tables; + walk= walk->next_local; + } + for (;walk ;walk= walk->next_local) { TABLE *table=walk->table; *tempfiles_ptr++= new Unique (refpos_order_cmp, @@ -481,12 +497,12 @@ multi_delete::~multi_delete() table_being_deleted; table_being_deleted= table_being_deleted->next_local) { - TABLE *t=table_being_deleted->table; - free_io_cache(t); // Alloced by unique - t->no_keyread=0; + TABLE *table= table_being_deleted->table; + free_io_cache(table); // Alloced by unique + table->no_keyread=0; } - for (uint counter= 0; counter < num_of_tables-1; counter++) + for (uint counter= 0; counter < num_of_tables; counter++) { if (tempfiles[counter]) delete tempfiles[counter]; @@ -496,14 +512,15 @@ multi_delete::~multi_delete() bool multi_delete::send_data(List &values) { - int secure_counter= -1; + int secure_counter= delete_while_scanning ? -1 : 0; + TABLE_LIST *del_table; DBUG_ENTER("multi_delete::send_data"); - for (table_being_deleted= delete_tables; - table_being_deleted; - table_being_deleted= table_being_deleted->next_local, secure_counter++) + for (del_table= delete_tables; + del_table; + del_table= del_table->next_local, secure_counter++) { - TABLE *table=table_being_deleted->table; + TABLE *table= del_table->table; /* Check if we are using outer join and we didn't find the row */ if (table->status & (STATUS_NULL_ROW | STATUS_DELETED)) @@ -514,7 +531,8 @@ bool multi_delete::send_data(List &values) if (secure_counter < 0) { - /* If this is the table we are scanning */ + /* We are scanning the current table */ + DBUG_ASSERT(del_table == table_being_deleted); if (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) @@ -528,8 +546,7 @@ bool multi_delete::send_data(List &values) TRG_ACTION_AFTER, FALSE)) DBUG_RETURN(1); } - else if (!table_being_deleted->next_local || - table_being_deleted->table->file->has_transactions()) + else { table->file->print_error(error,MYF(0)); DBUG_RETURN(1); @@ -540,7 +557,7 @@ bool multi_delete::send_data(List &values) error=tempfiles[secure_counter]->unique_add((char*) table->file->ref); if (error) { - error=-1; + error= 1; // Fatal error DBUG_RETURN(1); } } @@ -563,22 +580,24 @@ void multi_delete::send_error(uint errcode,const char *err) /* Something already deleted so we have to invalidate cache */ query_cache_invalidate3(thd, delete_tables, 1); - /* Below can happen when thread is killed early ... */ - if (!table_being_deleted) - table_being_deleted=delete_tables; - /* If rows from the first table only has been deleted and it is transactional, just do rollback. The same if all tables are transactional, regardless of where we are. In all other cases do attempt deletes ... */ - if ((table_being_deleted->table->file->has_transactions() && - table_being_deleted == delete_tables) || !normal_tables) + if ((table_being_deleted == delete_tables && + table_being_deleted->table->file->has_transactions()) || + !normal_tables) ha_rollback_stmt(thd); else if (do_delete) { - VOID(do_deletes(1)); + /* + We have to execute the recorded do_deletes() and write info into the + error log + */ + error= 1; + send_eof(); } DBUG_VOID_RETURN; } @@ -591,27 +610,20 @@ void multi_delete::send_error(uint errcode,const char *err) 1 error */ -int multi_delete::do_deletes(bool from_send_error) +int multi_delete::do_deletes() { int local_error= 0, counter= 0; DBUG_ENTER("do_deletes"); + DBUG_ASSERT(do_delete); - if (from_send_error) - { - /* Found out table number for 'table_being_deleted*/ - for (TABLE_LIST *aux= delete_tables; - aux != table_being_deleted; - aux= aux->next_local) - counter++; - } - else - table_being_deleted = delete_tables; - - do_delete= 0; + do_delete= 0; // Mark called if (!found) DBUG_RETURN(0); - for (table_being_deleted= table_being_deleted->next_local; - table_being_deleted; + + table_being_deleted= (delete_while_scanning ? delete_tables->next_local : + delete_tables); + + for (; table_being_deleted; table_being_deleted= table_being_deleted->next_local, counter++) { TABLE *table = table_being_deleted->table; @@ -673,7 +685,7 @@ bool multi_delete::send_eof() thd->proc_info="deleting from reference tables"; /* Does deletes for the last n - 1 tables, returns 0 if ok */ - int local_error= do_deletes(0); // returns 0 if success + int local_error= do_deletes(); // returns 0 if success /* reset used flags */ thd->proc_info="end"; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 2ae293c1bff..e1d701936cf 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -217,6 +217,8 @@ exit: queries defined. After temporary table is filled, if this is not EXPLAIN, then the entire unit / node is deleted. unit is deleted if UNION is used for derived table and node is deleted is it is a simple SELECT. + If you use this function, make sure it's not called at prepare. + Due to evaluation of LIMIT clause it can not be used at prepared stage. RETURN 0 ok @@ -245,11 +247,7 @@ int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) } else { - unit->offset_limit_cnt= first_select->offset_limit; - unit->select_limit_cnt= first_select->select_limit+ - first_select->offset_limit; - if (unit->select_limit_cnt < first_select->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; + unit->set_limit(first_select); if (unit->select_limit_cnt == HA_POS_ERROR) first_select->options&= ~OPTION_FOUND_ROWS; diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 3bda16202b9..8a12339ccee 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -225,20 +225,22 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show) MYSQL_ERROR *err; SELECT_LEX *sel= &thd->lex->select_lex; - ha_rows offset= sel->offset_limit, limit= sel->select_limit; + SELECT_LEX_UNIT *unit= &thd->lex->unit; + ha_rows idx= 0; Protocol *protocol=thd->protocol; - + + unit->set_limit(sel); + List_iterator_fast it(thd->warn_list); while ((err= it++)) { /* Skip levels that the user is not interested in */ if (!(levels_to_show & ((ulong) 1 << err->level))) continue; - if (offset) - { - offset--; + if (++idx <= unit->offset_limit_cnt) continue; - } + if (idx > unit->select_limit_cnt) + break; protocol->prepare_for_resend(); protocol->store(warning_level_names[err->level], warning_level_length[err->level], system_charset_info); @@ -246,8 +248,6 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show) protocol->store(err->msg, strlen(err->msg), system_charset_info); if (protocol->write()) DBUG_RETURN(TRUE); - if (!--limit) - break; } send_eof(thd); DBUG_RETURN(FALSE); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 1aa034ce61c..9356ee04c45 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -321,8 +321,8 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables) key_expr ha_rkey_mode cond - select_limit - offset_limit + select_limit_cnt + offset_limit_cnt RETURN FALSE ok @@ -333,7 +333,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, char *keyname, List *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, - ha_rows select_limit,ha_rows offset_limit) + ha_rows select_limit_cnt, ha_rows offset_limit_cnt) { TABLE_LIST *hash_tables; TABLE *table; @@ -413,8 +413,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1))) goto err0; - table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it - if (keyname) { if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0) @@ -422,14 +420,11 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); goto err0; } - table->file->ha_index_or_rnd_end(); - table->file->ha_index_init(keyno); } if (insert_fields(thd, tables, tables->db, tables->alias, &it, 0, 0)) goto err0; - select_limit+=offset_limit; protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); HANDLER_TABLES_HACK(thd); @@ -447,12 +442,25 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, table->file->init_table_handle_for_HANDLER(); - for (num_rows=0; num_rows < select_limit; ) + for (num_rows=0; num_rows < select_limit_cnt; ) { switch (mode) { + case RNEXT: + if (table->file->inited != handler::NONE) + { + error=keyname ? + table->file->index_next(table->record[0]) : + table->file->rnd_next(table->record[0]); + break; + } + /* else fall through */ case RFIRST: if (keyname) + { + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); error= table->file->index_first(table->record[0]); + } else { table->file->ha_index_or_rnd_end(); @@ -461,19 +469,20 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } mode=RNEXT; break; - case RLAST: - DBUG_ASSERT(keyname != 0); - error= table->file->index_last(table->record[0]); - mode=RPREV; - break; - case RNEXT: - error= (keyname ? - table->file->index_next(table->record[0]) : - table->file->rnd_next(table->record[0])); - break; case RPREV: DBUG_ASSERT(keyname != 0); - error= table->file->index_prev(table->record[0]); + if (table->file->inited != handler::NONE) + { + error=table->file->index_prev(table->record[0]); + break; + } + /* else fall through */ + case RLAST: + DBUG_ASSERT(keyname != 0); + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); + error= table->file->index_last(table->record[0]); + mode=RPREV; break; case RNEXT_SAME: /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */ @@ -509,6 +518,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len)))) goto err; + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); key_copy(key, table->record[0], table->key_info + keyno, key_len); error= table->file->index_read(table->record[0], key,key_len,ha_rkey_mode); @@ -535,7 +546,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } if (cond && !cond->val_int()) continue; - if (num_rows >= offset_limit) + if (num_rows >= offset_limit_cnt) { Item *item; protocol->prepare_for_resend(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8e4456a42a6..5ca75554c6f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -128,7 +128,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, /* it is join view => we need to find table for update */ List_iterator_fast it(fields); Item *item; - TABLE_LIST *tbl= 0; + TABLE_LIST *tbl= 0; // reset for call to check_single_table() table_map map= 0; while ((item= it++)) @@ -916,6 +916,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (res == VIEW_CHECK_ERROR) goto before_trg_err; + if (thd->clear_next_insert_id) + { + /* Reset auto-increment cacheing if we do an update */ + thd->clear_next_insert_id= 0; + thd->next_insert_id= 0; + } if ((error=table->file->update_row(table->record[1],table->record[0]))) { if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) @@ -949,6 +955,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE)) goto before_trg_err; + if (thd->clear_next_insert_id) + { + /* Reset auto-increment cacheing if we do an update */ + thd->clear_next_insert_id= 0; + thd->next_insert_id= 0; + } if ((error=table->file->update_row(table->record[1], table->record[0]))) goto err; @@ -1012,6 +1024,7 @@ ok_or_after_trg_err: err: info->last_errno= error; + thd->lex->current_select->no_error= 0; // Give error table->file->print_error(error,MYF(0)); before_trg_err: @@ -1081,7 +1094,7 @@ public: volatile bool status,dead; COPY_INFO info; I_List rows; - uint group_count; + ulong group_count; TABLE_LIST table_list; // Argument delayed_insert() @@ -1753,7 +1766,7 @@ static void free_delayed_insert_blobs(register TABLE *table) bool delayed_insert::handle_inserts(void) { int error; - uint max_rows; + ulong max_rows; bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(); delayed_row *row; DBUG_ENTER("handle_inserts"); @@ -1772,11 +1785,11 @@ bool delayed_insert::handle_inserts(void) } thd.proc_info="insert"; - max_rows=delayed_insert_limit; + max_rows= delayed_insert_limit; if (thd.killed || table->s->version != refresh_version) { thd.killed= THD::KILL_CONNECTION; - max_rows= ~(uint)0; // Do as much as possible + max_rows= ~(ulong)0; // Do as much as possible } /* diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 574c9966c63..1270aab18ae 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1138,8 +1138,9 @@ void st_select_lex::init_select() order_list.elements= 0; order_list.first= 0; order_list.next= (byte**) &order_list.first; - select_limit= HA_POS_ERROR; - offset_limit= 0; + /* Set limit and offset to default values */ + select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ + offset_limit= 0; /* denotes the default offset = 0 */ with_sum_func= 0; } @@ -1363,7 +1364,7 @@ ulong st_select_lex_node::get_table_join_options() */ bool st_select_lex::test_limit() { - if (select_limit != HA_POS_ERROR) + if (select_limit != 0) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "LIMIT & IN/ALL/ANY/SOME subquery"); @@ -1551,24 +1552,20 @@ void st_select_lex::print_limit(THD *thd, String *str) item->substype() == Item_subselect::IN_SUBS || item->substype() == Item_subselect::ALL_SUBS)) { - DBUG_ASSERT(!item->fixed || select_limit == 1L && offset_limit == 0L); + DBUG_ASSERT(!item->fixed || + select_limit->val_int() == LL(1) && offset_limit == 0); return; } if (explicit_limit) { str->append(" limit ", 7); - char buff[20]; - // latin1 is good enough for numbers - String st(buff, sizeof(buff), &my_charset_latin1); - st.set((ulonglong)select_limit, &my_charset_latin1); - str->append(st); if (offset_limit) { + offset_limit->print(str); str->append(','); - st.set((ulonglong)select_limit, &my_charset_latin1); - str->append(st); } + select_limit->print(str); } } @@ -1619,7 +1616,7 @@ bool st_lex::can_be_merged() select_lex.with_sum_func == 0 && select_lex.table_list.elements >= 1 && !(select_lex.options & SELECT_DISTINCT) && - select_lex.select_limit == HA_POS_ERROR); + select_lex.select_limit == 0); } @@ -1756,11 +1753,16 @@ bool st_lex::need_correct_ident() values - SELECT_LEX with initial values for counters */ -void st_select_lex_unit::set_limit(SELECT_LEX *values) +void st_select_lex_unit::set_limit(SELECT_LEX *sl) { - offset_limit_cnt= values->offset_limit; - select_limit_cnt= values->select_limit+values->offset_limit; - if (select_limit_cnt < values->select_limit) + ulonglong select_limit_val; + + DBUG_ASSERT(! thd->current_arena->is_stmt_prepare()); + select_limit_val= sl->select_limit ? sl->select_limit->val_uint() : + HA_POS_ERROR; + offset_limit_cnt= sl->offset_limit ? sl->offset_limit->val_uint() : ULL(0); + select_limit_cnt= select_limit_val + offset_limit_cnt; + if (select_limit_cnt < select_limit_val) select_limit_cnt= HA_POS_ERROR; // no limit } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e297d303f3d..8af416f0ce8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -303,6 +303,7 @@ public: UNCACHEABLE_RAND UNCACHEABLE_SIDEEFFECT UNCACHEABLE_EXPLAIN + UNCACHEABLE_PREPARE */ uint8 uncacheable; enum sub_select_type linkage; @@ -488,7 +489,7 @@ public: List expr_list; List when_list; /* WHEN clause (expression) */ SQL_LIST *gorder_list; - ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ + Item *select_limit, *offset_limit; /* LIMIT clause parameters */ // Arrays of pointers to top elements of all_fields list Item **ref_pointer_array; @@ -750,7 +751,12 @@ typedef struct st_lex uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; uint slave_thd_opt, start_transaction_opt; - uint table_count; /* used when usual update transformed in multiupdate */ + /* + In LEX representing update which were transformed to multi-update + stores total number of tables. For LEX representing multi-delete + holds number of tables from which we will delete records. + */ + uint table_count; uint8 describe; uint8 derived_tables; uint8 create_view_algorithm; diff --git a/sql/sql_list.cc b/sql/sql_list.cc index 485c569f49c..d57a7dfe4e3 100644 --- a/sql/sql_list.cc +++ b/sql/sql_list.cc @@ -15,8 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/sql_map.cc b/sql/sql_map.cc index 556d37a405c..9346f3df305 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -15,8 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc index b349eda0e2e..831b15cf7ef 100644 --- a/sql/sql_olap.cc +++ b/sql/sql_olap.cc @@ -28,8 +28,6 @@ #ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1 -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a9e68de3705..be7ba7d571d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -125,6 +125,11 @@ static bool end_active_trans(THD *thd) { int error=0; DBUG_ENTER("end_active_trans"); + if (unlikely(thd->transaction.in_sub_stmt)) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + DBUG_RETURN(1); + } if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)) { @@ -143,6 +148,15 @@ static bool end_active_trans(THD *thd) static bool begin_trans(THD *thd) { int error=0; + /* + QQ: May be it is better to simply prohibit COMMIT and ROLLBACK in + stored routines as SQL2003 suggests? + */ + if (unlikely(thd->transaction.in_sub_stmt)) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + return 1; + } if (thd->locked_tables) { thd->lock=thd->locked_tables; @@ -1337,6 +1351,15 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) int res= 0; DBUG_ENTER("end_trans"); + /* + QQ: May be it is better to simply prohibit COMMIT and ROLLBACK in + stored routines as SQL2003 suggests? + */ + if (unlikely(thd->transaction.in_sub_stmt)) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + DBUG_RETURN(1); + } switch (completion) { case COMMIT: /* @@ -2351,7 +2374,8 @@ mysql_execute_command(THD *thd) { SELECT_LEX *param= lex->unit.global_parameters; if (!param->explicit_limit) - param->select_limit= thd->variables.select_limit; + param->select_limit= + new Item_int((ulonglong)thd->variables.select_limit); } select_result *result=lex->result; @@ -2747,7 +2771,7 @@ mysql_execute_command(THD *thd) TABLE_LIST *select_tables= lex->query_tables; if ((res= create_table_precheck(thd, select_tables, create_table))) - goto unsent_create_error; + goto end_with_restore_list; #ifndef HAVE_READLINK lex->create_info.data_file_name=lex->create_info.index_file_name=0; @@ -2757,7 +2781,7 @@ mysql_execute_command(THD *thd) create_table->table_name) || append_file_to_dir(thd, &lex->create_info.index_file_name, create_table->table_name)) - goto unsent_create_error; + goto end_with_restore_list; #endif /* If we are using SET CHARSET without DEFAULT, add an implicit @@ -2787,8 +2811,8 @@ mysql_execute_command(THD *thd) */ if (wait_if_global_read_lock(thd, 0, 1)) { - res= -1; - goto unsent_create_error; + res= 1; + goto end_with_restore_list; } if (select_lex->item_list.elements) // With select { @@ -2807,7 +2831,8 @@ mysql_execute_command(THD *thd) unique_table(create_table, select_tables)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->table_name); - goto unsent_create_error1; + res= 1; + goto end_with_restart_wait; } /* If we create merge table, we have to test tables in merge, too */ if (lex->create_info.used_fields & HA_CREATE_USED_UNION) @@ -2820,7 +2845,8 @@ mysql_execute_command(THD *thd) if (unique_table(tab, select_tables)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), tab->table_name); - goto unsent_create_error1; + res= 1; + goto end_with_restart_wait; } } } @@ -2863,15 +2889,8 @@ mysql_execute_command(THD *thd) if (!res) send_ok(thd); } - /* - Release the protection against the global read lock and wake - everyone, who might want to set a global read lock. - */ - start_waiting_global_read_lock(thd); - lex->link_first_table_back(create_table, link_to_local); - break; -unsent_create_error1: +end_with_restart_wait: /* Release the protection against the global read lock and wake everyone, who might want to set a global read lock. @@ -2879,9 +2898,9 @@ unsent_create_error1: start_waiting_global_read_lock(thd); /* put tables back for PS rexecuting */ -unsent_create_error: +end_with_restore_list: lex->link_first_table_back(create_table, link_to_local); - goto error; + break; } case SQLCOM_CREATE_INDEX: DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -3146,13 +3165,15 @@ unsent_create_error: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (update_precheck(thd, all_tables)) break; + DBUG_ASSERT(select_lex->offset_limit == 0); + unit->set_limit(select_lex); res= (result= mysql_update(thd, all_tables, select_lex->item_list, lex->value_list, select_lex->where, select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, - select_lex->select_limit, + unit->select_limit_cnt, lex->duplicates, lex->ignore)); /* mysql_update return 2 if we need to switch to multi-update */ if (result != 2) @@ -3258,9 +3279,11 @@ unsent_create_error: DBUG_ASSERT(first_table == all_tables && first_table != 0); if ((res= delete_precheck(thd, all_tables))) break; + DBUG_ASSERT(select_lex->offset_limit == 0); + unit->set_limit(select_lex); res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, - select_lex->select_limit, select_lex->options); + unit->select_limit_cnt, select_lex->options); break; } case SQLCOM_DELETE_MULTI: @@ -3268,10 +3291,9 @@ unsent_create_error: DBUG_ASSERT(first_table == all_tables && first_table != 0); TABLE_LIST *aux_tables= (TABLE_LIST *)thd->lex->auxilliary_table_list.first; - uint table_count; multi_delete *result; - if ((res= multi_delete_precheck(thd, all_tables, &table_count))) + if ((res= multi_delete_precheck(thd, all_tables))) break; /* condition will be TRUE on SP re-excuting */ @@ -3288,7 +3310,7 @@ unsent_create_error: goto error; if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, - table_count))) + lex->table_count))) { res= mysql_select(thd, &select_lex->ref_pointer_array, select_lex->get_table_list(), @@ -3847,9 +3869,10 @@ unsent_create_error: */ if (check_db_used(thd, all_tables)) goto error; + unit->set_limit(select_lex); res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str, lex->insert_list, lex->ha_rkey_mode, select_lex->where, - select_lex->select_limit, select_lex->offset_limit); + unit->select_limit_cnt, unit->offset_limit_cnt); break; case SQLCOM_BEGIN: @@ -4537,7 +4560,8 @@ unsent_create_error: send_ok(thd); break; } - if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE) + if (thd->transaction.xa_state == XA_IDLE && + thd->lex->xa_opt == XA_ONE_PHASE) { int r; if ((r= ha_commit(thd))) @@ -4545,8 +4569,8 @@ unsent_create_error: else send_ok(thd); } - else - if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE) + else if (thd->transaction.xa_state == XA_PREPARED && + thd->lex->xa_opt == XA_NONE) { if (wait_if_global_read_lock(thd, 0, 0)) { @@ -5032,7 +5056,7 @@ bool check_stack_overrun(THD *thd, long margin, { long stack_used; if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= - thread_stack - margin) + (long) (thread_stack - margin)) { sprintf(errbuff[0],ER(ER_STACK_OVERRUN),stack_used,thread_stack); my_message(ER_STACK_OVERRUN,errbuff[0],MYF(0)); @@ -5130,7 +5154,6 @@ mysql_init_select(LEX *lex) { SELECT_LEX *select_lex= lex->current_select; select_lex->init_select(); - select_lex->select_limit= HA_POS_ERROR; lex->orig_sql_command= SQLCOM_END; lex->wild= 0; if (select_lex == &lex->select_lex) @@ -5145,25 +5168,28 @@ bool mysql_new_select(LEX *lex, bool move_down) { SELECT_LEX *select_lex; + THD *thd= lex->thd; DBUG_ENTER("mysql_new_select"); - if (!(select_lex= new(lex->thd->mem_root) SELECT_LEX())) + if (!(select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); - select_lex->select_number= ++lex->thd->select_number; + select_lex->select_number= ++thd->select_number; select_lex->init_query(); select_lex->init_select(); select_lex->parent_lex= lex; + if (thd->current_arena->is_stmt_prepare()) + select_lex->uncacheable|= UNCACHEABLE_PREPARE; if (move_down) { SELECT_LEX_UNIT *unit; lex->subqueries= TRUE; /* first select_lex of subselect or derived table */ - if (!(unit= new(lex->thd->mem_root) SELECT_LEX_UNIT())) + if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT())) DBUG_RETURN(1); unit->init_query(); unit->init_select(); - unit->thd= lex->thd; + unit->thd= thd; unit->include_down(lex->current_select); unit->link_next= 0; unit->link_prev= 0; @@ -5187,14 +5213,14 @@ mysql_new_select(LEX *lex, bool move_down) as far as we included SELECT_LEX for UNION unit should have fake SELECT_LEX for UNION processing */ - if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX())) + if (!(fake= unit->fake_select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); fake->include_standalone(unit, (SELECT_LEX_NODE**)&unit->fake_select_lex); fake->select_number= INT_MAX; fake->make_empty_select(); fake->linkage= GLOBAL_OPTIONS_TYPE; - fake->select_limit= HA_POS_ERROR; + fake->select_limit= 0; } } @@ -5242,8 +5268,8 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select_lex.select_limit= lex->unit.select_limit_cnt= - HA_POS_ERROR; + lex->select_lex.select_limit= 0; + lex->unit.select_limit_cnt= HA_POS_ERROR; lex->select_lex.table_list.save_and_clear(&lex->auxilliary_table_list); lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ; lex->query_tables= 0; @@ -6757,8 +6783,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (select_lex->order_list.elements) msg= "ORDER BY"; - else if (select_lex->select_limit && select_lex->select_limit != - HA_POS_ERROR) + else if (select_lex->select_limit) msg= "LIMIT"; if (msg) { @@ -6775,23 +6800,19 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) multi_delete_precheck() thd Thread handler tables Global/local table list - table_count Pointer to table counter RETURN VALUE FALSE OK TRUE error */ -bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) { SELECT_LEX *select_lex= &thd->lex->select_lex; TABLE_LIST *aux_tables= (TABLE_LIST *)thd->lex->auxilliary_table_list.first; - TABLE_LIST *target_tbl; DBUG_ENTER("multi_delete_precheck"); - *table_count= 0; - /* sql_yacc guarantees that tables and aux_tables are not zero */ DBUG_ASSERT(aux_tables != 0); if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) || @@ -6804,9 +6825,35 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); } - for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local) + DBUG_RETURN(FALSE); +} + + +/* + Link tables in auxilary table list of multi-delete with corresponding + elements in main table list, and set proper locks for them. + + SYNOPSIS + multi_delete_set_locks_and_link_aux_tables() + lex - pointer to LEX representing multi-delete + + RETURN VALUE + FALSE - success + TRUE - error +*/ + +bool multi_delete_set_locks_and_link_aux_tables(LEX *lex) +{ + TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first; + TABLE_LIST *target_tbl; + DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables"); + + lex->table_count= 0; + + for (target_tbl= (TABLE_LIST *)lex->auxilliary_table_list.first; + target_tbl; target_tbl= target_tbl->next_local) { - (*table_count)++; + lex->table_count++; /* All tables in aux_tables must be found in FROM PART */ TABLE_LIST *walk; for (walk= tables; walk; walk= walk->next_local) @@ -6824,14 +6871,6 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) } walk->lock_type= target_tbl->lock_type; target_tbl->correspondent_table= walk; // Remember corresponding table - - /* in case of subselects, we need to set lock_type in - * corresponding table in list of all tables */ - if (walk->correspondent_table) - { - target_tbl->correspondent_table= walk->correspondent_table; - walk->correspondent_table->lock_type= walk->lock_type; - } } DBUG_RETURN(FALSE); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1521b206e0d..37efd1d62b9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -15,18 +15,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /********************************************************************** -This file contains the implementation of prepare and executes. +This file contains the implementation of prepare and executes. Prepare: - - Server gets the query from client with command 'COM_PREPARE'; + - Server gets the query from client with command 'COM_PREPARE'; in the following format: [COM_PREPARE:1] [query] - - Parse the query and recognize any parameter markers '?' and + - Parse the query and recognize any parameter markers '?' and store its information list in lex->param_list - - Allocate a new statement for this prepare; and keep this in + - Allocate a new statement for this prepare; and keep this in 'thd->prepared_statements' pool. - - Without executing the query, return back to client the total + - Without executing the query, return back to client the total number of parameters along with result-set metadata information (if any) in the following format: [STMT_ID:4] @@ -34,10 +34,10 @@ Prepare: [Param_count:2] [Columns meta info] (if Column_count > 0) [Params meta info] (if Param_count > 0 ) (TODO : 4.1.1) - + Prepare-execute: - - Server gets the command 'COM_EXECUTE' to execute the + - Server gets the command 'COM_EXECUTE' to execute the previously prepared query. If there is any param markers; then client will send the data in the following format: [COM_EXECUTE:1] @@ -45,12 +45,12 @@ Prepare-execute: [NULL_BITS:(param_count+7)/8)] [TYPES_SUPPLIED_BY_CLIENT(0/1):1] [[length]data] - [[length]data] .. [[length]data]. - (Note: Except for string/binary types; all other types will not be + [[length]data] .. [[length]data]. + (Note: Except for string/binary types; all other types will not be supplied with length field) - - Replace the param items with this new data. If it is a first execute + - Replace the param items with this new data. If it is a first execute or types altered by client; then setup the conversion routines. - - Execute the query without re-parsing and send back the results + - Execute the query without re-parsing and send back the results to client Long data handling: @@ -61,8 +61,8 @@ Long data handling: - data from the packet is appended to long data value buffer for this placeholder. - It's up to the client to check for read data ended. The server doesn't - care; and also server doesn't notify to the client that it got the - data or not; if there is any error; then during execute; the error + care; and also server doesn't notify to the client that it got the + data or not; if there is any error; then during execute; the error will be returned ***********************************************************************/ @@ -97,7 +97,7 @@ public: #else bool (*set_params_data)(Prepared_statement *st, String *expanded_query); #endif - bool (*set_params_from_vars)(Prepared_statement *stmt, + bool (*set_params_from_vars)(Prepared_statement *stmt, List& varnames, String *expanded_query); public: @@ -167,7 +167,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns) Send types and names of placeholders to the client XXX: fix this nasty upcast from List to List */ - DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) || + DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) || (stmt->param_count && stmt->thd->protocol_simple.send_fields((List *) &stmt->lex->param_list, @@ -220,7 +220,7 @@ static ulong get_param_length(uchar **packet, ulong len) } if (len < 5) return 0; - (*packet)+=9; // Must be 254 when here + (*packet)+=9; // Must be 254 when here /* In our client-server protocol all numbers bigger than 2^24 stored as 8 bytes with uint8korr. Here we always know that @@ -242,7 +242,7 @@ static ulong get_param_length(uchar **packet, ulong len) pos input data buffer len length of data in the buffer - All these functions read the data from pos, convert it to requested type + All these functions read the data from pos, convert it to requested type and assign to param; pos is advanced to predefined length. Make a note that the NULL handling is examined at first execution @@ -260,7 +260,7 @@ static void set_param_tiny(Item_param *param, uchar **pos, ulong len) return; #endif int8 value= (int8) **pos; - param->set_int(param->unsigned_flag ? (longlong) ((uint8) value) : + param->set_int(param->unsigned_flag ? (longlong) ((uint8) value) : (longlong) value, 4); *pos+= 1; } @@ -480,7 +480,7 @@ static void set_param_str(Item_param *param, uchar **pos, ulong len) } -#undef get_param_length +#undef get_param_length static void setup_one_conversion_function(THD *thd, Item_param *param, uchar param_type) @@ -583,12 +583,12 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, #ifndef EMBEDDED_LIBRARY /* - Update the parameter markers by reading data from client packet + Update the parameter markers by reading data from client packet and if binary/update log is set, generate the valid query. */ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, - uchar *read_pos, uchar *data_end, + uchar *read_pos, uchar *data_end, String *query) { THD *thd= stmt->thd; @@ -596,14 +596,14 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, Item_param **end= begin + stmt->param_count; uint32 length= 0; - String str; + String str; const String *res; - DBUG_ENTER("insert_params_withlog"); + DBUG_ENTER("insert_params_withlog"); if (query->copy(stmt->query, stmt->query_length, default_charset_info)) DBUG_RETURN(1); - + for (Item_param **it= begin; it < end; ++it) { Item_param *param= *it; @@ -624,7 +624,7 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, if (query->replace(param->pos_in_query+length, 1, *res)) DBUG_RETURN(1); - + length+= res->length()-1; } DBUG_RETURN(0); @@ -632,13 +632,13 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, static bool insert_params(Prepared_statement *stmt, uchar *null_array, - uchar *read_pos, uchar *data_end, + uchar *read_pos, uchar *data_end, String *expanded_query) { Item_param **begin= stmt->param_array; Item_param **end= begin + stmt->param_count; - DBUG_ENTER("insert_params"); + DBUG_ENTER("insert_params"); for (Item_param **it= begin; it < end; ++it) { @@ -672,7 +672,7 @@ static bool setup_conversion_functions(Prepared_statement *stmt, if (*read_pos++) //types supplied / first execute { /* - First execute or types altered by the client, setup the + First execute or types altered by the client, setup the conversion routines for all parameters (one time) */ Item_param **it= stmt->param_array; @@ -720,8 +720,8 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) uchar *buff= (uchar*) client_param->buffer; param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, - client_param->length ? - *client_param->length : + client_param->length ? + *client_param->length : client_param->buffer_length); } } @@ -747,7 +747,7 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) if (query->copy(stmt->query, stmt->query_length, default_charset_info)) DBUG_RETURN(1); - + for (; it < end; ++it, ++client_param) { Item_param *param= *it; @@ -759,10 +759,10 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) else { uchar *buff= (uchar*)client_param->buffer; - param->unsigned_flag= client_param->is_unsigned; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, - client_param->length ? - *client_param->length : + client_param->length ? + *client_param->length : client_param->buffer_length); } } @@ -881,21 +881,21 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, } /* - Validate INSERT statement: + Validate INSERT statement: SYNOPSIS mysql_test_insert() - stmt prepared statemen handler - tables global/local table list + stmt prepared statemen handler + tables global/local table list RETURN VALUE - FALSE OK - TRUE error + FALSE success + TRUE error, error message is set in THD */ static bool mysql_test_insert(Prepared_statement *stmt, TABLE_LIST *table_list, - List &fields, + List &fields, List &values_list, List &update_fields, List &update_values, @@ -905,11 +905,10 @@ static bool mysql_test_insert(Prepared_statement *stmt, LEX *lex= stmt->lex; List_iterator_fast its(values_list); List_item *values; - bool res; DBUG_ENTER("mysql_test_insert"); - if ((res= insert_precheck(thd, table_list))) - DBUG_RETURN(res); + if (insert_precheck(thd, table_list)) + goto error; /* open temporary memory pool for temporary data allocated by derived @@ -920,10 +919,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, TL_WRITE_DELAYED as having two such locks can cause table corruption. */ if (open_normal_and_derived_tables(thd, table_list)) - { - DBUG_RETURN(TRUE); - } - + goto error; if ((values= its++)) { @@ -937,17 +933,14 @@ static bool mysql_test_insert(Prepared_statement *stmt, table_list->table->insert_values=(byte *)1; } - if ((res= mysql_prepare_insert(thd, table_list, table_list->table, - fields, values, update_fields, - update_values, duplic, - &unused_conds, FALSE))) + if (mysql_prepare_insert(thd, table_list, table_list->table, fields, + values, update_fields, update_values, duplic, + &unused_conds, FALSE)) goto error; value_count= values->elements; its.rewind(); - res= TRUE; - if (table_list->lock_type == TL_WRITE_DELAYED && !(table_list->table->file->table_flags() & HA_CAN_INSERT_DELAYED)) { @@ -965,15 +958,14 @@ static bool mysql_test_insert(Prepared_statement *stmt, goto error; } if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) - goto error; + goto error; } } + DBUG_RETURN(FALSE); - res= FALSE; error: - lex->unit.cleanup(); /* insert_values is cleared in open_table */ - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -982,14 +974,15 @@ error: SYNOPSIS mysql_test_update() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries RETURN VALUE 0 success + 1 error, error message is set in THD 2 convert to multi_update - 1 error */ + static int mysql_test_update(Prepared_statement *stmt, TABLE_LIST *table_list) { @@ -998,74 +991,65 @@ static int mysql_test_update(Prepared_statement *stmt, uint table_count= 0; SELECT_LEX *select= &stmt->lex->select_lex; #ifndef NO_EMBEDDED_ACCESS_CHECKS - uint want_privilege; + uint want_privilege; #endif DBUG_ENTER("mysql_test_update"); if (update_precheck(thd, table_list)) - DBUG_RETURN(1); + goto error; - if (!open_tables(thd, &table_list, &table_count)) + if (open_tables(thd, &table_list, &table_count)) + goto error; + + if (table_list->multitable_view) { - if (table_list->multitable_view) - { - DBUG_ASSERT(table_list->view != 0); - DBUG_PRINT("info", ("Switch to multi-update")); - /* pass counter value */ - thd->lex->table_count= table_count; - /* convert to multiupdate */ - return 2; - } + DBUG_ASSERT(table_list->view != 0); + DBUG_PRINT("info", ("Switch to multi-update")); + /* pass counter value */ + thd->lex->table_count= table_count; + /* convert to multiupdate */ + DBUG_RETURN(2); + } - /* - thd->fill_derived_tables() is false here for sure (because it is - preparation of PS, so we even do not check it - */ - if (lock_tables(thd, table_list, table_count) || - mysql_handle_derived(thd->lex, &mysql_derived_prepare)) - DBUG_RETURN(1); + /* + thd->fill_derived_tables() is false here for sure (because it is + preparation of PS, so we even do not check it). + */ + if (lock_tables(thd, table_list, table_count) || + mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + goto error; #ifndef NO_EMBEDDED_ACCESS_CHECKS /* TABLE_LIST contain right privilages request */ want_privilege= table_list->grant.want_privilege; #endif - if (!(res= mysql_prepare_update(thd, table_list, - &select->where, - select->order_list.elements, - (ORDER *) select->order_list.first))) - { + if (mysql_prepare_update(thd, table_list, &select->where, + select->order_list.elements, + (ORDER *) select->order_list.first)) + goto error; + #ifndef NO_EMBEDDED_ACCESS_CHECKS - table_list->grant.want_privilege= - table_list->table->grant.want_privilege= - want_privilege; + table_list->grant.want_privilege= want_privilege; + table_list->table->grant.want_privilege= want_privilege; #endif - thd->lex->select_lex.no_wrap_view_item= 1; - if (setup_fields(thd, 0, table_list, select->item_list, 1, 0, 0)) - { - res= 1; - thd->lex->select_lex.no_wrap_view_item= 0; - } - else - { - thd->lex->select_lex.no_wrap_view_item= 0; + thd->lex->select_lex.no_wrap_view_item= 1; + res= setup_fields(thd, 0, table_list, select->item_list, 1, 0, 0); + thd->lex->select_lex.no_wrap_view_item= 0; + if (res) + goto error; #ifndef NO_EMBEDDED_ACCESS_CHECKS - /* Check values */ - table_list->grant.want_privilege= - table_list->table->grant.want_privilege= - (SELECT_ACL & ~table_list->table->grant.privilege); + /* Check values */ + table_list->grant.want_privilege= + table_list->table->grant.want_privilege= + (SELECT_ACL & ~table_list->table->grant.privilege); #endif - if (setup_fields(thd, 0, table_list, - stmt->lex->value_list, 0, 0, 0)) - res= 1; - } - } - stmt->lex->unit.cleanup(); - } - else - res= 1; - /* TODO: here we should send types of placeholders to the client. */ - DBUG_RETURN(res); + if (setup_fields(thd, 0, table_list, stmt->lex->value_list, 0, 0, 0)) + goto error; + /* TODO: here we should send types of placeholders to the client. */ + DBUG_RETURN(0); +error: + DBUG_RETURN(1); } @@ -1074,38 +1058,34 @@ static int mysql_test_update(Prepared_statement *stmt, SYNOPSIS mysql_test_delete() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries RETURN VALUE FALSE success - TRUE error + TRUE error, error message is set in THD */ -static int mysql_test_delete(Prepared_statement *stmt, - TABLE_LIST *table_list) + +static bool mysql_test_delete(Prepared_statement *stmt, + TABLE_LIST *table_list) { THD *thd= stmt->thd; LEX *lex= stmt->lex; DBUG_ENTER("mysql_test_delete"); - if (delete_precheck(thd, table_list)) - DBUG_RETURN(TRUE); + if (delete_precheck(thd, table_list) || + open_and_lock_tables(thd, table_list)) + goto error; - if (!open_and_lock_tables(thd, table_list)) + if (!table_list->table) { - bool res; - if (!table_list->table) - { - my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), - table_list->view_db.str, table_list->view_name.str); - DBUG_RETURN(-1); - } - - res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where); - lex->unit.cleanup(); - DBUG_RETURN(res); + my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), + table_list->view_db.str, table_list->view_name.str); + goto error; } - /* TODO: here we should send types of placeholders to the client. */ + + DBUG_RETURN(mysql_prepare_delete(thd, table_list, &lex->select_lex.where)); +error: DBUG_RETURN(TRUE); } @@ -1113,25 +1093,24 @@ static int mysql_test_delete(Prepared_statement *stmt, /* Validate SELECT statement. In case of success, if this query is not EXPLAIN, send column list info - back to client. + back to client. SYNOPSIS mysql_test_select() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries RETURN VALUE FALSE success TRUE error, sent to client */ -static int mysql_test_select(Prepared_statement *stmt, - TABLE_LIST *tables, bool text_protocol) +static bool mysql_test_select(Prepared_statement *stmt, + TABLE_LIST *tables, bool text_protocol) { THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; - bool result; DBUG_ENTER("mysql_test_select"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1139,19 +1118,20 @@ static int mysql_test_select(Prepared_statement *stmt, if (tables) { if (check_table_access(thd, privilege, tables,0)) - DBUG_RETURN(TRUE); + goto error; } else if (check_access(thd, privilege, any_db,0,0,0)) - DBUG_RETURN(TRUE); + goto error; #endif - result= TRUE; if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) - goto err; + { + my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send)); + goto error; + } if (open_and_lock_tables(thd, tables)) - goto err; - + goto error; thd->used_tables= 0; // Updated by setup_fields @@ -1161,15 +1141,13 @@ static int mysql_test_select(Prepared_statement *stmt, usual, and we pass 0 as setup_tables_done_option */ if (unit->prepare(thd, 0, 0, "")) - { - goto err_prep; - } + goto error; if (!text_protocol) { if (lex->describe) { if (send_prep_stmt(stmt, 0) || thd->protocol->flush()) - goto err_prep; + goto error; } else { @@ -1179,7 +1157,7 @@ static int mysql_test_select(Prepared_statement *stmt, /* Change columns if a procedure like analyse() */ if (unit->last_procedure && unit->last_procedure->change_columns(fields)) - goto err_prep; + goto error; /* We can use lex->result as it should've been @@ -1188,15 +1166,12 @@ static int mysql_test_select(Prepared_statement *stmt, if (send_prep_stmt(stmt, lex->result->field_count(fields)) || lex->result->send_fields(fields, Protocol::SEND_EOF) || thd->protocol->flush()) - goto err_prep; + goto error; } } - result= FALSE; // ok - -err_prep: - unit->cleanup(); -err: - DBUG_RETURN(result); + DBUG_RETURN(FALSE); +error: + DBUG_RETURN(TRUE); } @@ -1205,32 +1180,28 @@ err: SYNOPSIS mysql_test_do_fields() - stmt prepared statemen handler - tables list of tables queries - values list of expressions + stmt prepared statemen handler + tables list of tables queries + values list of expressions RETURN VALUE FALSE success - TRUE error, sent to client + TRUE error, error message is set in THD */ static bool mysql_test_do_fields(Prepared_statement *stmt, - TABLE_LIST *tables, - List *values) + TABLE_LIST *tables, + List *values) { - DBUG_ENTER("mysql_test_do_fields"); THD *thd= stmt->thd; - bool res; + + DBUG_ENTER("mysql_test_do_fields"); if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) DBUG_RETURN(TRUE); if (open_and_lock_tables(thd, tables)) - { DBUG_RETURN(TRUE); - } - res= setup_fields(thd, 0, 0, *values, 0, 0, 0); - stmt->lex->unit.cleanup(); - DBUG_RETURN(res); + DBUG_RETURN(setup_fields(thd, 0, 0, *values, 0, 0, 0)); } @@ -1239,14 +1210,15 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, SYNOPSIS mysql_test_set_fields() - stmt prepared statemen handler - tables list of tables queries - values list of expressions + stmt prepared statemen handler + tables list of tables queries + values list of expressions RETURN VALUE FALSE success TRUE error */ + static bool mysql_test_set_fields(Prepared_statement *stmt, TABLE_LIST *tables, List *var_list) @@ -1255,25 +1227,19 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, List_iterator_fast it(*var_list); THD *thd= stmt->thd; set_var_base *var; - bool res; - if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) - DBUG_RETURN(TRUE); - - if ((res= open_and_lock_tables(thd, tables))) + if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || + open_and_lock_tables(thd, tables)) goto error; + while ((var= it++)) { if (var->light_check(thd)) - { - stmt->lex->unit.cleanup(); - res= TRUE; goto error; - } } + DBUG_RETURN(FALSE); error: - stmt->lex->unit.cleanup(); - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -1294,7 +1260,7 @@ error: RETURN VALUE FALSE success - TRUE error + TRUE error, error message is set in THD */ static bool select_like_stmt_test(Prepared_statement *stmt, @@ -1304,24 +1270,16 @@ static bool select_like_stmt_test(Prepared_statement *stmt, DBUG_ENTER("select_like_stmt_test"); THD *thd= stmt->thd; LEX *lex= stmt->lex; - bool res= FALSE; - if (specific_prepare && (res= (*specific_prepare)(thd))) - goto end; + if (specific_prepare && (*specific_prepare)(thd)) + DBUG_RETURN(TRUE); thd->used_tables= 0; // Updated by setup_fields - // JOIN::prepare calls - if (lex->unit.prepare(thd, 0, setup_tables_done_option, "")) - { - res= TRUE; - } -end: - lex->unit.cleanup(); - DBUG_RETURN(res); + /* Calls JOIN::prepare */ + DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option, "")); } - /* Check internal SELECT of the prepared command (with opening and locking tables used). @@ -1365,29 +1323,30 @@ select_like_stmt_test_with_open_n_lock(Prepared_statement *stmt, SYNOPSIS mysql_test_create_table() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error, error message is set in THD */ -static int mysql_test_create_table(Prepared_statement *stmt) +static bool mysql_test_create_table(Prepared_statement *stmt) { DBUG_ENTER("mysql_test_create_table"); THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX *select_lex= &lex->select_lex; - int res= 0; + bool res= FALSE; /* Skip first table, which is the table we are creating */ bool link_to_local; TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local); TABLE_LIST *tables= lex->query_tables; - if (!(res= create_table_precheck(thd, tables, create_table)) && - select_lex->item_list.elements) + if (create_table_precheck(thd, tables, create_table)) + DBUG_RETURN(TRUE); + + if (select_lex->item_list.elements) { select_lex->resolve_mode= SELECT_LEX::SELECT_MODE; res= select_like_stmt_test_with_open_n_lock(stmt, tables, 0, 0); @@ -1405,8 +1364,8 @@ static int mysql_test_create_table(Prepared_statement *stmt) SYNOPSIS mysql_test_multiupdate() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries converted converted to multi-update from usual update RETURN VALUE @@ -1415,7 +1374,7 @@ static int mysql_test_create_table(Prepared_statement *stmt) */ static bool mysql_test_multiupdate(Prepared_statement *stmt, - TABLE_LIST *tables, + TABLE_LIST *tables, bool converted) { /* if we switched from normal update, rights are checked */ @@ -1432,37 +1391,38 @@ static bool mysql_test_multiupdate(Prepared_statement *stmt, SYNOPSIS mysql_test_multidelete() - stmt prepared statemen handler - tables list of tables queries + stmt prepared statemen handler + tables list of tables queries RETURN VALUE 0 success - 1 error, sent to client - -1 error, not sent to client + 1 error, error message in THD is set. */ -static int mysql_test_multidelete(Prepared_statement *stmt, - TABLE_LIST *tables) + +static bool mysql_test_multidelete(Prepared_statement *stmt, + TABLE_LIST *tables) { - int res; stmt->thd->lex->current_select= &stmt->thd->lex->select_lex; if (add_item_to_list(stmt->thd, new Item_null())) - return -1; + { + my_error(ER_OUTOFMEMORY, MYF(0), 0); + goto error; + } - uint fake_counter; - if ((res= multi_delete_precheck(stmt->thd, tables, &fake_counter))) - return res; - if ((res= select_like_stmt_test_with_open_n_lock(stmt, tables, - &mysql_multi_delete_prepare, - OPTION_SETUP_TABLES_DONE))) - return res; + if (multi_delete_precheck(stmt->thd, tables) || + select_like_stmt_test_with_open_n_lock(stmt, tables, + &mysql_multi_delete_prepare, + OPTION_SETUP_TABLES_DONE)) + goto error; if (!tables->table) { my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), - tables->view_db.str, tables->view_name.str); - return -1; + tables->view_db.str, tables->view_name.str); + goto error; } - return 0; - + return FALSE; +error: + return TRUE; } @@ -1498,8 +1458,8 @@ static bool mysql_insert_select_prepare_tester(THD *thd) SYNOPSIS mysql_test_insert_select() - stmt prepared statemen handler - tables list of tables of query + stmt prepared statemen handler + tables list of tables of query RETURN VALUE 0 success @@ -1508,7 +1468,7 @@ static bool mysql_insert_select_prepare_tester(THD *thd) */ static int mysql_test_insert_select(Prepared_statement *stmt, - TABLE_LIST *tables) + TABLE_LIST *tables) { int res; LEX *lex= stmt->lex; @@ -1520,8 +1480,8 @@ static int mysql_test_insert_select(Prepared_statement *stmt, tables->table->insert_values=(byte *)1; } - if ((res= insert_precheck(stmt->thd, tables))) - return res; + if (insert_precheck(stmt->thd, tables)) + return 1; /* store it, because mysql_insert_select_prepare_tester change it */ first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first; @@ -1552,12 +1512,12 @@ static int mysql_test_insert_select(Prepared_statement *stmt, by calling fix_fields. RETURN VALUE - 0 success - 1 error, sent to client + FALSE success, statement metadata is sent to client + TRUE error, error message is set (but not sent) */ -static int check_prepared_statement(Prepared_statement *stmt, - bool text_protocol) +static bool check_prepared_statement(Prepared_statement *stmt, + bool text_protocol) { THD *thd= stmt->thd; LEX *lex= stmt->lex; @@ -1576,14 +1536,14 @@ static int check_prepared_statement(Prepared_statement *stmt, case SQLCOM_REPLACE: case SQLCOM_INSERT: res= mysql_test_insert(stmt, tables, lex->field_list, - lex->many_values, - select_lex->item_list, lex->value_list, - lex->duplicates); + lex->many_values, + select_lex->item_list, lex->value_list, + lex->duplicates); break; case SQLCOM_UPDATE: res= mysql_test_update(stmt, tables); - /* mysql_test_update return 2 if we need to switch to multi-update */ + /* mysql_test_update returns 2 if we need to switch to multi-update */ if (res != 2) break; @@ -1599,12 +1559,12 @@ static int check_prepared_statement(Prepared_statement *stmt, if ((res= mysql_test_select(stmt, tables, text_protocol))) goto error; /* Statement and field info has already been sent */ - DBUG_RETURN(0); + DBUG_RETURN(FALSE); case SQLCOM_CREATE_TABLE: res= mysql_test_create_table(stmt); break; - + case SQLCOM_DO: res= mysql_test_do_fields(stmt, tables, lex->insert_list); break; @@ -1650,18 +1610,15 @@ static int check_prepared_statement(Prepared_statement *stmt, break; default: - /* - All other is not supported yet - */ - res= -1; + /* All other statements are not supported yet. */ my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0)); goto error; } if (res == 0) - DBUG_RETURN(text_protocol? 0 : (send_prep_stmt(stmt, 0) || - thd->protocol->flush())); + DBUG_RETURN(text_protocol? FALSE : (send_prep_stmt(stmt, 0) || + thd->protocol->flush())); error: - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } /* @@ -1699,33 +1656,44 @@ static bool init_param_array(Prepared_statement *stmt) return FALSE; } + +/* Cleanup PS after execute/prepare and restore THD state */ + +static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd) +{ + stmt->lex->unit.cleanup(); + cleanup_items(stmt->free_list); + thd->rollback_item_tree_changes(); + thd->cleanup_after_query(); +} + /* Given a query string with parameter markers, create a Prepared Statement from it and send PS info back to the client. - + SYNOPSIS mysql_stmt_prepare() - packet query to be prepared - packet_length query string length, including ignored trailing NULL or + packet query to be prepared + packet_length query string length, including ignored trailing NULL or quote char. name NULL or statement name. For unnamed statements binary PS - protocol is used, for named statements text protocol is + protocol is used, for named statements text protocol is used. RETURN FALSE OK, statement prepared successfully TRUE Error NOTES - This function parses the query and sends the total number of parameters - and resultset metadata information back to client (if any), without - executing the query i.e. without any log/disk writes. This allows the - queries to be re-executed without re-parsing during execute. + This function parses the query and sends the total number of parameters + and resultset metadata information back to client (if any), without + executing the query i.e. without any log/disk writes. This allows the + queries to be re-executed without re-parsing during execute. If parameter markers are found in the query, then store the information - using Item_param along with maintaining a list in lex->param_array, so - that a fast and direct retrieval can be made without going through all + using Item_param along with maintaining a list in lex->param_array, so + that a fast and direct retrieval can be made without going through all field items. - + */ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, @@ -1804,10 +1772,8 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, } lex_end(lex); close_thread_tables(thd); + cleanup_stmt_and_thd_after_use(stmt, thd); thd->restore_backup_statement(stmt, &thd->stmt_backup); - cleanup_items(stmt->free_list); - thd->rollback_item_tree_changes(); - thd->cleanup_after_query(); thd->current_arena= thd; if (error) @@ -1838,7 +1804,10 @@ void init_stmt_after_parse(THD *thd, LEX *lex) optimisation. */ for (; sl; sl= sl->next_select_in_list()) + { sl->prep_where= sl->where; + sl->uncacheable&= ~UNCACHEABLE_PREPARE; + } for (TABLE_LIST *table= lex->query_tables; table; table= table->next_global) table->prep_on_expr= table->on_expr; @@ -1847,10 +1816,10 @@ void init_stmt_after_parse(THD *thd, LEX *lex) /* Reinit prepared statement/stored procedure before execution */ -void reset_stmt_for_execute(THD *thd, LEX *lex) +void reinit_stmt_before_use(THD *thd, LEX *lex) { SELECT_LEX *sl= lex->all_selects_list; - DBUG_ENTER("reset_stmt_for_execute"); + DBUG_ENTER("reinit_stmt_before_use"); if (lex->empty_field_list_on_rset) { @@ -1894,8 +1863,8 @@ void reset_stmt_for_execute(THD *thd, LEX *lex) } /* - TODO: When the new table structure is ready, then have a status bit - to indicate the table is altered, and re-do the setup_* + TODO: When the new table structure is ready, then have a status bit + to indicate the table is altered, and re-do the setup_* and open the tables back. */ /* @@ -1904,8 +1873,8 @@ void reset_stmt_for_execute(THD *thd, LEX *lex) they have their own table list). */ for (TABLE_LIST *tables= lex->query_tables; - tables; - tables= tables->next_global) + tables; + tables= tables->next_global) { /* Reset old pointers to TABLEs: they are not valid since the tables @@ -1936,10 +1905,10 @@ void reset_stmt_for_execute(THD *thd, LEX *lex) /* Clears parameters from data left from previous execution or long data - + SYNOPSIS reset_stmt_params() - stmt prepared statement for which parameters should be reset + stmt prepared statement for which parameters should be reset */ static void reset_stmt_params(Prepared_statement *stmt) @@ -2036,8 +2005,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) } #else /* - In embedded library we re-install conversion routines each time - we set params, and also we don't need to parse packet. + In embedded library we re-install conversion routines each time + we set params, and also we don't need to parse packet. So we do it in one function. */ if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query)) @@ -2046,7 +2015,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) thd->stmt_backup.set_statement(thd); thd->set_statement(stmt); thd->current_arena= stmt; - reset_stmt_for_execute(thd, stmt->lex); + reinit_stmt_before_use(thd, stmt->lex); /* From now cursors assume that thd->mem_root is clean */ if (expanded_query.length() && alloc_query(thd, (char *)expanded_query.ptr(), @@ -2070,17 +2039,18 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) if (cursor && cursor->is_open()) { + /* + It's safer if we grab THD state after mysql_execute_command is + finished and not in Cursor::open(), because currently the call to + Cursor::open is buried deep in JOIN::exec of the top level join. + */ cursor->init_from_thd(thd); - cursor->state= stmt->state; } else { - thd->lex->unit.cleanup(); - cleanup_items(stmt->free_list); + close_thread_tables(thd); + cleanup_stmt_and_thd_after_use(stmt, thd); reset_stmt_params(stmt); - close_thread_tables(thd); /* to close derived tables */ - thd->rollback_item_tree_changes(); - thd->cleanup_after_query(); } thd->set_statement(&thd->stmt_backup); @@ -2158,7 +2128,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, { DBUG_ENTER("execute_stmt"); - reset_stmt_for_execute(thd, stmt->lex); + reinit_stmt_before_use(thd, stmt->lex); if (expanded_query->length() && alloc_query(thd, (char *)expanded_query->ptr(), @@ -2180,14 +2150,11 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); - thd->lex->unit.cleanup(); - thd->current_arena= thd; - cleanup_items(stmt->free_list); - thd->rollback_item_tree_changes(); - reset_stmt_params(stmt); close_thread_tables(thd); // to close derived tables + cleanup_stmt_and_thd_after_use(stmt, thd); + reset_stmt_params(stmt); thd->set_statement(&thd->stmt_backup); - thd->cleanup_after_query(); + thd->current_arena= thd; if (stmt->state == Item_arena::PREPARED) stmt->state= Item_arena::EXECUTED; @@ -2200,9 +2167,9 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, SYNOPSIS mysql_stmt_fetch() - thd Thread handler - packet Packet from client (with stmt_id & num_rows) - packet_length Length of packet + thd Thread handler + packet Packet from client (with stmt_id & num_rows) + packet_length Length of packet */ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) @@ -2210,7 +2177,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) /* assume there is always place for 8-16 bytes */ ulong stmt_id= uint4korr(packet); ulong num_rows= uint4korr(packet+4); - Statement *stmt; + Prepared_statement *stmt; DBUG_ENTER("mysql_stmt_fetch"); if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch"))) @@ -2224,23 +2191,27 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) thd->current_arena= stmt; thd->set_n_backup_statement(stmt, &thd->stmt_backup); - stmt->cursor->init_thd(thd); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), QUERY_PRIOR); - thd->protocol= &thd->protocol_prep; // Switch to binary protocol + thd->protocol= &thd->protocol_prep; // Switch to binary protocol stmt->cursor->fetch(num_rows); thd->protocol= &thd->protocol_simple; // Use normal protocol if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); - /* Restore THD state */ - stmt->cursor->reset_thd(thd); thd->restore_backup_statement(stmt, &thd->stmt_backup); thd->current_arena= thd; + if (!stmt->cursor->is_open()) + { + /* We're done with the fetch: reset PS for next execution */ + cleanup_stmt_and_thd_after_use(stmt, thd); + reset_stmt_params(stmt); + } + DBUG_VOID_RETURN; } @@ -2250,7 +2221,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) SYNOPSIS mysql_stmt_reset() thd Thread handle - packet Packet with stmt id + packet Packet with stmt id DESCRIPTION This function resets statement to the state it was right after prepare. @@ -2277,22 +2248,22 @@ void mysql_stmt_reset(THD *thd, char *packet) stmt->state= Item_arena::PREPARED; - /* - Clear parameters from data which could be set by + /* + Clear parameters from data which could be set by mysql_stmt_send_long_data() call. */ reset_stmt_params(stmt); mysql_reset_thd_for_next_command(thd); send_ok(thd); - + DBUG_VOID_RETURN; } /* Delete a prepared statement from memory. - Note: we don't send any reply to that command. + Note: we don't send any reply to that command. */ void mysql_stmt_free(THD *thd, char *packet) @@ -2317,9 +2288,9 @@ void mysql_stmt_free(THD *thd, char *packet) SYNOPSIS mysql_stmt_get_longdata() - thd Thread handle - pos String to append - packet_length Length of string + thd Thread handle + pos String to append + packet_length Length of string DESCRIPTION Get a part of a long data. @@ -2338,7 +2309,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) Prepared_statement *stmt; Item_param *param; char *packet_end= packet + packet_length - 1; - + DBUG_ENTER("mysql_stmt_get_longdata"); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 71cebb61ae6..87bf5463ffa 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -84,7 +84,7 @@ static int send_file(THD *thd) char fname[FN_REFLEN+1]; const char *errmsg = 0; int old_timeout; - uint packet_len; + unsigned long packet_len; char buf[IO_SIZE]; // It's safe to alloc this DBUG_ENTER("send_file"); @@ -1316,6 +1316,7 @@ bool mysql_show_binlog_events(THD* thd) if (mysql_bin_log.is_open()) { LEX_MASTER_INFO *lex_mi= &thd->lex->mi; + SELECT_LEX_UNIT *unit= &thd->lex->unit; ha_rows event_count, limit_start, limit_end; my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly char search_file_name[FN_REFLEN], *name; @@ -1324,8 +1325,9 @@ bool mysql_show_binlog_events(THD* thd) LOG_INFO linfo; Log_event* ev; - limit_start= thd->lex->current_select->offset_limit; - limit_end= thd->lex->current_select->select_limit + limit_start; + unit->set_limit(thd->lex->current_select); + limit_start= unit->offset_limit_cnt; + limit_end= unit->select_limit_cnt; name= search_file_name; if (log_file_name) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 27ef3fcea6f..099b7857af8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17,8 +17,6 @@ /* mysql_select and join optimization */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif @@ -36,9 +34,6 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "index_merge" }; -const key_map key_map_empty(0); -const key_map key_map_full(~(uint)0); - static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array); static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds, DYNAMIC_ARRAY *keyuse); @@ -88,7 +83,7 @@ static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables); static void update_depend_map(JOIN *join); static void update_depend_map(JOIN *join, ORDER *order); static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond, - bool *simple_order); + bool change_list, bool *simple_order); static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables, List &fields, bool send_row, uint select_options, const char *info, @@ -749,7 +744,7 @@ JOIN::optimize() /* Optimize distinct away if possible */ { ORDER *org_order= order; - order=remove_const(this, order,conds,&simple_order); + order=remove_const(this, order,conds,1, &simple_order); /* If we are using ORDER BY NULL or ORDER BY const_expression, return result in any order (even if we are using a GROUP BY) @@ -817,8 +812,9 @@ JOIN::optimize() DBUG_RETURN(1); } simple_group= 0; - if (rollup.state == ROLLUP::STATE_NONE) - group_list= remove_const(this, group_list, conds, &simple_group); + group_list= remove_const(this, group_list, conds, + rollup.state == ROLLUP::STATE_NONE, + &simple_group); if (!group_list && group) { order=0; // The output has only one row @@ -830,7 +826,7 @@ JOIN::optimize() if (procedure && procedure->group) { group_list= procedure->group= remove_const(this, procedure->group, conds, - &simple_group); + 1, &simple_group); calc_group_buffer(this, group_list); } @@ -957,32 +953,35 @@ JOIN::optimize() #endif DBUG_EXECUTE("info",TEST_join(this);); - /* - Because filesort always does a full table scan or a quick range scan - we must add the removed reference to the select for the table. - We only need to do this when we have a simple_order or simple_group - as in other cases the join is done before the sort. - */ - if (const_tables != tables && - (order || group_list) && - join_tab[const_tables].type != JT_ALL && - join_tab[const_tables].type != JT_FT && - join_tab[const_tables].type != JT_REF_OR_NULL && - (order && simple_order || group_list && simple_group)) - { - if (add_ref_to_table_cond(thd,&join_tab[const_tables])) - DBUG_RETURN(1); - } - if (!(select_options & SELECT_BIG_RESULT) && - ((group_list && const_tables != tables && - (!simple_group || - !test_if_skip_sort_order(&join_tab[const_tables], group_list, - unit->select_limit_cnt, 0))) || - select_distinct) && - tmp_table_param.quick_group && !procedure) + if (const_tables != tables) { - need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort + /* + Because filesort always does a full table scan or a quick range scan + we must add the removed reference to the select for the table. + We only need to do this when we have a simple_order or simple_group + as in other cases the join is done before the sort. + */ + if ((order || group_list) && + join_tab[const_tables].type != JT_ALL && + join_tab[const_tables].type != JT_FT && + join_tab[const_tables].type != JT_REF_OR_NULL && + (order && simple_order || group_list && simple_group)) + { + if (add_ref_to_table_cond(thd,&join_tab[const_tables])) + DBUG_RETURN(1); + } + + if (!(select_options & SELECT_BIG_RESULT) && + ((group_list && + (!simple_group || + !test_if_skip_sort_order(&join_tab[const_tables], group_list, + unit->select_limit_cnt, 0))) || + select_distinct) && + tmp_table_param.quick_group && !procedure) + { + need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort + } } tmp_having= having; @@ -1710,10 +1709,11 @@ Cursor::init_from_thd(THD *thd) We need to save and reset thd->mem_root, otherwise it'll be freed later in mysql_parse. - We can't just change the thd->mem_root here as we want to keep the things - that is already allocated in thd->mem_root for Cursor::fetch() + We can't just change the thd->mem_root here as we want to keep the + things that are already allocated in thd->mem_root for Cursor::fetch() */ main_mem_root= *thd->mem_root; + state= thd->current_arena->state; /* Allocate new memory root for thd */ init_sql_alloc(thd->mem_root, thd->variables.query_alloc_block_size, @@ -1736,24 +1736,6 @@ Cursor::init_from_thd(THD *thd) What problems can we have with it if cursor is open? TODO: must be fixed because of the prelocked mode. */ - /* - TODO: grab thd->free_list here? - */ -} - - -void -Cursor::init_thd(THD *thd) -{ - DBUG_ASSERT(thd->derived_tables == 0); - thd->derived_tables= derived_tables; - - DBUG_ASSERT(thd->open_tables == 0); - thd->open_tables= open_tables; - - DBUG_ASSERT(thd->lock== 0); - thd->lock= lock; - thd->query_id= query_id; } @@ -1829,6 +1811,13 @@ Cursor::fetch(ulong num_rows) DBUG_ENTER("Cursor::fetch"); DBUG_PRINT("enter",("rows: %lu", num_rows)); + DBUG_ASSERT(thd->derived_tables == 0 && thd->open_tables == 0 && + thd->lock == 0); + + thd->derived_tables= derived_tables; + thd->open_tables= open_tables; + thd->lock= lock; + thd->query_id= query_id; /* save references to memory, allocated during fetch */ thd->set_n_backup_item_arena(this, &thd->stmt_backup); @@ -1847,6 +1836,9 @@ Cursor::fetch(ulong num_rows) #endif thd->restore_backup_item_arena(this, &thd->stmt_backup); + DBUG_ASSERT(thd->free_list == 0); + reset_thd(thd); + if (error == NESTED_LOOP_CURSOR_LIMIT) { /* Fetch limit worked, possibly more rows are there */ @@ -1887,8 +1879,8 @@ Cursor::close() join->cleanup(); delete join; } - /* XXX: Another hack: closing tables used in the cursor */ { + /* XXX: Another hack: closing tables used in the cursor */ DBUG_ASSERT(lock || open_tables || derived_tables); TABLE *tmp_derived_tables= thd->derived_tables; @@ -2085,8 +2077,8 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, { select->head=table; table->reginfo.impossible_range=0; - if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, - limit)) == 1) + if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, + limit, 0)) == 1) DBUG_RETURN(select->quick->records); if (error == -1) { @@ -5088,7 +5080,8 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join_tab->select_cond=0; join_tab->quick=0; join_tab->type= JT_ALL; /* Map through all records */ - join_tab->keys.init(~(uint)0); /* test everything in quick */ + join_tab->keys.init(); + join_tab->keys.set_all(); /* test everything in quick */ join_tab->info=0; join_tab->on_expr_ref=0; join_tab->last_inner= 0; @@ -5381,6 +5374,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) JOIN_TAB *first_inner_tab= tab->first_inner; table_map current_map= tab->table->map; bool use_quick_range=0; + COND *tmp; + /* Following force including random expression in last table condition. It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 @@ -5402,7 +5397,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) join->best_positions[i].records_read= rows2double(tab->quick->records); } - COND *tmp= NULL; + tmp= NULL; if (cond) tmp= make_cond_for_table(cond,used_tables,current_map); if (cond && !tmp && tab->quick) @@ -5535,7 +5530,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) (join->select_options & OPTION_FOUND_ROWS ? HA_POS_ERROR : - join->unit->select_limit_cnt)) < 0) + join->unit->select_limit_cnt), 0) < 0) { /* Before reporting "Impossible WHERE" for the whole query @@ -5548,7 +5543,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) (join->select_options & OPTION_FOUND_ROWS ? HA_POS_ERROR : - join->unit->select_limit_cnt)) < 0) + join->unit->select_limit_cnt),0) < 0) DBUG_RETURN(1); // Impossible WHERE } else @@ -6117,20 +6112,39 @@ static void update_depend_map(JOIN *join, ORDER *order) /* - simple_order is set to 1 if sort_order only uses fields from head table - and the head table is not a LEFT JOIN table + Remove all constants and check if ORDER only contains simple expressions + + SYNOPSIS + remove_const() + join Join handler + first_order List of SORT or GROUP order + cond WHERE statement + change_list Set to 1 if we should remove things from list + If this is not set, then only simple_order is + calculated + simple_order Set to 1 if we are only using simple expressions + + RETURN + Returns new sort order + + simple_order is set to 1 if sort_order only uses fields from head table + and the head table is not a LEFT JOIN table + */ static ORDER * -remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) +remove_const(JOIN *join,ORDER *first_order, COND *cond, + bool change_list, bool *simple_order) { if (join->tables == join->const_tables) - return 0; // No need to sort - DBUG_ENTER("remove_const"); + return change_list ? 0 : first_order; // No need to sort + ORDER *order,**prev_ptr; table_map first_table= join->join_tab[join->const_tables].table->map; table_map not_const_tables= ~join->const_table_map; table_map ref; + DBUG_ENTER("remove_const"); + prev_ptr= &first_order; *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1; @@ -6161,7 +6175,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) } if ((ref=order_tables & (not_const_tables ^ first_table))) { - if (!(order_tables & first_table) && only_eq_ref_tables(join,first_order,ref)) + if (!(order_tables & first_table) && + only_eq_ref_tables(join,first_order, ref)) { DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue; @@ -6170,11 +6185,13 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) } } } - *prev_ptr= order; // use this entry + if (change_list) + *prev_ptr= order; // use this entry prev_ptr= &order->next; } - *prev_ptr=0; - if (!first_order) // Nothing to sort/group + if (change_list) + *prev_ptr=0; + if (prev_ptr == &first_order) // Nothing to sort/group *simple_order=1; DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order)); DBUG_RETURN(first_order); @@ -7379,6 +7396,8 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) } else { + if (!(table->prep_on_expr)) + table->prep_on_expr= table->on_expr; used_tables= table->table->map; if (conds) not_null_tables= conds->not_null_tables(); @@ -7989,7 +8008,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, bool using_unique_constraint= 0; bool use_packed_rows= 0; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); - char *tmpname,path[FN_REFLEN], filename[FN_REFLEN]; + char *tmpname,path[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; Field **reg_field, **from_field; @@ -9822,7 +9841,7 @@ test_if_quick_select(JOIN_TAB *tab) delete tab->select->quick; tab->select->quick=0; return tab->select->test_quick_select(tab->join->thd, tab->keys, - (table_map) 0, HA_POS_ERROR); + (table_map) 0, HA_POS_ERROR, 0); } @@ -10051,7 +10070,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { join->do_send_rows= 0; if (join->unit->fake_select_lex) - join->unit->fake_select_lex->select_limit= HA_POS_ERROR; + join->unit->fake_select_lex->select_limit= 0; DBUG_RETURN(NESTED_LOOP_OK); } } @@ -10858,12 +10877,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, parameres are set correctly by the range optimizer. */ key_map new_ref_key_map; - new_ref_key_map.clear_all(); /* Force the creation of quick select */ - new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */ + new_ref_key_map.clear_all(); // Force the creation of quick select + new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key. if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0, - (tab->join->select_options & OPTION_FOUND_ROWS) ? - HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0) + (tab->join->select_options & + OPTION_FOUND_ROWS) ? + HA_POS_ERROR : + tab->join->unit->select_limit_cnt,0) <= + 0) DBUG_RETURN(0); } ref_key= new_ref_key; @@ -12252,7 +12274,7 @@ alloc_group_fields(JOIN *join,ORDER *group) { for (; group ; group=group->next) { - Item_buff *tmp=new_Item_buff(*group->item); + Item_buff *tmp=new_Item_buff(join->thd, *group->item); if (!tmp || join->group_fields.push_front(tmp)) return TRUE; } @@ -12521,6 +12543,8 @@ bool JOIN::make_sum_func_list(List &field_list, List &send_fields, for (uint i=0 ; i <= send_group_parts ;i++) sum_funcs_end[i]= func; } + else if (rollup.state == ROLLUP::STATE_READY) + DBUG_RETURN(FALSE); // Don't put end marker *func=0; // End marker DBUG_RETURN(FALSE); } @@ -13058,17 +13082,15 @@ bool JOIN::rollup_make_fields(List &fields_arg, List &sel_fields, { if (item->eq(*group_tmp->item,0)) { - Item_null_result *null_item; /* This is an element that is used by the GROUP BY and should be set to NULL in this level */ + Item_null_result *null_item= new (thd->mem_root) Item_null_result(); + if (!null_item) + return 1; item->maybe_null= 1; // Value will be null sometimes - null_item= rollup.null_items[i]; - DBUG_ASSERT(null_item->result_field == 0 || - null_item->result_field == - ((Item_field *) item)->result_field); - null_item->result_field= ((Item_field *) item)->result_field; + null_item->result_field= item->get_tmp_table_field(); item= null_item; break; } @@ -13610,7 +13632,7 @@ static void print_join(THD *thd, String *str, List *tables) (*table)->print(thd, str); TABLE_LIST **end= table + tables->elements; - for(TABLE_LIST **tbl= table + 1; tbl < end; tbl++) + for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) { TABLE_LIST *curr= *tbl; if (curr->outer_join) diff --git a/sql/sql_select.h b/sql/sql_select.h index 49ac58e913b..5351bbb13d3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -386,8 +386,6 @@ public: /* Temporary implementation as now we replace THD state by value */ /* Save THD state into cursor */ void init_from_thd(THD *thd); - /* Restore THD from cursor to continue cursor execution */ - void init_thd(THD *thd); /* bzero cursor state in THD */ void reset_thd(THD *thd); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 32ad85b88f7..1e34f32184a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1265,7 +1265,7 @@ static bool show_status_array(THD *thd, const char *wild, name_buffer, wild))) { char *value=variables->value; - const char *pos, *end; + const char *pos, *end; // We assign a lot of const's long nr; if (show_type == SHOW_SYS) { @@ -1336,8 +1336,8 @@ static bool show_status_array(THD *thd, const char *wild, case SHOW_SLAVE_RETRIED_TRANS: { /* - TODO: in 5.1 with multimaster, have one such counter per line in SHOW - SLAVE STATUS, and have the sum over all lines here. + TODO: in 5.1 with multimaster, have one such counter per line in + SHOW SLAVE STATUS, and have the sum over all lines here. */ pthread_mutex_lock(&LOCK_active_mi); pthread_mutex_lock(&active_mi->rli.data_lock); @@ -1359,7 +1359,11 @@ static bool show_status_array(THD *thd, const char *wild, } else { - for (int i= 1; i < MAX_SLAVE_ERROR; i++) + /* 10 is enough assuming errors are max 4 digits */ + int i; + for (i= 1; + i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10; + i++) { if (bitmap_is_set(bitmap, i)) { @@ -1369,6 +1373,8 @@ static bool show_status_array(THD *thd, const char *wild, } if (end != buff) end--; // Remove last ',' + if (i < MAX_SLAVE_ERROR) + end= strmov((char*) end, "..."); // Couldn't show all errors } break; } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index be4354227a5..51f802e7465 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -16,12 +16,11 @@ /* This file is originally from the mysql distribution. Coded by monty */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif +#include #include #include #include diff --git a/sql/sql_string.h b/sql/sql_string.h index c05305d9265..ddae6368228 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -261,8 +261,6 @@ public: } bool fill(uint32 max_length,char fill); void strip_sp(); - inline void caseup() { my_caseup(str_charset,Ptr,str_length); } - inline void casedn() { my_casedn(str_charset,Ptr,str_length); } friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d98ae778bcf..8a29c481dc1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -346,7 +346,7 @@ int quick_rm_table(enum db_type base,const char *db, build_table_path(path, sizeof(path), db, table_name, reg_ext); if (my_delete(path,MYF(0))) error=1; /* purecov: inspected */ - build_table_path(path, sizeof(path), db, table_name, ""); + *fn_ext(path)= 0; // Remove reg_ext return ha_delete_table(current_thd, base, path, table_name, 0) || error; } @@ -1556,7 +1556,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, /* Check if table exists */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { - char tmp_table_name[NAME_LEN+1]; + char tmp_table_name[tmp_file_prefix_length+22+22+22+3]; my_snprintf(tmp_table_name, sizeof(tmp_table_name), "%s%lx_%lx_%x", tmp_file_prefix, current_pid, thd->thread_id, thd->tmp_table++); @@ -2589,28 +2589,33 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char *db= table->db; char *table_name= table->table_name; - char *src_db= thd->db; + char *src_db; char *src_table= table_ident->table.str; int err; bool res= TRUE; TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); + src_db= table_ident->db.str ? table_ident->db.str : thd->db; /* Validate the source table */ if (table_ident->table.length > NAME_LEN || (table_ident->table.length && - check_table_name(src_table,table_ident->table.length)) || - table_ident->db.str && check_db_name((src_db= table_ident->db.str))) + check_table_name(src_table,table_ident->table.length))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); DBUG_RETURN(TRUE); } + if (!src_db || check_db_name(src_db)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL"); + DBUG_RETURN(-1); + } bzero((gptr)&src_tables_list, sizeof(src_tables_list)); - src_tables_list.db= table_ident->db.str ? table_ident->db.str : thd->db; - src_tables_list.table_name= table_ident->table.str; + src_tables_list.db= src_db; + src_tables_list.table_name= src_table; if (lock_and_wait_for_table_name(thd, &src_tables_list)) goto err; @@ -2909,7 +2914,7 @@ int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List &keys) build_table_path(path, sizeof(path), table_list->db, (lower_case_table_names == 2) ? table_list->alias : table_list->table_name, - reg_ext) != 0 || + reg_ext) == 0 || mysql_create_frm(thd, path, &create_info, fields, key_count, key_info_buffer, table->file)) /* don't need to free((gptr) key_info_buffer);*/ @@ -3010,7 +3015,7 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, build_table_path(path, sizeof(path), table_list->db, (lower_case_table_names == 2) ? table_list->alias : table_list->table_name, - reg_ext) != 0 || + reg_ext) == 0 || mysql_create_frm(thd, path, &create_info, fields, key_count, key_info_buffer, table->file)) /*don't need to free((gptr) key_numbers);*/ @@ -3393,12 +3398,25 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, continue; // Field is removed uint key_part_length=key_part->length; if (cfield->field) // Not new field - { // Check if sub key - if (cfield->field->type() != FIELD_TYPE_BLOB && - (cfield->field->pack_length() == key_part_length || - cfield->length <= key_part_length / - key_part->field->charset()->mbmaxlen)) - key_part_length=0; // Use whole field + { + /* + If the field can't have only a part used in a key according to its + new type, or should not be used partially according to its + previous type, or the field length is less than the key part + length, unset the key part length. + + We also unset the key part length if it is the same as the + old field's length, so the whole new field will be used. + + BLOBs may have cfield->length == 0, which is why we test it before + checking whether cfield->length < key_part_length (in chars). + */ + if (!Field::type_can_have_key_part(cfield->field->type()) || + !Field::type_can_have_key_part(cfield->sql_type) || + cfield->field->field_length == key_part_length || + (cfield->length && (cfield->length < key_part_length / + key_part->field->charset()->mbmaxlen))) + key_part_length= 0; // Use whole field } key_part_length /= key_part->field->charset()->mbmaxlen; key_parts.push_back(new key_part_spec(cfield->field_name, diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index d61da8ff06b..0547283d0c5 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -53,6 +53,7 @@ public: if (bodies[event][time_type]) { + bool save_in_sub_stmt= thd->transaction.in_sub_stmt; #ifndef EMBEDDED_LIBRARY /* Surpress OK packets in case if we will execute statements */ my_bool nsok= thd->net.no_send_ok; @@ -81,7 +82,11 @@ public: does NOT go into binlog. */ tmp_disable_binlog(thd); + thd->transaction.in_sub_stmt= TRUE; + res= bodies[event][time_type]->execute_function(thd, 0, 0, 0); + + thd->transaction.in_sub_stmt= save_in_sub_stmt; reenable_binlog(thd); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 7c6e88306d9..e0c3034a58a 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -28,10 +28,8 @@ dynamic functions, so this shouldn't be a real problem. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation // gcc: implement sql_udf.h +#pragma implementation // gcc: Class implementation #endif #include "mysql_priv.h" diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 56401ced67c..912636b6cf3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -448,7 +448,7 @@ bool st_select_lex_unit::exec() table->no_keyread=1; } res= sl->join->error; - offset_limit_cnt= sl->offset_limit; + offset_limit_cnt= sl->offset_limit ? sl->offset_limit->val_uint() : 0; if (!res) { examined_rows+= thd->examined_row_count; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 0d00c38f638..6b9a8ddfcb6 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -710,7 +710,7 @@ bool mysql_multi_update_prepare(THD *thd) tl->table->reginfo.lock_type= tl->lock_type; } } - for(tl= table_list; tl; tl= tl->next_local) + for (tl= table_list; tl; tl= tl->next_local) { /* Check access privileges for table */ if (!tl->derived) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 289bf9d28a3..9f0c3260d8f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1000,8 +1000,9 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view) we do not support updatable UNIONs in VIEW, so we can check just limit of LEX::select_lex */ - if ((!view->view && !view->belong_to_view) || thd->lex->sql_command == SQLCOM_INSERT || - thd->lex->select_lex.select_limit == HA_POS_ERROR) + if ((!view->view && !view->belong_to_view) || + thd->lex->sql_command == SQLCOM_INSERT || + thd->lex->select_lex.select_limit == 0) DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */ table= view->table; if (view->belong_to_view) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2f584bc6b4e..33d6c192d07 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -721,7 +721,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); signed_literal now_or_signed_literal opt_escape sp_opt_default simple_ident_nospvar simple_ident_q - field_or_var + field_or_var limit_option %type NUM_literal @@ -919,6 +919,11 @@ deallocate: yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "DEALLOCATE"); + YYABORT; + } lex->sql_command= SQLCOM_DEALLOCATE_PREPARE; lex->prepared_stmt_name= $3; }; @@ -939,6 +944,11 @@ prepare: yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "PREPARE"); + YYABORT; + } lex->sql_command= SQLCOM_PREPARE; lex->prepared_stmt_name= $2; }; @@ -969,6 +979,11 @@ execute: yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "EXECUTE"); + YYABORT; + } lex->sql_command= SQLCOM_EXECUTE; lex->prepared_stmt_name= $2; } @@ -1138,6 +1153,11 @@ create: | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_CREATE_INDEX; if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, TL_OPTION_UPDATING)) @@ -3285,6 +3305,11 @@ alter: { THD *thd= YYTHD; LEX *lex= thd->lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_ALTER_TABLE; lex->name= 0; lex->duplicates= DUP_ERROR; @@ -3593,8 +3618,14 @@ slave: start: START_SYM TRANSACTION_SYM start_transaction_opts { - Lex->sql_command = SQLCOM_BEGIN; - Lex->start_transaction_opt= $3; + LEX *lex= Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } + lex->sql_command= SQLCOM_BEGIN; + lex->start_transaction_opt= $3; } ; @@ -3772,7 +3803,13 @@ opt_no_write_to_binlog: rename: RENAME table_or_tables { - Lex->sql_command=SQLCOM_RENAME_TABLE; + LEX *lex= Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } + lex->sql_command=SQLCOM_RENAME_TABLE; } table_to_table_list {} @@ -5071,10 +5108,12 @@ derived_table_list: join_table: table_ref normal_join table_ref { TEST_ASSERT($1 && ($$=$3)); } - | table_ref STRAIGHT_JOIN table_factor - { TEST_ASSERT($1 && ($$=$3)); $3->straight=1; } + | table_ref STRAIGHT_JOIN table_ref + { TEST_ASSERT($1 && ($$=$3)); $3->straight=1; } | table_ref normal_join table_ref ON expr { TEST_ASSERT($1 && ($$=$3)); add_join_on($3,$5); } + | table_ref STRAIGHT_JOIN table_ref ON expr + { TEST_ASSERT($1 && ($$=$3)); $3->straight=1; add_join_on($3,$5); } | table_ref normal_join table_ref USING { @@ -5542,8 +5581,8 @@ opt_limit_clause_init: { LEX *lex= Lex; SELECT_LEX *sel= lex->current_select; - sel->offset_limit= 0L; - sel->select_limit= HA_POS_ERROR; + sel->offset_limit= 0; + sel->select_limit= 0; } | limit_clause {} ; @@ -5558,21 +5597,21 @@ limit_clause: ; limit_options: - ulong_num + limit_option { SELECT_LEX *sel= Select; sel->select_limit= $1; - sel->offset_limit= 0L; + sel->offset_limit= 0; sel->explicit_limit= 1; } - | ulong_num ',' ulong_num + | limit_option ',' limit_option { SELECT_LEX *sel= Select; sel->select_limit= $3; sel->offset_limit= $1; sel->explicit_limit= 1; } - | ulong_num OFFSET_SYM ulong_num + | limit_option OFFSET_SYM limit_option { SELECT_LEX *sel= Select; sel->select_limit= $1; @@ -5580,18 +5619,23 @@ limit_options: sel->explicit_limit= 1; } ; - +limit_option: + param_marker + | ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); } + | LONG_NUM { $$= new Item_uint($1.str, $1.length); } + | NUM { $$= new Item_uint($1.str, $1.length); } + ; delete_limit_clause: /* empty */ { LEX *lex=Lex; - lex->current_select->select_limit= HA_POS_ERROR; + lex->current_select->select_limit= 0; } - | LIMIT ulonglong_num + | LIMIT limit_option { SELECT_LEX *sel= Select; - sel->select_limit= (ha_rows) $2; + sel->select_limit= $2; sel->explicit_limit= 1; }; @@ -5751,10 +5795,21 @@ drop: lex->sql_command = SQLCOM_DROP_TABLE; lex->drop_temporary= $2; lex->drop_if_exists= $4; + if (!lex->drop_temporary && lex->sphead && + lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } } | DROP INDEX_SYM ident ON table_ident {} { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_DROP_INDEX; lex->alter_info.drop_list.empty(); lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, @@ -5802,6 +5857,11 @@ drop: { THD *thd= YYTHD; LEX *lex= thd->lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_DROP_VIEW; lex->drop_if_exists= $3; } @@ -6089,10 +6149,17 @@ single_multi: | table_wild_list { mysql_init_multi_delete(Lex); } FROM join_table_list where_clause + { + if (multi_delete_set_locks_and_link_aux_tables(Lex)) + YYABORT; + } | FROM table_wild_list { mysql_init_multi_delete(Lex); } USING join_table_list where_clause - {} + { + if (multi_delete_set_locks_and_link_aux_tables(Lex)) + YYABORT; + } ; table_wild_list: @@ -7942,8 +8009,8 @@ handler: LEX *lex=Lex; lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ - lex->current_select->select_limit= 1; - lex->current_select->offset_limit= 0L; + lex->current_select->select_limit= new Item_int((int32) 1); + lex->current_select->offset_limit= 0; if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0)) YYABORT; } @@ -8364,6 +8431,11 @@ begin: BEGIN_SYM { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command = SQLCOM_BEGIN; lex->start_transaction_opt= 0; } @@ -8396,6 +8468,11 @@ commit: COMMIT_SYM opt_work opt_chain opt_release { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_COMMIT; lex->tx_chain= $3; lex->tx_release= $4; @@ -8406,6 +8483,11 @@ rollback: ROLLBACK_SYM opt_work opt_chain opt_release { LEX *lex=Lex; + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); + YYABORT; + } lex->sql_command= SQLCOM_ROLLBACK; lex->tx_chain= $3; lex->tx_release= $4; diff --git a/sql/table.cc b/sql/table.cc index eb4dbe5a1f3..33cee79eb61 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2164,16 +2164,12 @@ bool st_table_list::check_single_table(st_table_list **table, table_map map, { if (*table) return TRUE; - else - { - *table= tbl; - tbl->check_option= view->check_option; - } + *table= tbl; + tbl->check_option= view->check_option; } } - else - if (tbl->check_single_table(table, map, view)) - return TRUE; + else if (tbl->check_single_table(table, map, view)) + return TRUE; } return FALSE; } diff --git a/sql/table.h b/sql/table.h index 8043429999b..8bc4e01852f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -436,10 +436,7 @@ typedef struct st_table_list bool skip_temporary; /* this table shouldn't be temporary */ /* TRUE if this merged view contain auto_increment field */ bool contain_auto_increment; -#if 0 -#else bool multitable_view; /* TRUE iff this is multitable view */ -#endif /* FRMTYPE_ERROR if any type is acceptable */ enum frm_type_enum required_type; char timestamp_buffer[20]; /* buffer for timestamp (19+1) */ diff --git a/sql/tztime.cc b/sql/tztime.cc index a52b9701e8e..f5111459da2 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -25,12 +25,11 @@ it creates unsolved link dependencies on some platforms. */ -#include - #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation #endif +#include #if !defined(TZINFO2SQL) && !defined(TESTTIME) #include "mysql_priv.h" #else diff --git a/sql/uniques.cc b/sql/uniques.cc index b08727705e4..367aed2d113 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -178,7 +178,7 @@ static double get_merge_many_buffs_cost(uint *buffer, Set initial state: first maxbuffer sequences contain max_n_elems elements each, last sequence contains last_n_elems elements. */ - for(i = 0; i < (int)maxbuffer; i++) + for (i = 0; i < (int)maxbuffer; i++) buff_elems[i]= max_n_elems; buff_elems[maxbuffer]= last_n_elems; diff --git a/sql/unireg.cc b/sql/unireg.cc index eda17d8f4a9..e8aad2fedd0 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -668,7 +668,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, { int error; Field::utype type; - uint firstpos, null_count; + uint null_count; uchar *buff,*null_pos; TABLE table; create_field *field; diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 447eea3e635..a4040ed2b90 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6384,9 +6384,12 @@ CHARSET_INFO my_charset_big5_chinese_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -6412,9 +6415,12 @@ CHARSET_INFO my_charset_big5_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 56df289158a..13105df9334 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -208,10 +208,13 @@ static void my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)), { } -static void my_case_bin(CHARSET_INFO *cs __attribute__((unused)), - char *str __attribute__((unused)), - uint length __attribute__((unused))) +static uint my_case_bin(CHARSET_INFO *cs __attribute__((unused)), + char *src __attribute__((unused)), + uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { + return srclen; } @@ -526,9 +529,12 @@ CHARSET_INFO my_charset_bin = NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index f2f31b1064e..fd2b0fd8e21 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -5512,9 +5512,12 @@ CHARSET_INFO my_charset_cp932_japanese_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -5539,9 +5542,12 @@ CHARSET_INFO my_charset_cp932_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index aaf87e97cb8..1361b728b26 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -618,9 +618,12 @@ CHARSET_INFO my_charset_latin2_czech_ci = NULL, /* sort_order_big*/ tab_8859_2_uni, /* tab_to_uni */ idx_uni_8859_2, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 4, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 21b7b56fdaa..e2167aa315e 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8696,9 +8696,12 @@ CHARSET_INFO my_charset_euckr_korean_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -8724,9 +8727,12 @@ CHARSET_INFO my_charset_euckr_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index d9171c800bf..784293918ed 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -8698,9 +8698,12 @@ CHARSET_INFO my_charset_eucjpms_japanese_ci= NULL, /* contractions */ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ @@ -8726,9 +8729,12 @@ CHARSET_INFO my_charset_eucjpms_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index 3672dcd0b33..2544245bc42 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -33,9 +33,12 @@ CHARSET_INFO compiled_charsets[] = { NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 0, /* strxfrm_mul */ + 0, /* caseup_mul */ + 0, /* casedn_mul */ 0, /* mbminlen */ 0, /* mbmaxlen */ 0, /* min_sort_ord */ diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 592ee341781..6b582081085 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5747,9 +5747,12 @@ CHARSET_INFO my_charset_gb2312_chinese_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -5774,9 +5777,12 @@ CHARSET_INFO my_charset_gb2312_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index ec96caa6b91..4150f198722 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9994,9 +9994,12 @@ CHARSET_INFO my_charset_gbk_chinese_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -10021,9 +10024,12 @@ CHARSET_INFO my_charset_gbk_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 7a75992dc4f..afe996d3cda 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -424,9 +424,12 @@ CHARSET_INFO my_charset_latin1= NULL, /* sort_order_big*/ cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ @@ -719,9 +722,12 @@ CHARSET_INFO my_charset_latin1_german2_ci= NULL, /* sort_order_big*/ cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 2, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ @@ -747,9 +753,12 @@ CHARSET_INFO my_charset_latin1_bin= NULL, /* sort_order_big*/ cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index b3ec476b8f5..2d9f8b16bfc 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -57,40 +57,48 @@ void my_casedn_str_mb(CHARSET_INFO * cs, char *str) } } -void my_caseup_mb(CHARSET_INFO * cs, char *str, uint length) +uint my_caseup_mb(CHARSET_INFO * cs, char *src, uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { register uint32 l; - register char *end=str+length; - register uchar *map=cs->to_upper; - - while (strto_upper; + + DBUG_ASSERT(src == dst && srclen == dstlen); + while (src < srcend) { - if ((l=my_ismbchar(cs, str,end))) - str+=l; + if ((l=my_ismbchar(cs, src, srcend))) + src+= l; else { - *str=(char) map[(uchar)*str]; - str++; + *src=(char) map[(uchar) *src]; + src++; } } + return srclen; } -void my_casedn_mb(CHARSET_INFO * cs, char *str, uint length) +uint my_casedn_mb(CHARSET_INFO * cs, char *src, uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { register uint32 l; - register char *end=str+length; + register char *srcend= src + srclen; register uchar *map=cs->to_lower; - - while (strto_upper; - for ( ; length>0 ; length--, str++) - *str= (char) map[(uchar)*str]; + uint srclen0= srclen; + register uchar *map= cs->to_upper; + DBUG_ASSERT(src == dst && srclen == dstlen); + for ( ; srclen > 0 ; srclen--, src++) + *src= (char) map[(uchar) *src]; + return srclen0; } -void my_casedn_8bit(CHARSET_INFO * cs, char *str, uint length) +uint my_casedn_8bit(CHARSET_INFO * cs, char *src, uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { + uint srclen0= srclen; register uchar *map=cs->to_lower; - for ( ; length>0 ; length--, str++) - *str= (char) map[(uchar) *str]; + DBUG_ASSERT(src == dst && srclen == dstlen); + for ( ; srclen > 0 ; srclen--, src++) + *src= (char) map[(uchar) *src]; + return srclen0; } int my_strcasecmp_8bit(CHARSET_INFO * cs,const char *s, const char *t) @@ -1303,6 +1313,8 @@ static my_bool create_fromuni(CHARSET_INFO *cs, void *(*alloc)(uint)) static my_bool my_cset_init_8bit(CHARSET_INFO *cs, void *(*alloc)(uint)) { + cs->caseup_multiply= 1; + cs->casedn_multiply= 1; return create_fromuni(cs, alloc); } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index a7d75da42c9..9cd5d6d7981 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4681,9 +4681,12 @@ CHARSET_INFO my_charset_sjis_japanese_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -4708,9 +4711,12 @@ CHARSET_INFO my_charset_sjis_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index c40e74c3343..4fe8bb4e349 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -983,9 +983,12 @@ CHARSET_INFO my_charset_tis620_thai_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 4, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ @@ -1010,9 +1013,12 @@ CHARSET_INFO my_charset_tis620_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index fb7e93e10b6..eb207c9821f 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -8049,9 +8049,12 @@ CHARSET_INFO my_charset_ucs2_general_uca= uca_weight, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8076,9 +8079,12 @@ CHARSET_INFO my_charset_ucs2_icelandic_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8103,9 +8109,12 @@ CHARSET_INFO my_charset_ucs2_latvian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8130,9 +8139,12 @@ CHARSET_INFO my_charset_ucs2_romanian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8157,9 +8169,12 @@ CHARSET_INFO my_charset_ucs2_slovenian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8184,9 +8199,12 @@ CHARSET_INFO my_charset_ucs2_polish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8211,9 +8229,12 @@ CHARSET_INFO my_charset_ucs2_estonian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8238,9 +8259,12 @@ CHARSET_INFO my_charset_ucs2_spanish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8265,9 +8289,12 @@ CHARSET_INFO my_charset_ucs2_swedish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8292,9 +8319,12 @@ CHARSET_INFO my_charset_ucs2_turkish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_turkish, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8319,9 +8349,12 @@ CHARSET_INFO my_charset_ucs2_czech_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8347,9 +8380,12 @@ CHARSET_INFO my_charset_ucs2_danish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8374,9 +8410,12 @@ CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8401,9 +8440,12 @@ CHARSET_INFO my_charset_ucs2_slovak_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8428,9 +8470,12 @@ CHARSET_INFO my_charset_ucs2_spanish2_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8456,9 +8501,12 @@ CHARSET_INFO my_charset_ucs2_roman_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8484,9 +8532,12 @@ CHARSET_INFO my_charset_ucs2_persian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8559,9 +8610,12 @@ CHARSET_INFO my_charset_utf8_general_uca_ci= uca_weight, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8587,9 +8641,12 @@ CHARSET_INFO my_charset_utf8_icelandic_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8614,9 +8671,12 @@ CHARSET_INFO my_charset_utf8_latvian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8641,9 +8701,12 @@ CHARSET_INFO my_charset_utf8_romanian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8668,9 +8731,12 @@ CHARSET_INFO my_charset_utf8_slovenian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8695,9 +8761,12 @@ CHARSET_INFO my_charset_utf8_polish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8722,9 +8791,12 @@ CHARSET_INFO my_charset_utf8_estonian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8749,9 +8821,12 @@ CHARSET_INFO my_charset_utf8_spanish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8776,9 +8851,12 @@ CHARSET_INFO my_charset_utf8_swedish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8803,9 +8881,12 @@ CHARSET_INFO my_charset_utf8_turkish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_turkish, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 2, /* caseup_multiply */ + 2, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8830,9 +8911,12 @@ CHARSET_INFO my_charset_utf8_czech_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8858,9 +8942,12 @@ CHARSET_INFO my_charset_utf8_danish_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8885,9 +8972,12 @@ CHARSET_INFO my_charset_utf8_lithuanian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8912,9 +9002,12 @@ CHARSET_INFO my_charset_utf8_slovak_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8939,9 +9032,12 @@ CHARSET_INFO my_charset_utf8_spanish2_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8966,9 +9062,12 @@ CHARSET_INFO my_charset_utf8_roman_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ @@ -8993,9 +9092,12 @@ CHARSET_INFO my_charset_utf8_persian_uca_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 8, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 706d42e3725..4acd75d7a6f 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -30,7 +30,6 @@ #define EILSEQ ENOENT #endif -extern MY_UNICASE_INFO *uni_plane[256]; static uchar ctype_ucs2[] = { 0, @@ -113,20 +112,26 @@ static int my_uni_ucs2(CHARSET_INFO *cs __attribute__((unused)) , } -static void my_caseup_ucs2(CHARSET_INFO *cs, char *s, uint slen) +static uint my_caseup_ucs2(CHARSET_INFO *cs, char *src, uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { my_wc_t wc; int res; - char *e=s+slen; - - while ((s < e) && (res=my_ucs2_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 ) + char *srcend= src + srclen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; + DBUG_ASSERT(src == dst && srclen == dstlen); + + while ((src < srcend) && + (res= my_ucs2_uni(cs, &wc, (uchar *)src, (uchar*) srcend)) > 0) { - int plane = (wc>>8) & 0xFF; - wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc; - if (res != my_uni_ucs2(cs,wc,(uchar*)s,(uchar*)e)) + int plane= (wc>>8) & 0xFF; + wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc; + if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) break; - s+=res; + src+= res; } + return srclen; } @@ -136,6 +141,7 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, uint slen, my_wc_t wc; int res; const uchar *e=s+slen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while (e > s+1 && e[-1] == ' ' && e[-2] == '\0') e-= 2; @@ -160,22 +166,26 @@ static void my_caseup_str_ucs2(CHARSET_INFO * cs __attribute__((unused)), -static void my_casedn_ucs2(CHARSET_INFO *cs, char *s, uint slen) +static uint my_casedn_ucs2(CHARSET_INFO *cs, char *src, uint srclen, + char *dst __attribute__((unused)), + uint dstlen __attribute__((unused))) { my_wc_t wc; int res; - char *e=s+slen; + char *srcend= src + srclen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; + DBUG_ASSERT(src == dst && srclen == dstlen); - while ((s < e) && (res=my_ucs2_uni(cs, &wc, (uchar*)s, (uchar*)e))>0) + while ((src < srcend) && + (res= my_ucs2_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) { - int plane = (wc>>8) & 0xFF; - wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc; - if (res != my_uni_ucs2(cs, wc, (uchar*)s, (uchar*)e)) - { + int plane= (wc>>8) & 0xFF; + wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc; + if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) break; - } - s+=res; + src+= res; } + return srclen; } static void my_casedn_str_ucs2(CHARSET_INFO *cs __attribute__((unused)), @@ -193,6 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, my_wc_t s_wc,t_wc; const uchar *se=s+slen; const uchar *te=t+tlen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -256,6 +267,7 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)), { const uchar *se, *te; uint minlen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; /* extra safety to make sure the lengths are even numbers */ slen&= ~1; @@ -305,6 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, my_wc_t s_wc,t_wc; const char *se=s+len; const char *te=t+len; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -352,6 +365,7 @@ static int my_strnxfrm_ucs2(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while( src < se && dst < de ) { @@ -1310,6 +1324,7 @@ int my_wildcmp_ucs2_ci(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many) { + MY_UNICASE_INFO **uni_plane= cs->caseinfo; return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend, escape,w_one,w_many,uni_plane); } @@ -1596,9 +1611,12 @@ CHARSET_INFO my_charset_ucs2_general_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ @@ -1623,9 +1641,12 @@ CHARSET_INFO my_charset_ucs2_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 2, /* mbminlen */ 2, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 5d0c77cee6e..6b704980d0d 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8566,9 +8566,12 @@ CHARSET_INFO my_charset_ujis_japanese_ci= NULL, /* contractions */ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ @@ -8594,9 +8597,12 @@ CHARSET_INFO my_charset_ujis_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 250c57cf265..6f6d24d8643 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -172,6 +172,8 @@ static MY_UNICASE_INFO plane00[]={ {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059} }; + + static MY_UNICASE_INFO plane01[]={ {0x0100,0x0101,0x0041}, {0x0100,0x0101,0x0041}, {0x0102,0x0103,0x0041}, {0x0102,0x0103,0x0041}, @@ -1482,7 +1484,7 @@ static MY_UNICASE_INFO planeFF[]={ {0xFFFE,0xFFFE,0xFFFE}, {0xFFFF,0xFFFF,0xFFFF} }; -MY_UNICASE_INFO *uni_plane[256]={ +MY_UNICASE_INFO *my_unicase_default[256]={ plane00, plane01, plane02, plane03, plane04, plane05, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1519,6 +1521,186 @@ MY_UNICASE_INFO *uni_plane[256]={ }; +/* + Turkish lower/upper mapping: + 1. LOWER(0x0049 LATIN CAPITAL LETTER I) -> + 0x0131 LATIN SMALL LETTER DOTLESS I + 2. UPPER(0x0069 LATIN SMALL LETTER I) -> + 0x0130 LATIN CAPITAL LETTER I WITH DOT ABOVE +*/ + +static MY_UNICASE_INFO turk00[]= +{ + {0x0000,0x0000,0x0000}, {0x0001,0x0001,0x0001}, + {0x0002,0x0002,0x0002}, {0x0003,0x0003,0x0003}, + {0x0004,0x0004,0x0004}, {0x0005,0x0005,0x0005}, + {0x0006,0x0006,0x0006}, {0x0007,0x0007,0x0007}, + {0x0008,0x0008,0x0008}, {0x0009,0x0009,0x0009}, + {0x000A,0x000A,0x000A}, {0x000B,0x000B,0x000B}, + {0x000C,0x000C,0x000C}, {0x000D,0x000D,0x000D}, + {0x000E,0x000E,0x000E}, {0x000F,0x000F,0x000F}, + {0x0010,0x0010,0x0010}, {0x0011,0x0011,0x0011}, + {0x0012,0x0012,0x0012}, {0x0013,0x0013,0x0013}, + {0x0014,0x0014,0x0014}, {0x0015,0x0015,0x0015}, + {0x0016,0x0016,0x0016}, {0x0017,0x0017,0x0017}, + {0x0018,0x0018,0x0018}, {0x0019,0x0019,0x0019}, + {0x001A,0x001A,0x001A}, {0x001B,0x001B,0x001B}, + {0x001C,0x001C,0x001C}, {0x001D,0x001D,0x001D}, + {0x001E,0x001E,0x001E}, {0x001F,0x001F,0x001F}, + {0x0020,0x0020,0x0020}, {0x0021,0x0021,0x0021}, + {0x0022,0x0022,0x0022}, {0x0023,0x0023,0x0023}, + {0x0024,0x0024,0x0024}, {0x0025,0x0025,0x0025}, + {0x0026,0x0026,0x0026}, {0x0027,0x0027,0x0027}, + {0x0028,0x0028,0x0028}, {0x0029,0x0029,0x0029}, + {0x002A,0x002A,0x002A}, {0x002B,0x002B,0x002B}, + {0x002C,0x002C,0x002C}, {0x002D,0x002D,0x002D}, + {0x002E,0x002E,0x002E}, {0x002F,0x002F,0x002F}, + {0x0030,0x0030,0x0030}, {0x0031,0x0031,0x0031}, + {0x0032,0x0032,0x0032}, {0x0033,0x0033,0x0033}, + {0x0034,0x0034,0x0034}, {0x0035,0x0035,0x0035}, + {0x0036,0x0036,0x0036}, {0x0037,0x0037,0x0037}, + {0x0038,0x0038,0x0038}, {0x0039,0x0039,0x0039}, + {0x003A,0x003A,0x003A}, {0x003B,0x003B,0x003B}, + {0x003C,0x003C,0x003C}, {0x003D,0x003D,0x003D}, + {0x003E,0x003E,0x003E}, {0x003F,0x003F,0x003F}, + {0x0040,0x0040,0x0040}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0049,0x0131,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x005B,0x005B,0x005B}, + {0x005C,0x005C,0x005C}, {0x005D,0x005D,0x005D}, + {0x005E,0x005E,0x005E}, {0x005F,0x005F,0x005F}, + {0x0060,0x0060,0x0060}, {0x0041,0x0061,0x0041}, + {0x0042,0x0062,0x0042}, {0x0043,0x0063,0x0043}, + {0x0044,0x0064,0x0044}, {0x0045,0x0065,0x0045}, + {0x0046,0x0066,0x0046}, {0x0047,0x0067,0x0047}, + {0x0048,0x0068,0x0048}, {0x0130,0x0069,0x0049}, + {0x004A,0x006A,0x004A}, {0x004B,0x006B,0x004B}, + {0x004C,0x006C,0x004C}, {0x004D,0x006D,0x004D}, + {0x004E,0x006E,0x004E}, {0x004F,0x006F,0x004F}, + {0x0050,0x0070,0x0050}, {0x0051,0x0071,0x0051}, + {0x0052,0x0072,0x0052}, {0x0053,0x0073,0x0053}, + {0x0054,0x0074,0x0054}, {0x0055,0x0075,0x0055}, + {0x0056,0x0076,0x0056}, {0x0057,0x0077,0x0057}, + {0x0058,0x0078,0x0058}, {0x0059,0x0079,0x0059}, + {0x005A,0x007A,0x005A}, {0x007B,0x007B,0x007B}, + {0x007C,0x007C,0x007C}, {0x007D,0x007D,0x007D}, + {0x007E,0x007E,0x007E}, {0x007F,0x007F,0x007F}, + {0x0080,0x0080,0x0080}, {0x0081,0x0081,0x0081}, + {0x0082,0x0082,0x0082}, {0x0083,0x0083,0x0083}, + {0x0084,0x0084,0x0084}, {0x0085,0x0085,0x0085}, + {0x0086,0x0086,0x0086}, {0x0087,0x0087,0x0087}, + {0x0088,0x0088,0x0088}, {0x0089,0x0089,0x0089}, + {0x008A,0x008A,0x008A}, {0x008B,0x008B,0x008B}, + {0x008C,0x008C,0x008C}, {0x008D,0x008D,0x008D}, + {0x008E,0x008E,0x008E}, {0x008F,0x008F,0x008F}, + {0x0090,0x0090,0x0090}, {0x0091,0x0091,0x0091}, + {0x0092,0x0092,0x0092}, {0x0093,0x0093,0x0093}, + {0x0094,0x0094,0x0094}, {0x0095,0x0095,0x0095}, + {0x0096,0x0096,0x0096}, {0x0097,0x0097,0x0097}, + {0x0098,0x0098,0x0098}, {0x0099,0x0099,0x0099}, + {0x009A,0x009A,0x009A}, {0x009B,0x009B,0x009B}, + {0x009C,0x009C,0x009C}, {0x009D,0x009D,0x009D}, + {0x009E,0x009E,0x009E}, {0x009F,0x009F,0x009F}, + {0x00A0,0x00A0,0x00A0}, {0x00A1,0x00A1,0x00A1}, + {0x00A2,0x00A2,0x00A2}, {0x00A3,0x00A3,0x00A3}, + {0x00A4,0x00A4,0x00A4}, {0x00A5,0x00A5,0x00A5}, + {0x00A6,0x00A6,0x00A6}, {0x00A7,0x00A7,0x00A7}, + {0x00A8,0x00A8,0x00A8}, {0x00A9,0x00A9,0x00A9}, + {0x00AA,0x00AA,0x00AA}, {0x00AB,0x00AB,0x00AB}, + {0x00AC,0x00AC,0x00AC}, {0x00AD,0x00AD,0x00AD}, + {0x00AE,0x00AE,0x00AE}, {0x00AF,0x00AF,0x00AF}, + {0x00B0,0x00B0,0x00B0}, {0x00B1,0x00B1,0x00B1}, + {0x00B2,0x00B2,0x00B2}, {0x00B3,0x00B3,0x00B3}, + {0x00B4,0x00B4,0x00B4}, {0x039C,0x00B5,0x039C}, + {0x00B6,0x00B6,0x00B6}, {0x00B7,0x00B7,0x00B7}, + {0x00B8,0x00B8,0x00B8}, {0x00B9,0x00B9,0x00B9}, + {0x00BA,0x00BA,0x00BA}, {0x00BB,0x00BB,0x00BB}, + {0x00BC,0x00BC,0x00BC}, {0x00BD,0x00BD,0x00BD}, + {0x00BE,0x00BE,0x00BE}, {0x00BF,0x00BF,0x00BF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00D7,0x00D7,0x00D7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x00DF,0x00DF,0x00DF}, + {0x00C0,0x00E0,0x0041}, {0x00C1,0x00E1,0x0041}, + {0x00C2,0x00E2,0x0041}, {0x00C3,0x00E3,0x0041}, + {0x00C4,0x00E4,0x0041}, {0x00C5,0x00E5,0x0041}, + {0x00C6,0x00E6,0x00C6}, {0x00C7,0x00E7,0x0043}, + {0x00C8,0x00E8,0x0045}, {0x00C9,0x00E9,0x0045}, + {0x00CA,0x00EA,0x0045}, {0x00CB,0x00EB,0x0045}, + {0x00CC,0x00EC,0x0049}, {0x00CD,0x00ED,0x0049}, + {0x00CE,0x00EE,0x0049}, {0x00CF,0x00EF,0x0049}, + {0x00D0,0x00F0,0x00D0}, {0x00D1,0x00F1,0x004E}, + {0x00D2,0x00F2,0x004F}, {0x00D3,0x00F3,0x004F}, + {0x00D4,0x00F4,0x004F}, {0x00D5,0x00F5,0x004F}, + {0x00D6,0x00F6,0x004F}, {0x00F7,0x00F7,0x00F7}, + {0x00D8,0x00F8,0x00D8}, {0x00D9,0x00F9,0x0055}, + {0x00DA,0x00FA,0x0055}, {0x00DB,0x00FB,0x0055}, + {0x00DC,0x00FC,0x0055}, {0x00DD,0x00FD,0x0059}, + {0x00DE,0x00FE,0x00DE}, {0x0178,0x00FF,0x0059} +}; + + + +MY_UNICASE_INFO *my_unicase_turkish[256]= +{ + turk00, plane01, plane02, plane03, plane04, plane05, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F, + NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF +}; + + + /* ** Compare string against string with wildcard ** This function is used in UTF8 and UCS2 @@ -1907,20 +2089,26 @@ static int my_uni_utf8 (CHARSET_INFO *cs __attribute__((unused)) , } -static void my_caseup_utf8(CHARSET_INFO *cs, char *s, uint slen) +static uint my_caseup_utf8(CHARSET_INFO *cs, char *src, uint srclen, + char *dst, uint dstlen) { my_wc_t wc; - int res; - char *e=s+slen; + int srcres, dstres; + char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; + DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); - while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 ) + while ((src < srcend) && + (srcres= my_utf8_uni(cs, &wc, (uchar *) src, (uchar*) srcend)) > 0) { - int plane = (wc>>8) & 0xFF; - wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc; - if (res != my_uni_utf8(cs,wc,(uchar*)s,(uchar*)e)) + int plane= (wc>>8) & 0xFF; + wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc; + if ((dstres= my_uni_utf8(cs, wc, (uchar*) dst, (uchar*) dstend)) <= 0) break; - s+=res; + src+= srcres; + dst+= dstres; } + return dst - dst0; } static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, @@ -1929,6 +2117,7 @@ static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, my_wc_t wc; int res; const uchar *e=s+slen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; /* Remove end space. We have to do this to be able to compare @@ -1952,31 +2141,37 @@ static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, static void my_caseup_str_utf8(CHARSET_INFO * cs, char * s) { - my_caseup_utf8(cs, s, strlen(s)); + uint len= strlen(s); + my_caseup_utf8(cs, s, len, s, len); } -static void my_casedn_utf8(CHARSET_INFO *cs, char *s, uint slen) +static uint my_casedn_utf8(CHARSET_INFO *cs, char *src, uint srclen, + char *dst, uint dstlen) { my_wc_t wc; - int res; - char *e=s+slen; + int srcres, dstres; + char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; + DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); - while ((s < e) && (res=my_utf8_uni(cs, &wc, (uchar*)s, (uchar*)e))>0) + while ((src < srcend) && + (srcres= my_utf8_uni(cs, &wc, (uchar*) src, (uchar*)srcend)) > 0) { - int plane = (wc>>8) & 0xFF; - wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc; - if (res != my_uni_utf8(cs, wc, (uchar*)s, (uchar*)e)) - { + int plane= (wc>>8) & 0xFF; + wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc; + if ((dstres= my_uni_utf8(cs, wc, (uchar*) dst, (uchar*) dstend)) <= 0) break; - } - s+=res; + src+= srcres; + dst+= dstres; } + return dst - dst0; } static void my_casedn_str_utf8(CHARSET_INFO *cs, char * s) { - my_casedn_utf8(cs, s, strlen(s)); + uint len= strlen(s); + my_casedn_utf8(cs, s, len, s, len); } @@ -1989,6 +2184,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, my_wc_t s_wc,t_wc; const uchar *se=s+slen; const uchar *te=t+tlen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while ( s < se && t < te ) { @@ -2057,6 +2253,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, int s_res, t_res, res; my_wc_t s_wc,t_wc; const uchar *se= s+slen, *te= t+tlen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE diff_if_only_endspace_difference= 0; @@ -2144,6 +2341,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, static int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t) { + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while (s[0] && t[0]) { my_wc_t s_wc,t_wc; @@ -2228,6 +2426,7 @@ int my_wildcmp_utf8(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many) { + MY_UNICASE_INFO **uni_plane= cs->caseinfo; return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend, escape,w_one,w_many,uni_plane); } @@ -2249,6 +2448,7 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, uchar *de= dst + dstlen; uchar *de_beg= de - 1; const uchar *se = src + srclen; + MY_UNICASE_INFO **uni_plane= cs->caseinfo; while (dst < de_beg) { @@ -2367,9 +2567,12 @@ CHARSET_INFO my_charset_utf8_general_ci= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ @@ -2395,9 +2598,12 @@ CHARSET_INFO my_charset_utf8_bin= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ @@ -2561,9 +2767,12 @@ CHARSET_INFO my_charset_utf8_general_cs= NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 3, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index cb8de8f43ac..b840a58a499 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -552,7 +552,7 @@ static uchar NEAR like_range_prefix_max_win1250ch[] = { 240, 242, 242, 245, 245, 245, 245, 247, 248, 251, 251, 251, 251, 253, 254, 255, }; -#define min_sort_char '\x00' +#define min_sort_char '\x20' #define max_sort_char '\xff' /* @@ -652,9 +652,12 @@ CHARSET_INFO my_charset_cp1250_czech_ci = NULL, /* sort_order_big*/ tab_cp1250_uni, /* tab_to_uni */ idx_uni_cp1250, /* tab_from_uni */ + my_unicase_default, /* caseinfo */ NULL, /* state_map */ NULL, /* ident_map */ 2, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ 1, /* mbminlen */ 1, /* mbmaxlen */ 0, /* min_sort_char */ diff --git a/strings/decimal.c b/strings/decimal.c index 1e62333ee66..4a487f3c9b0 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1546,18 +1546,30 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, *buf1=1; to->intg++; } + /* Here we check 999.9 -> 1000 case when we need to increase intg */ + else + { + int first_dig= to->intg % DIG_PER_DEC1; + /* first_dig==0 should be handled above in the 'if' */ + if (first_dig && (*buf1 >= powers10[first_dig])) + to->intg++; + } } else { - while (unlikely(*buf1 == 0) && buf1 >= to->buf) - buf1--; - if (buf1 < to->buf) + for (;;) { - decimal_make_zero(to); - return E_DEC_OK; + if (likely(*buf1)) + break; + if (buf1-- == to->buf) + { + decimal_make_zero(to); + return E_DEC_OK; + } } } - if (scale<0) scale=0; + if (scale<0) + scale=0; done: to->frac=scale; @@ -1727,11 +1739,14 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) while (buf1 <=end1 && buf2 <= end2 && *buf1 == *buf2) buf1++, buf2++; if (buf1 <= end1) + { if (buf2 <= end2) carry= *buf2 > *buf1; else carry= 0; + } else + { if (buf2 <= end2) carry=1; else /* short-circuit everything: from1 == from2 */ @@ -1741,6 +1756,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) decimal_make_zero(to); return E_DEC_OK; } + } } if (to == 0) /* decimal_cmp() */ @@ -1937,10 +1953,18 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) { dec1 *buf= to->buf; dec1 *end= to->buf + intg0 + frac0; - for (; (buf @@ -54,11 +54,8 @@ news and information about the MySQL software. Also please see the documentation and the manual for more information. %package server -Release: %{release} Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Summary(pt_BR): MySQL: Um servidor SQL rápido e confiável. -Group(pt_BR): Aplicações/Banco_de_Dados Requires: fileutils sh-utils Provides: msqlormysql mysql-server mysql MySQL Obsoletes: MySQL mysql mysql-server @@ -88,11 +85,8 @@ If you want to access and work with the database, you have to install package "MySQL-client" as well! %package client -Release: %{release} Summary: MySQL - Client Group: Applications/Databases -Summary(pt_BR): MySQL - Cliente -Group(pt_BR): Aplicações/Banco_de_Dados Obsoletes: mysql-client Provides: mysql-client @@ -101,11 +95,7 @@ This package contains the standard MySQL clients and administration tools. %{see_base} -%description client -l pt_BR -Este pacote contém os clientes padrão para o MySQL. - %package ndb-storage -Release: %{release} Summary: MySQL - ndbcluster storage engine Group: Applications/Databases @@ -119,7 +109,6 @@ with the MySQL Max server. %{see_base} %package ndb-management -Release: %{release} Summary: MySQL - ndbcluster storage engine management Group: Applications/Databases @@ -131,7 +120,6 @@ one computer in the cluster. %{see_base} %package ndb-tools -Release: %{release} Summary: MySQL - ndbcluster storage engine basic tools Group: Applications/Databases @@ -141,7 +129,6 @@ This package contains ndbcluster storage engine basic tools. %{see_base} %package ndb-extra -Release: %{release} Summary: MySQL - ndbcluster storage engine extra tools Group: Applications/Databases @@ -152,12 +139,9 @@ They should be used with caution. %{see_base} %package bench -Release: %{release} Requires: %{name}-client perl-DBI perl Summary: MySQL - Benchmarks and test system Group: Applications/Databases -Summary(pt_BR): MySQL - Medições de desempenho -Group(pt_BR): Aplicações/Banco_de_Dados Provides: mysql-bench Obsoletes: mysql-bench @@ -166,15 +150,9 @@ This package contains MySQL benchmark scripts and data. %{see_base} -%description bench -l pt_BR -Este pacote contém medições de desempenho de scripts e dados do MySQL. - %package devel -Release: %{release} Summary: MySQL - Development header files and libraries Group: Applications/Databases -Summary(pt_BR): MySQL - Medições de desempenho -Group(pt_BR): Aplicações/Banco_de_Dados Provides: mysql-devel Obsoletes: mysql-devel @@ -184,12 +162,7 @@ necessary to develop MySQL client applications. %{see_base} -%description devel -l pt_BR -Este pacote contém os arquivos de cabeçalho (header files) e bibliotecas -necessárias para desenvolver aplicações clientes do MySQL. - %package shared -Release: %{release} Summary: MySQL - Shared libraries Group: Applications/Databases @@ -198,7 +171,6 @@ This package contains the shared libraries (*.so*) which certain languages and applications need to dynamically load and use MySQL. %package Max -Release: %{release} Summary: MySQL - server with extended functionality Group: Applications/Databases Provides: mysql-Max @@ -222,12 +194,9 @@ the standard MySQL package. Please note that this is a dynamically linked binary! %package embedded -Release: %{release} Requires: %{name}-devel Summary: MySQL - embedded library Group: Applications/Databases -Summary(pt_BR): MySQL - Medições de desempenho -Group(pt_BR): Aplicações/Banco_de_Dados Obsoletes: mysql-embedded %description embedded @@ -271,7 +240,7 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --libdir=%{_libdir} \ --sysconfdir=%{_sysconfdir} \ --datadir=%{_datadir} \ - --localstatedir=/var/lib/mysql \ + --localstatedir=%{mysqldatadir} \ --infodir=%{_infodir} \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ @@ -311,7 +280,7 @@ mkdir -p $RBR%{_libdir}/mysql PATH=${MYSQL_BUILD_PATH:-/bin:/usr/bin} export PATH -# Build the 4.0 Max binary (includes BDB and UDFs and therefore +# Build the Max binary (includes BDB and UDFs and therefore # cannot be linked statically against the patched glibc) # Use gcc for C and C++ code (to avoid a dependency on libstdc++ and @@ -336,8 +305,7 @@ BuildMySQL "--enable-shared \ --with-comment=\"MySQL Community Edition - Max (GPL)\" \ --with-server-suffix='-Max'" -# Save everything for debug -# tar cf $RBR/all.tar . +make test # Save mysqld-max mv sql/mysqld sql/mysqld-max @@ -363,6 +331,7 @@ fi # Save libraries (cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*) (cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*) +(cd ndb/src/.libs; tar rf $RBR/shared-libs.tar *.so*) # Now clean up make clean @@ -387,13 +356,15 @@ BuildMySQL "--disable-shared \ --without-openssl" nm --numeric-sort sql/mysqld > sql/mysqld.sym +make test + %install RBR=$RPM_BUILD_ROOT MBD=$RPM_BUILD_DIR/mysql-%{mysql_version} # Ensure that needed directories exists install -d $RBR%{_sysconfdir}/{logrotate.d,init.d} -install -d $RBR/var/lib/mysql/mysql +install -d $RBR%{mysqldatadir}/mysql install -d $RBR%{_datadir}/{sql-bench,mysql-test} install -d $RBR%{_includedir} install -d $RBR%{_libdir} @@ -447,7 +418,7 @@ then fi %post server -mysql_datadir=/var/lib/mysql +mysql_datadir=%{mysqldatadir} # Create data directory if needed if test ! -d $mysql_datadir; then mkdir -m755 $mysql_datadir; fi @@ -467,17 +438,17 @@ fi # Create a MySQL user. Do not report any problems if it already # exists. This is redhat specific and should be handled more portable -useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" mysql 2> /dev/null || true +useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" %{mysqld_user} 2> /dev/null || true # Change permissions so that the user that will run the MySQL daemon # owns all database files. -chown -R mysql $mysql_datadir +chown -R %{mysqld_user} $mysql_datadir # Initiate databases -mysql_install_db --rpm --user=mysql +%{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} # Change permissions again to fix any new files. -chown -R mysql $mysql_datadir +chown -R %{mysqld_user} $mysql_datadir # Fix permissions for the permission database so that only the user # can read them. @@ -661,6 +632,8 @@ fi %{_libdir}/mysql/libmysqlclient_r.la %{_libdir}/mysql/libmystrings.a %{_libdir}/mysql/libmysys.a +%{_libdir}/mysql/libndbclient.a +%{_libdir}/mysql/libndbclient.la %{_libdir}/mysql/libvio.a %files shared @@ -672,6 +645,7 @@ fi %defattr(-, root, root, 0755) %attr(-, root, root) %{_datadir}/sql-bench %attr(-, root, root) %{_datadir}/mysql-test +%attr(755, rott, root) %{_bindir}/mysql_client_test %attr(755, root, root) %{_bindir}/mysqltestmanager %attr(755, root, root) %{_bindir}/mysqltestmanager-pwgen %attr(755, root, root) %{_bindir}/mysqltestmanagerc @@ -689,6 +663,18 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Jun 06 2005 Lenz Grimmer + +- added mysql_client_test to the "bench" subpackage (BUG 10676) +- added the libndbclient static and shared libraries (BUG 10676) + +* Wed Jun 01 2005 Lenz Grimmer + +- use "mysqldatadir" variable instead of hard-coding the path multiple times +- use the "mysqld_user" variable on all occasions a user name is referenced +- removed (incomplete) Brazilian translations +- removed redundant release tags from the subpackage descriptions + * Wed May 25 2005 Joerg Bruehe - Added a "make clean" between separate calls to "BuildMySQL". diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 002076afd90..b6ca4996c70 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13145,6 +13145,67 @@ static void test_bug9643() myquery(rc); } +/* + Check that proper cleanups are done for prepared statement when + fetching thorugh a cursor. +*/ + +static void test_bug10729() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + char a[21]; + int rc; + const char *stmt_text; + int i= 0; + char *name_array[3]= { "aaa", "bbb", "ccc" }; + ulong type; + + myheader("test_bug10729"); + + mysql_query(mysql, "drop table if exists t1"); + mysql_query(mysql, "create table t1 (id integer not null primary key," + "name VARCHAR(20) NOT NULL)"); + rc= mysql_query(mysql, "insert into t1 (id, name) values " + "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + + type= (ulong) CURSOR_TYPE_READ_ONLY; + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); + check_execute(stmt, rc); + stmt_text= "select name from t1"; + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + + bzero(bind, sizeof(bind)); + bind[0].buffer_type= MYSQL_TYPE_STRING; + bind[0].buffer= (void*) a; + bind[0].buffer_length= sizeof(a); + mysql_stmt_bind_result(stmt, bind); + + for (i= 0; i < 3; i++) + { + int row_no= 0; + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + while ((rc= mysql_stmt_fetch(stmt)) == 0) + { + DIE_UNLESS(strcmp(a, name_array[row_no]) == 0); + if (!opt_silent) + printf("%d: %s\n", row_no, a); + ++row_no; + } + DIE_UNLESS(rc == MYSQL_NO_DATA); + } + rc= mysql_stmt_close(stmt); + DIE_UNLESS(rc == 0); + + rc= mysql_query(mysql, "drop table t1"); + myquery(rc); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -13377,6 +13438,7 @@ static struct my_tests_st my_tests[]= { { "test_bug9520", test_bug9520 }, { "test_bug9478", test_bug9478 }, { "test_bug9643", test_bug9643 }, + { "test_bug10729", test_bug10729 }, { 0, 0 } };