From b3e68622ba2e99a386a1c2fa9905cd588864f322 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Sep 2003 19:23:01 +0200 Subject: [PATCH 01/50] fixed: thread lock-up on a FLASH TABLE when another thread has an open handler Bug#1204 --- sql/sql_handler.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index b0d8b18dd17..a19fcdc2d73 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -34,7 +34,7 @@ The second is to be freeed only on thread end. mysql_ha_open should then do { handler_items=concat(handler_items, free_list); free_list=0; } - But !!! do_cammand calls free_root at the end of every query and frees up + But !!! do_command calls free_root at the end of every query and frees up all the sql_alloc'ed memory. It's harder to work around... */ @@ -73,7 +73,11 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) if (*ptr) { VOID(pthread_mutex_lock(&LOCK_open)); - close_thread_table(thd, ptr); + if (close_thread_table(thd, ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } VOID(pthread_mutex_unlock(&LOCK_open)); } else @@ -90,8 +94,11 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) int mysql_ha_closeall(THD *thd, TABLE_LIST *tables) { TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0); - if (*ptr) - close_thread_table(thd, ptr); + if (*ptr && close_thread_table(thd, ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } return 0; } From eb7dc66717e839f10a45834a09aa7683c4bae2f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Sep 2003 18:54:22 +0200 Subject: [PATCH 02/50] make mysqld to respect socket/port options of mysqld_safe command line and [mysqld_safe] section in my.cnf, even if they are also specified in [mysql] section. --- scripts/mysqld_safe.sh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 1c056e963cb..ece4ba098f4 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -51,9 +51,9 @@ parse_arguments() { ;; # these two might have been set in a [mysqld_safe] section of my.cnf - # they get passed via environment variables to mysqld_safe - --socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--socket=;;"` ;; - --port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--port=;;"` ;; + # they are added to mysqld command line to override settings from my.cnf + --socket=*) mysql_unix_port=`echo "$arg" | sed -e "s;--socket=;;"` ;; + --port=*) mysql_tcp_port=`echo "$arg" | sed -e "s;--port=;;"` ;; # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])! --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;; @@ -114,8 +114,7 @@ else ledir=@libexecdir@ fi -MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@} -MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@} +safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}} user=@MYSQLD_USER@ niceness=0 @@ -171,9 +170,14 @@ else fi test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err -export MYSQL_UNIX_PORT -export MYSQL_TCP_PORT - +if test -n "$mysql_unix_port" +then + args="--socket=$mysql_unix_port $args" +fi +if test -n "$mysql_tcp_port" +then + args="--port=$mysql_tcp_port $args" +fi if test $niceness -eq 0 then @@ -296,7 +300,7 @@ echo "Starting $MYSQLD daemon with databases from $DATADIR" echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log while true do - rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety + rm -f $safe_mysql_unix_port $pid_file # Some extra safety if test -z "$args" then $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1 From 206168cd0a1e22ad550764465c1af7abbdb63b66 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Sep 2003 21:35:47 +0200 Subject: [PATCH 03/50] typo fixed (bug #1390 - incorrect mysql_config output) --- scripts/mysql_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index 3cc5b3a5016..f7c4b4ff381 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -62,7 +62,7 @@ get_full_path () { case $1 in /*) echo "$1";; - ./*) tmp=`pwd`/$1; echo $tmp | sed -e 's;/./;/;' ;; + ./*) tmp=`pwd`/$1; echo $tmp | sed -e 's;/\./;/;' ;; *) which $1 ;; esac } From 907e0555834de14fa1aec538b217dd1f1c3ff23f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2003 11:21:17 +0200 Subject: [PATCH 04/50] enum options renamed to avoid possible name conflicts --- client/client_priv.h | 2 +- myisam/myisamchk.c | 2 +- sql/mysqld.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 85c99951532..5029f219494 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -26,7 +26,7 @@ /* We have to define 'enum options' identical in all files to keep OS2 happy */ -enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, +enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE, OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 83edadf153f..b7627fc59fd 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -144,7 +144,7 @@ int main(int argc, char **argv) #endif } /* main */ -enum options { +enum options_mc { OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS, OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index bcf115feccc..cc870ed3e36 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3130,7 +3130,7 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg) ** handle start options ******************************************************************************/ -enum options { +enum options_mysqld { OPT_ISAM_LOG=256, OPT_SKIP_NEW, OPT_SKIP_GRANT, OPT_SKIP_LOCK, OPT_ENABLE_LOCK, OPT_USE_LOCKING, From 08a08a67dbde78258e46b0d9bcd387c8419b8fcd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 14:11:16 +0200 Subject: [PATCH 05/50] fix_max_connections to resize alarm_queue (Bug #1435) include/queues.h: resize_queue() include/thr_alarm.h: resize_thr_alarm() to resize alarm_queue mysys/queues.c: resize_queue() mysys/thr_alarm.c: resize_thr_alarm() to resize alarm_queue --- include/queues.h | 1 + include/thr_alarm.h | 1 + mysys/queues.c | 24 +++++++++++++++++------- mysys/thr_alarm.c | 10 ++++++++++ sql/set_var.cc | 21 +++++++++++++++------ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/queues.h b/include/queues.h index 699705d0869..ac15b09719b 100644 --- a/include/queues.h +++ b/include/queues.h @@ -49,6 +49,7 @@ int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key, int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key, pbool max_at_top, queue_compare compare, void *first_cmp_arg); +int resize_queue(QUEUE *queue, uint max_elements); void delete_queue(QUEUE *queue); void queue_insert(QUEUE *queue,byte *element); byte *queue_remove(QUEUE *queue,uint idx); diff --git a/include/thr_alarm.h b/include/thr_alarm.h index 8ff4472f700..a54c192b1ed 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -100,6 +100,7 @@ typedef struct st_alarm { #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A)!= 0) void init_thr_alarm(uint max_alarm); +void resize_thr_alarm(uint max_alarms); my_bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff); void thr_alarm_kill(pthread_t thread_id); void thr_end_alarm(thr_alarm_t *alarmed); diff --git a/mysys/queues.c b/mysys/queues.c index fe642131d74..ae69684f9e4 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -44,25 +44,35 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key, } /* - Reinitialize queue for new usage; Note that you can't currently resize - the number of elements! If you need this, fix it :) + Reinitialize queue for new usage; */ - int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key, pbool max_at_top, int (*compare) (void *, byte *, byte *), void *first_cmp_arg) { DBUG_ENTER("reinit_queue"); - if (queue->max_elements < max_elements) - /* It's real easy to do realloc here, just don't want to bother */ - DBUG_RETURN(my_errno=EE_OUTOFMEMORY); - queue->elements=0; queue->compare=compare; queue->first_cmp_arg=first_cmp_arg; queue->offset_to_key=offset_to_key; queue->max_at_top= max_at_top ? (-1 ^ 1) : 0; + resize_queue(queue, max_elements); + DBUG_RETURN(0); +} + +int resize_queue(QUEUE *queue, uint max_elements) +{ + byte **new_root; + DBUG_ENTER("resize_queue"); + if (queue->max_elements == max_elements) + DBUG_RETURN(0); + if ((new_root= (byte **) my_realloc((void *)queue->root, + (max_elements+1)*sizeof(void*), MYF(MY_WME))) == 0) + DBUG_RETURN(1); + set_if_smaller(queue->elements, max_elements); + queue->max_elements=max_elements; + queue->root=new_root; DBUG_RETURN(0); } diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 2289f8208bc..5d2ac8b0099 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -120,6 +120,16 @@ void init_thr_alarm(uint max_alarms) DBUG_VOID_RETURN; } +void resize_thr_alarm(uint max_alarms) +{ + pthread_mutex_lock(&LOCK_alarm); + /* it's ok not to shrink the queue sometimes */ + if (alarm_queue.elements < max_alarms) + resize_queue(&alarm_queue,max_alarms+1); + pthread_mutex_unlock(&LOCK_alarm); + return; +} + /* Request alarm after sec seconds. diff --git a/sql/set_var.cc b/sql/set_var.cc index 8c0859fbca4..3388fbc1932 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -86,6 +86,7 @@ static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type); static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); static void fix_max_binlog_size(THD *thd, enum_var_type type); static void fix_max_relay_log_size(THD *thd, enum_var_type type); +static void fix_max_connections(THD *thd, enum_var_type type); /* Variable definition list @@ -147,7 +148,8 @@ sys_var_long_ptr sys_max_binlog_size("max_binlog_size", &max_binlog_size, fix_max_binlog_size); sys_var_long_ptr sys_max_connections("max_connections", - &max_connections); + &max_connections, + fix_max_connections); sys_var_long_ptr sys_max_connect_errors("max_connect_errors", &max_connect_errors); sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads", @@ -636,7 +638,7 @@ static void fix_max_join_size(THD *thd, enum_var_type type) thd->options&= ~OPTION_BIG_SELECTS; } } - + /* If one doesn't use the SESSION modifier, the isolation level @@ -689,7 +691,7 @@ static void fix_key_buffer_size(THD *thd, enum_var_type type) } -void fix_delay_key_write(THD *thd, enum_var_type type) +extern void fix_delay_key_write(THD *thd, enum_var_type type) { switch ((enum_delay_key_write) delay_key_write_options) { case DELAY_KEY_WRITE_NONE: @@ -705,7 +707,7 @@ void fix_delay_key_write(THD *thd, enum_var_type type) } } -void fix_max_binlog_size(THD *thd, enum_var_type type) +static void fix_max_binlog_size(THD *thd, enum_var_type type) { DBUG_ENTER("fix_max_binlog_size"); DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", @@ -716,7 +718,7 @@ void fix_max_binlog_size(THD *thd, enum_var_type type) DBUG_VOID_RETURN; } -void fix_max_relay_log_size(THD *thd, enum_var_type type) +static void fix_max_relay_log_size(THD *thd, enum_var_type type) { DBUG_ENTER("fix_max_relay_log_size"); DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", @@ -726,6 +728,13 @@ void fix_max_relay_log_size(THD *thd, enum_var_type type) DBUG_VOID_RETURN; } +#include +static void +fix_max_connections(THD *thd, enum_var_type type) +{ + resize_thr_alarm(max_connections); +} + bool sys_var_long_ptr::update(THD *thd, set_var *var) { ulonglong tmp= var->value->val_int(); @@ -1478,7 +1487,7 @@ int set_var::check(THD *thd) { my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name); return -1; - } + } return var->check(thd, this) ? -1 : 0; } From e86fc82cf27303a0fe165b4567291ae228491302 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 20:02:27 +0200 Subject: [PATCH 06/50] bug #1434 (and related issues) --- mysql-test/t/create.test | 22 +++++++++++++++++++++- sql/sql_class.h | 4 ++-- sql/sql_insert.cc | 14 ++++++++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index d46807f1dca..815aad560b1 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -129,8 +129,28 @@ insert into t1 values ("a", 1), ("b", 2); drop table t1; # -# Bug # 801 +# Bug #801 # create table t1 select x'4132'; drop table t1; + +# +# bug #1434 +# + +create table t1 select 1,2,3; +create table if not exists t1 select 1,2; +--error 1136 +create table if not exists t1 select 1,2,3,4; +create table if not exists t1 select 1; +select * from t1; +drop table t1; +create table t1 select 1,2,3; +create table if not exists t1 select 1,2; +--error 1136 +create table if not exists t1 select 1,2,3,4; +create table if not exists t1 select 1; +select * from t1; +drop table t1; + diff --git a/sql/sql_class.h b/sql/sql_class.h index 2ed9cb7b877..bf626eb7d92 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -703,6 +703,7 @@ class select_create: public select_insert { HA_CREATE_INFO *create_info; MYSQL_LOCK *lock; Field **field; + my_bool do_not_drop; public: select_create (const char *db_name, const char *table_name, HA_CREATE_INFO *create_info_par, @@ -711,8 +712,7 @@ public: List &select_fields,enum_duplicates duplic) :select_insert (NULL, &select_fields, duplic), db(db_name), name(table_name), extra_fields(&fields_par),keys(&keys_par), - create_info(create_info_par), - lock(0) + create_info(create_info_par), lock(0), do_not_drop(0) {} int prepare(List &list); bool send_data(List &values); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0a83358e8c6..ad08ad6ccd6 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1438,6 +1438,15 @@ select_create::prepare(List &values) if (!table) DBUG_RETURN(-1); // abort() deletes table + if (table->fields < values.elements) + { + do_not_drop=1; + my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, + ER(ER_WRONG_VALUE_COUNT_ON_ROW), + MYF(0),1); + DBUG_RETURN(-1); + } + /* First field to copy */ field=table->field+table->fields - values.elements; @@ -1498,7 +1507,7 @@ bool select_create::send_eof() */ if (!table->tmp_table) hash_delete(&open_cache,(byte*) table); - lock=0; + lock=0; table=0; VOID(pthread_mutex_unlock(&LOCK_open)); } @@ -1519,7 +1528,8 @@ void select_create::abort() enum db_type table_type=table->db_type; if (!table->tmp_table) hash_delete(&open_cache,(byte*) table); - quick_rm_table(table_type,db,name); + if (!do_not_drop) + quick_rm_table(table_type,db,name); table=0; } VOID(pthread_mutex_unlock(&LOCK_open)); From 93e1bbf671d775095fc0d7600bd817e85131a5f2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 20:11:39 +0200 Subject: [PATCH 07/50] results updated --- mysql-test/r/create.result | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index e6192eb6ccb..51952009f08 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -178,3 +178,25 @@ Column 'k1' cannot be null drop table t1; create table t1 select x'4132'; drop table t1; +create table t1 select 1,2,3; +create table if not exists t1 select 1,2; +create table if not exists t1 select 1,2,3,4; +Column count doesn't match value count at row 1 +create table if not exists t1 select 1; +select * from t1; +1 2 3 +1 2 3 +0 1 2 +0 0 1 +drop table t1; +create table t1 select 1,2,3; +create table if not exists t1 select 1,2; +create table if not exists t1 select 1,2,3,4; +Column count doesn't match value count at row 1 +create table if not exists t1 select 1; +select * from t1; +1 2 3 +1 2 3 +0 1 2 +0 0 1 +drop table t1; From 743bc7cf357031be28b848acce7ddced9f76dcbf Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Oct 2003 12:35:24 +0200 Subject: [PATCH 08/50] - added make_sharedlib_distribution.sh to the source distribution --- scripts/Makefile.am | 4 +- scripts/make_sharedlib_distribution.sh | 117 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 scripts/make_sharedlib_distribution.sh diff --git a/scripts/Makefile.am b/scripts/Makefile.am index c83b0d0b043..93a6666df39 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -36,6 +36,7 @@ bin_SCRIPTS = @server_scripts@ \ mysqld_multi EXTRA_SCRIPTS = make_binary_distribution.sh \ + make_sharedlib_distribution.sh \ make_win_src_distribution.sh \ msql2mysql.sh \ mysql_config.sh \ @@ -60,12 +61,13 @@ EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ mysqlbug -pkgdata_DATA = make_binary_distribution +pkgdata_DATA = make_binary_distribution make_sharedlib_distribution # mysqlbug should be distributed built so that people can report build # failures with it. CLEANFILES = @server_scripts@ \ make_binary_distribution \ + make_sharedlib_distribution \ make_win_src_distribution \ msql2mysql \ mysql_config \ diff --git a/scripts/make_sharedlib_distribution.sh b/scripts/make_sharedlib_distribution.sh new file mode 100644 index 00000000000..4104a315296 --- /dev/null +++ b/scripts/make_sharedlib_distribution.sh @@ -0,0 +1,117 @@ +#!/bin/sh +# The default path should be /usr/local + +# Get some info from configure +# chmod +x ./scripts/setsomevars + +machine=@MACHINE_TYPE@ +system=@SYSTEM_TYPE@ +version=@VERSION@ +export machine system version +SOURCE=`pwd` +CP="cp -p" +MV="mv" + +STRIP=1 +DEBUG=0 +SILENT=0 +TMP=/tmp +SUFFIX="" + +parse_arguments() { + for arg do + case "$arg" in + --debug) DEBUG=1;; + --tmp=*) TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;; + --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;; + --no-strip) STRIP=0 ;; + --silent) SILENT=1 ;; + *) + echo "Unknown argument '$arg'" + exit 1 + ;; + esac + done +} + +parse_arguments "$@" + +BASE=$TMP/my_dist$SUFFIX + +if [ -d $BASE ] ; then + rm -r -f $BASE +fi + +mkdir -p $BASE/lib + +for i in \ + libmysql/.libs/libmysqlclient.so* \ + libmysql_r/.libs/libmysqlclient_r.so* +do + if [ -f $i ] + then + $CP $i $BASE/lib + fi +done + +# Change the distribution to a long descriptive name +NEW_NAME=mysql-shared-$version-$system-$machine$SUFFIX +BASE2=$TMP/$NEW_NAME +rm -r -f $BASE2 +mv $BASE $BASE2 +BASE=$BASE2 + +#if we are debugging, do not do tar/gz +if [ x$DEBUG = x1 ] ; then + exit +fi + +# This is needed to prefer GNU tar instead of tar because tar can't +# always handle long filenames + +PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' ` +which_1 () +{ + for cmd + do + for d in $PATH_DIRS + do + for file in $d/$cmd + do + if test -x $file -a ! -d $file + then + echo $file + exit 0 + fi + done + done + done + exit 1 +} + +# +# Create the result tar file +# + +tar=`which_1 gnutar gtar` +if test "$?" = "1" -o "$tar" = "" +then + tar=tar +fi + +echo "Using $tar to create archive" +cd $TMP + +OPT=cvf +if [ x$SILENT = x1 ] ; then + OPT=cf +fi + +$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME +cd $SOURCE +echo "Compressing archive" +gzip -9 $NEW_NAME.tar +echo "Removing temporary directory" +rm -r -f $BASE + +echo "$NEW_NAME.tar.gz created" From 6a90df8b0cfdd003593f585f95b5d3eadce8c7cb Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Oct 2003 17:15:59 -0400 Subject: [PATCH 09/50] fixed temp directory for mysqlbinlog (was wrong on solaris) --- mysql-test/t/mysqlbinlog.test | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index c5e1be37b01..e22a37fabfd 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -39,28 +39,28 @@ select "--- Local --" as ""; # --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.001 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ $MYSQL_TEST_DIR/var/log/master-bin.001 # this should not fail but shouldn't produce any working statements --disable_query_log select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ $MYSQL_TEST_DIR/var/log/master-bin.002 # this should show almost nothing --disable_query_log select "--- --database --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --database=nottest $MYSQL_TEST_DIR/var/log/master-bin.001 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --database=nottest $MYSQL_TEST_DIR/var/log/master-bin.001 # this test for position option --disable_query_log select "--- --position --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --position=27 $MYSQL_TEST_DIR/var/log/master-bin.002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=27 $MYSQL_TEST_DIR/var/log/master-bin.002 # These are tests for remote binlog. # They should return the same as previous test. @@ -76,28 +76,28 @@ select "--- Remote --" as ""; # This is broken now # By the way it seems that remote version fetches all events with name >= master-bin.001 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.001 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.001 # This is broken too --disable_query_log select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 # And this too ! (altough it is documented) --disable_query_log select "--- --database --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.001 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.001 # Strangely but this works --disable_query_log select "--- --position --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 # clean up drop table t1; From 9b1944382ae27acef6d0f2ca42770f638016587d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Oct 2003 14:55:33 +0200 Subject: [PATCH 10/50] Tiny cleanup after the push of WL#1098 "Seconds_behind_master in SHOW SLAVE STATUS": a better comment, and replacing an assignment by an equivalent simpler one. sql/log_event.cc: a better comment, and replacing an assignment by an equivalent simpler one. --- sql/log_event.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index ebbd0d1b373..62dc56e7fd2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -327,8 +327,12 @@ int Log_event::exec_event(struct st_relay_log_info* rli) { rli->inc_group_relay_log_pos(get_event_len(),log_pos); flush_relay_log_info(rli); - /* if this is a fake rotate, don't record the timestamp */ - rli->last_master_timestamp= (when) ? when : 0; + /* + Note that Rotate_log_event::exec_event() does not call this function, + so there is no chance that a fake rotate event resets + last_master_timestamp. + */ + rli->last_master_timestamp= when; } } return 0; From 7e1a1032e826e867e41cdd3361b40fac33956543 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Oct 2003 17:40:38 +0200 Subject: [PATCH 11/50] Make the slave die if master is 5.0. Indeed, 5.0 masters send a Format_description_log_event (or maybe it will be named Description_log_event) which is not recognized by 4.0, so a 4.0 can't be a slave of 5.0. We detect it early to produce a helpful message instead of "corrupted relay log" later. sql/slave.cc: Make the slave die if master is 5.0. --- sql/slave.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 10d451a88bc..12698c8eda4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1017,11 +1017,12 @@ static int check_master_version(MYSQL* mysql, MASTER_INFO* mi) BINLOG_FORMAT_323_GEQ_57 ; break; case '4': - case '5': mi->old_format = BINLOG_FORMAT_CURRENT; break; default: - errmsg = "Master reported unrecognized MySQL version"; + /* 5.0 is not supported */ + errmsg = "Master reported an unrecognized MySQL version. Note that 4.0 \ +slaves can't replicate a 5.0 or newer master."; break; } From bc8f801bf0f239b85ee95ea5410915f0f5424fc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Oct 2003 18:16:15 +0200 Subject: [PATCH 12/50] Don't show Slave_IO_State in the testsuite (replace it with #) because it can't be predicted. I manually edited rpl_openssl.result because the test is skipped on my machine. Hope it's correct. mysql-test/r/rpl000015.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_error_ignored_table.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_flush_log_loop.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_loaddata.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_log.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_log_pos.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_max_relay_size.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_openssl.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_replicate_do.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_reset_slave.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_rotate_logs.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_trunc_binlog.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/r/rpl_until.result: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl000015.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_empty_master_crash.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_error_ignored_table.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_flush_log_loop.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_loaddata.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_log.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_log_pos.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_max_relay_size.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_openssl.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_redirect.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_replicate_do.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_reset_slave.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_rotate_logs.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_trunc_binlog.test: Don't show Slave_IO_State because it can't be predicted. mysql-test/t/rpl_until.test: Don't show Slave_IO_State because it can't be predicted. --- mysql-test/r/rpl000015.result | 6 +++--- mysql-test/r/rpl_error_ignored_table.result | 2 +- mysql-test/r/rpl_flush_log_loop.result | 2 +- mysql-test/r/rpl_loaddata.result | 6 +++--- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_log_pos.result | 8 ++++---- mysql-test/r/rpl_max_relay_size.result | 12 ++++++------ mysql-test/r/rpl_openssl.result | 8 ++++---- mysql-test/r/rpl_replicate_do.result | 2 +- mysql-test/r/rpl_reset_slave.result | 8 ++++---- mysql-test/r/rpl_rotate_logs.result | 6 +++--- mysql-test/r/rpl_trunc_binlog.result | 2 +- mysql-test/r/rpl_until.result | 8 ++++---- mysql-test/t/rpl000015.test | 8 ++++---- mysql-test/t/rpl_empty_master_crash.test | 2 +- mysql-test/t/rpl_error_ignored_table.test | 2 +- mysql-test/t/rpl_flush_log_loop.test | 2 +- mysql-test/t/rpl_loaddata.test | 6 +++--- mysql-test/t/rpl_log.test | 2 +- mysql-test/t/rpl_log_pos.test | 8 ++++---- mysql-test/t/rpl_max_relay_size.test | 12 ++++++------ mysql-test/t/rpl_openssl.test | 4 ++-- mysql-test/t/rpl_redirect.test | 2 +- mysql-test/t/rpl_replicate_do.test | 2 +- mysql-test/t/rpl_reset_slave.test | 8 ++++---- mysql-test/t/rpl_rotate_logs.test | 6 +++--- mysql-test/t/rpl_trunc_binlog.test | 2 +- mysql-test/t/rpl_until.test | 8 ++++---- 28 files changed, 73 insertions(+), 73 deletions(-) diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result index e96fc49f09e..98ad998f2ed 100644 --- a/mysql-test/r/rpl000015.result +++ b/mysql-test/r/rpl000015.result @@ -8,16 +8,16 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File change master to master_host='127.0.0.1'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 slave-relay-bin.000001 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # +# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 slave-relay-bin.000001 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # drop table if exists t1; create table t1 (n int); insert into t1 values (10),(45),(90); diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result index 1f537850231..2baa69d4aad 100644 --- a/mysql-test/r/rpl_error_ignored_table.result +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -9,7 +9,7 @@ insert into t1 values (1),(1); ERROR 23000: Duplicate entry '1' for key 1 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 213 slave-relay-bin.000002 257 master-bin.000001 Yes Yes test.t1 0 0 213 257 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 213 slave-relay-bin.000002 257 master-bin.000001 Yes Yes test.t1 0 0 213 257 None 0 No # show tables like 't1'; Tables_in_test (t1) drop table t1; diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index 5b71a68bace..e0f85210616 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -14,4 +14,4 @@ start slave; flush logs; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 79 relay-log.000002 4 slave-bin.000001 Yes Yes 0 0 79 4 None 0 No # +# 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 79 relay-log.000002 4 slave-bin.000001 Yes Yes 0 0 79 4 None 0 No # diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index b9546d7f381..092b14cacfb 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -33,7 +33,7 @@ set global sql_slave_skip_counter=1; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1311 slave-relay-bin.000002 1355 master-bin.000001 Yes Yes 0 0 1311 1355 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1311 slave-relay-bin.000002 1355 master-bin.000001 Yes Yes 0 0 1311 1355 None 0 No # set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -43,7 +43,7 @@ change master to master_user='test'; change master to master_user='root'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1442 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 1442 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1442 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 1442 4 None 0 No # set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -54,7 +54,7 @@ stop slave; reset slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # reset master; create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), unique(day)); diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 12a45a2b4ad..6860067a2d4 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -96,6 +96,6 @@ slave-bin.000002 62 Query 1 62 use `test`; insert into t1 values (1) slave-bin.000002 122 Query 1 122 use `test`; drop table t1 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000003 214 master-bin.000002 Yes Yes 0 0 276 214 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000003 214 master-bin.000002 Yes Yes 0 0 276 214 None 0 No # show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index 7209cc19a57..098fb056cc6 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -9,7 +9,7 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # stop slave; change master to master_log_pos=73; start slave; @@ -17,17 +17,17 @@ stop slave; change master to master_log_pos=73; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 73 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 73 4 None 0 No # start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 48 master-bin.000001 No Yes 0 0 73 48 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 48 master-bin.000001 No Yes 0 0 73 48 None 0 No # stop slave; change master to master_log_pos=173; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 173 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 173 4 None 0 No # show master status; File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index d678ad213bf..2d08ca6e3a3 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -16,7 +16,7 @@ select @@global.max_relay_log_size; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000014 1221 master-bin.000001 Yes Yes 0 0 50477 1221 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000014 1221 master-bin.000001 Yes Yes 0 0 50477 1221 None 0 No # stop slave; reset slave; set global max_relay_log_size=(5*4096); @@ -26,7 +26,7 @@ select @@global.max_relay_log_size; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000004 9457 master-bin.000001 Yes Yes 0 0 50477 9457 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000004 9457 master-bin.000001 Yes Yes 0 0 50477 9457 None 0 No # stop slave; reset slave; set global max_relay_log_size=0; @@ -36,25 +36,25 @@ select @@global.max_relay_log_size; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000008 1283 master-bin.000001 Yes Yes 0 0 50477 1283 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000008 1283 master-bin.000001 Yes Yes 0 0 50477 1283 None 0 No # stop slave; reset slave; flush logs; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # reset slave; start slave; flush logs; create table t1 (a int); show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50535 slave-relay-bin.000009 62 master-bin.000001 Yes Yes 0 0 50535 62 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50535 slave-relay-bin.000009 62 master-bin.000001 Yes Yes 0 0 50535 62 None 0 No # flush logs; drop table t1; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50583 slave-relay-bin.000010 52 master-bin.000001 Yes Yes 0 0 50583 52 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50583 slave-relay-bin.000010 52 master-bin.000001 Yes Yes 0 0 50583 52 None 0 No # flush logs; show master status; File Position Binlog_do_db Binlog_ignore_db diff --git a/mysql-test/r/rpl_openssl.result b/mysql-test/r/rpl_openssl.result index 880facfe075..7ce3e2cd0e4 100644 --- a/mysql-test/r/rpl_openssl.result +++ b/mysql-test/r/rpl_openssl.result @@ -19,12 +19,12 @@ select * from t1; t 1 show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key -127.0.0.1 replssl MASTER_MYPORT 1 master-bin.000001 289 slave-relay-bin.000001 108 master-bin.000001 Yes Yes 0 0 289 108 None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem +Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +# 127.0.0.1 replssl MASTER_MYPORT 1 master-bin.000001 289 slave-relay-bin.000001 108 master-bin.000001 Yes Yes 0 0 289 108 None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # stop slave; change master to master_user='root',master_password='', master_ssl=0; start slave; drop table t1; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key -127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 337 slave-relay-bin.000001 96 master-bin.000001 Yes Yes 0 0 337 96 None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem +Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 337 slave-relay-bin.000001 96 master-bin.000001 Yes Yes 0 0 337 96 None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result index f7164f8a636..271ee9cefa1 100644 --- a/mysql-test/r/rpl_replicate_do.result +++ b/mysql-test/r/rpl_replicate_do.result @@ -28,4 +28,4 @@ ERROR 42S02: Table 'test.t11' doesn't exist drop table if exists t1,t2,t11; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1325 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1325 None 0 No # diff --git a/mysql-test/r/rpl_reset_slave.result b/mysql-test/r/rpl_reset_slave.result index 401569ccbce..8887462389d 100644 --- a/mysql-test/r/rpl_reset_slave.result +++ b/mysql-test/r/rpl_reset_slave.result @@ -6,17 +6,17 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # stop slave; change master to master_user='test'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 test MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 79 4 None 0 No # +# 127.0.0.1 test MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 79 4 None 0 No # reset slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master - 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 16a0ef4cb71..4e31164f2ec 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -16,7 +16,7 @@ create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 60 master-bin.000001 417 slave-relay-bin.000001 461 master-bin.000001 Yes Yes 0 0 417 461 None 0 No # +# 127.0.0.1 root MASTER_PORT 60 master-bin.000001 417 slave-relay-bin.000001 461 master-bin.000001 Yes Yes 0 0 417 461 None 0 No # select * from t1; s Could not break slave @@ -57,7 +57,7 @@ master-bin.000003 insert into t2 values (65); show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 60 master-bin.000003 290 slave-relay-bin.000001 1088 master-bin.000003 Yes Yes 0 0 290 1088 None 0 No # +# 127.0.0.1 root MASTER_PORT 60 master-bin.000003 290 slave-relay-bin.000001 1088 master-bin.000003 Yes Yes 0 0 290 1088 None 0 No # select * from t2; m 34 @@ -81,7 +81,7 @@ a testing temporary tables part 2 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 60 master-bin.000004 2886 slave-relay-bin.000001 7891 master-bin.000004 Yes Yes 0 0 2886 7891 None 0 No # +# 127.0.0.1 root MASTER_PORT 60 master-bin.000004 2886 slave-relay-bin.000001 7891 master-bin.000004 Yes Yes 0 0 2886 7891 None 0 No # lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result index da23034bacd..1cd9cdf08a0 100644 --- a/mysql-test/r/rpl_trunc_binlog.result +++ b/mysql-test/r/rpl_trunc_binlog.result @@ -10,5 +10,5 @@ reset slave; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 326 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 326 None 0 No # reset master; diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 2a08659aea6..3ee902cfc09 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -31,7 +31,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-bin.000001 244 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-bin.000001 244 No # start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -41,7 +41,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-no-such-bin.000001 291 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-no-such-bin.000001 291 No # start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; select * from t2; n @@ -49,13 +49,13 @@ n 2 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 537 master-bin.000001 Yes No 0 0 449 649 Relay slave-relay-bin.000002 537 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 537 master-bin.000001 Yes No 0 0 449 649 Relay slave-relay-bin.000002 537 No # start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=561; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -Waiting for master to send event 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 649 master-bin.000001 Yes No 0 0 561 693 Master master-bin.000001 561 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 649 master-bin.000001 Yes No 0 0 561 693 Master master-bin.000001 561 No # start slave until master_log_file='master-bin', master_log_pos=561; ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index b71e8472e67..38e0d1bff6c 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -7,24 +7,24 @@ save_master_pos; connection slave; reset slave; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$MASTER_MYPORT; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; connection master; --disable_warnings diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test index b56bf2a059f..bee9ef72dc4 100644 --- a/mysql-test/t/rpl_empty_master_crash.test +++ b/mysql-test/t/rpl_empty_master_crash.test @@ -1,6 +1,6 @@ source include/master-slave.inc; ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index f6ca1c56cde..aacdb506107 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -15,7 +15,7 @@ sync_with_master; # The port number is different when doing the release build with # Do-compile, hence we have to replace the port number here accordingly --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # check that the table has been ignored, because otherwise the test is nonsense show tables like 't1'; diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test index b469a7c571e..74920722868 100644 --- a/mysql-test/t/rpl_flush_log_loop.test +++ b/mysql-test/t/rpl_flush_log_loop.test @@ -18,5 +18,5 @@ sleep 5; flush logs; sleep 5; --replace_result $SLAVE_MYPORT SLAVE_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 0121c90ccb6..10213644836 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -72,7 +72,7 @@ set global sql_slave_skip_counter=1; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # Trigger error again to test CHANGE MASTER @@ -92,7 +92,7 @@ stop slave; change master to master_user='test'; change master to master_user='root'; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # Trigger error again to test RESET SLAVE @@ -114,7 +114,7 @@ wait_for_slave_to_stop; stop slave; reset slave; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # Finally, see if logging is done ok on master for a failing LOAD DATA INFILE diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index b388a5a095e..7ae0a4dc3c2 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -94,7 +94,7 @@ show binlog events in 'slave-bin.000001' from 4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.000002' from 4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # Need to recode the following diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index 2e1cd3275fc..b32f68844a2 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -5,7 +5,7 @@ source include/master-slave.inc; show master status; sync_slave_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; stop slave; change master to master_log_pos=73; @@ -15,12 +15,12 @@ stop slave; change master to master_log_pos=73; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; start slave; sleep 5; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; stop slave; change master to master_log_pos=173; @@ -28,7 +28,7 @@ change master to master_log_pos=173; start slave; sleep 2; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; connection master; show master status; diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index 4a8acc616d9..99f0a9fdde6 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -29,7 +29,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; stop slave; reset slave; @@ -38,7 +38,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; stop slave; reset slave; @@ -47,7 +47,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -58,7 +58,7 @@ reset slave; # (to make sure it does not crash). flush logs; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; reset slave; @@ -74,7 +74,7 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # one more rotation, to be sure Relay_log_space is correctly updated flush logs; @@ -84,7 +84,7 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; connection master; diff --git a/mysql-test/t/rpl_openssl.test b/mysql-test/t/rpl_openssl.test index fbc03d965f1..8a36904f4d4 100644 --- a/mysql-test/t/rpl_openssl.test +++ b/mysql-test/t/rpl_openssl.test @@ -45,7 +45,7 @@ select * from t1; #checking show slave status --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; #checking if replication works without ssl also performing clean up @@ -58,5 +58,5 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_redirect.test b/mysql-test/t/rpl_redirect.test index 2d915a37712..3b5ad6ba88d 100644 --- a/mysql-test/t/rpl_redirect.test +++ b/mysql-test/t/rpl_redirect.test @@ -12,7 +12,7 @@ sync_with_master; #discover slaves connection master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # SHOW SLAVE STATUS; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW SLAVE HOSTS; diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test index 485bfbedb1f..7066f6e53d8 100644 --- a/mysql-test/t/rpl_replicate_do.test +++ b/mysql-test/t/rpl_replicate_do.test @@ -33,6 +33,6 @@ connection slave; sync_with_master; # show slave status, just to see of it prints replicate-do-table --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_reset_slave.test b/mysql-test/t/rpl_reset_slave.test index 76d1d247958..e03916ec73a 100644 --- a/mysql-test/t/rpl_reset_slave.test +++ b/mysql-test/t/rpl_reset_slave.test @@ -9,22 +9,22 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; stop slave; change master to master_user='test'; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; reset slave; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index a5aa674bd88..78213c6a750 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -55,7 +55,7 @@ create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); sync_slave_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; select * from t1; connection master; @@ -107,7 +107,7 @@ show binary logs; insert into t2 values (65); sync_slave_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; select * from t2; @@ -138,7 +138,7 @@ sync_with_master; select * from t4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # because of concurrent insert, the table may not be up to date # if we do not lock diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test index 28602a32abd..4c14ec72b5c 100644 --- a/mysql-test/t/rpl_trunc_binlog.test +++ b/mysql-test/t/rpl_trunc_binlog.test @@ -21,7 +21,7 @@ start slave; # can't sync_with_master so we must sleep sleep 3; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; connection master; reset master; diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 13ce85c8c0f..8b20a493826 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -29,7 +29,7 @@ sleep 2; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # this should fail right after start @@ -38,7 +38,7 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29 select * from t1; sleep 2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # try replicate all until second insert to t2; @@ -46,7 +46,7 @@ start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; sleep 2; select * from t2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; # clean up @@ -62,7 +62,7 @@ start slave until master_log_file='master-bin.000001', master_log_pos=561; sleep 2; # here the sql slave thread should be stopped --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 33 # +--replace_column 1 # 33 # show slave status; #testing various error conditions From e41e9e55128f02ca64b49a0eb9390768e0efe3ce Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Oct 2003 17:06:18 +0400 Subject: [PATCH 13/50] Fix for rpl_openssl test (there was extra spaces in result file) mysql-test/r/rpl_openssl.result: Removed extra spaces --- mysql-test/r/rpl_openssl.result | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_openssl.result b/mysql-test/r/rpl_openssl.result index 7ce3e2cd0e4..32760f2c870 100644 --- a/mysql-test/r/rpl_openssl.result +++ b/mysql-test/r/rpl_openssl.result @@ -19,12 +19,12 @@ select * from t1; t 1 show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -# 127.0.0.1 replssl MASTER_MYPORT 1 master-bin.000001 289 slave-relay-bin.000001 108 master-bin.000001 Yes Yes 0 0 289 108 None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # +Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +# 127.0.0.1 replssl MASTER_MYPORT 1 master-bin.000001 289 slave-relay-bin.000001 108 master-bin.000001 Yes Yes 0 0 289 108 None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # stop slave; change master to master_user='root',master_password='', master_ssl=0; start slave; drop table t1; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 337 slave-relay-bin.000001 96 master-bin.000001 Yes Yes 0 0 337 96 None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # +Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 337 slave-relay-bin.000001 96 master-bin.000001 Yes Yes 0 0 337 96 None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem # From b297e76402bc8819d6e7c7765f380a764205388d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2003 11:21:32 -0500 Subject: [PATCH 14/50] mysqld.cc: Fix error in --show-slave-auth-info help string. sql/mysqld.cc: Fix error in --show-slave-auth-info help string. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1c26d4a8b7c..62f2471d34f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3992,7 +3992,7 @@ relay logs.", 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO, - "Show user and password in SHOW SLAVE STATUS.", + "Show user and password in SHOW SLAVE HOSTS.", (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"concurrent-insert", OPT_CONCURRENT_INSERT, From 74ea459412f9a479ea1385a72cc27b4245c06435 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2003 22:00:24 +0300 Subject: [PATCH 15/50] Add new user variables for tuning memory usage: query_alloc_block_size, query_prealloc_size, range_alloc_block_size,transaction_alloc_block_size and transaction_prealloc_size Add more checks for "out of memory" detection in range optimization configure.in: Added detection of mallinfo mysql-test/r/variables.result: Test of new variables mysql-test/t/variables.test: Test of new variables sql/ha_berkeley.cc: Use init_sql_alloc instead of init_alloc_root for better OOM detection sql/log_event.cc: Add new user variables for tuning memory usage sql/mysql_priv.h: Add new user variables for tuning memory usage sql/mysqld.cc: Add new user variables for tuning memory usage sql/opt_ft.cc: Add new user variables for tuning memory usage sql/opt_ft.h: Add new user variables for tuning memory usage sql/opt_range.cc: Add new user variables for tuning memory usage Add more checks for out of memory conditions sql/opt_range.h: Add new user variables for tuning memory usage sql/set_var.cc: Add new user variables for tuning memory usage sql/sql_acl.cc: Add new user variables for tuning memory usage sql/sql_class.h: Add new user variables for tuning memory usage sql/sql_delete.cc: Add new user variables for tuning memory usage sql/sql_parse.cc: Add new user variables for tuning memory usage sql/sql_select.cc: Add new user variables for tuning memory usage sql/sql_test.cc: Add information about memory useage if system supports mallinfo() sql/sql_udf.cc: Add new user variables for tuning memory usage sql/sql_update.cc: Add new user variables for tuning memory usage sql/table.cc: Add new user variables for tuning memory usage --- configure.in | 2 +- mysql-test/r/variables.result | 32 ++++++++++ mysql-test/t/variables.test | 12 ++++ sql/ha_berkeley.cc | 2 +- sql/log_event.cc | 4 +- sql/mysql_priv.h | 10 ++++ sql/mysqld.cc | 30 +++++++++- sql/opt_ft.cc | 8 +-- sql/opt_ft.h | 7 ++- sql/opt_range.cc | 110 +++++++++++++++++++++------------- sql/opt_range.h | 14 +++-- sql/set_var.cc | 25 ++++++++ sql/sql_acl.cc | 4 +- sql/sql_class.h | 5 ++ sql/sql_delete.cc | 3 +- sql/sql_parse.cc | 18 +++--- sql/sql_select.cc | 19 +++--- sql/sql_test.cc | 27 +++++++++ sql/sql_udf.cc | 2 +- sql/sql_update.cc | 2 +- sql/table.cc | 2 +- 21 files changed, 257 insertions(+), 81 deletions(-) diff --git a/configure.in b/configure.in index 168ac91667d..f085d365ed2 100644 --- a/configure.in +++ b/configure.in @@ -1806,7 +1806,7 @@ AC_CHECK_FUNCS(alarm bmove \ cuserid fcntl fconvert poll \ getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \ perror pread realpath readlink rename \ - socket strnlen madvise mkstemp \ + socket strnlen madvise mallinfo mkstemp \ strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \ gethostbyaddr_r gethostbyname_r getpwnam \ bfill bzero bcmp strstr strpbrk strerror \ diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 7c054f55acd..50e97120de6 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -171,6 +171,38 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000; select ROUND(RAND(),5); ROUND(RAND(),5) 0.02887 +show variables like '%alloc%'; +Variable_name Value +query_alloc_block_size 8192 +query_prealloc_size 8192 +range_alloc_block_size 2048 +transaction_alloc_block_size 8192 +transaction_prealloc_size 4096 +set @@range_alloc_block_size=1024*16; +set @@query_alloc_block_size=1024*17+2; +set @@query_prealloc_size=1024*18; +set @@transaction_alloc_block_size=1024*20-1; +set @@transaction_prealloc_size=1024*21-1; +select @@query_alloc_block_size; +@@query_alloc_block_size +17408 +show variables like '%alloc%'; +Variable_name Value +query_alloc_block_size 17408 +query_prealloc_size 18432 +range_alloc_block_size 16384 +transaction_alloc_block_size 19456 +transaction_prealloc_size 20480 +set @@range_alloc_block_size=default; +set @@query_alloc_block_size=default, @@query_prealloc_size=default; +set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; +show variables like '%alloc%'; +Variable_name Value +query_alloc_block_size 8192 +query_prealloc_size 8192 +range_alloc_block_size 2048 +transaction_alloc_block_size 8192 +transaction_prealloc_size 4096 set big_tables=OFFF; Variable 'big_tables' can't be set to the value of 'OFFF' set big_tables="OFFF"; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index fa39906fd6a..6a3264741ad 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -99,6 +99,18 @@ select @@timestamp>0; set @@rand_seed1=10000000,@@rand_seed2=1000000; select ROUND(RAND(),5); +show variables like '%alloc%'; +set @@range_alloc_block_size=1024*16; +set @@query_alloc_block_size=1024*17+2; +set @@query_prealloc_size=1024*18; +set @@transaction_alloc_block_size=1024*20-1; +set @@transaction_prealloc_size=1024*21-1; +select @@query_alloc_block_size; +show variables like '%alloc%'; +set @@range_alloc_block_size=default; +set @@query_alloc_block_size=default, @@query_prealloc_size=default; +set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; +show variables like '%alloc%'; # The following should give errors diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 78704a18052..6796a9c3306 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -240,7 +240,7 @@ int berkeley_show_logs(THD *thd) MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); DBUG_ENTER("berkeley_show_logs"); - init_alloc_root(&show_logs_root, 1024, 1024); + init_sql_alloc(&show_logs_root, 1024, 1024); my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root); if ((error= log_archive(db_env, &all_logs, DB_ARCH_ABS | DB_ARCH_LOG, diff --git a/sql/log_event.cc b/sql/log_event.cc index 3e9064a78ea..699d1ff866d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1771,7 +1771,7 @@ void Unknown_log_event::print(FILE* file, bool short_form, char* last_db) int Query_log_event::exec_event(struct st_relay_log_info* rli) { int expected_error, actual_error= 0; - init_sql_alloc(&thd->mem_root, 8192,0); + init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size,0); thd->db= (char*) rewrite_db(db); /* @@ -1912,7 +1912,7 @@ Default database: '%s'", int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, bool use_rli_only_for_errors) { - init_sql_alloc(&thd->mem_root, 8192,0); + init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size, 0); thd->db= (char*) rewrite_db(db); DBUG_ASSERT(thd->query == 0); thd->query = 0; // Should not be needed diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 23cf4952e3d..adb7831896c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -75,6 +75,16 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int. #endif #define TEMP_POOL_SIZE 128 + +#define QUERY_ALLOC_BLOCK_SIZE 8192 +#define QUERY_ALLOC_PREALLOC_SIZE 8192 +#define TRANS_ALLOC_BLOCK_SIZE 4096 +#define TRANS_ALLOC_PREALLOC_SIZE 4096 +#define RANGE_ALLOC_BLOCK_SIZE 2048 +#define ACL_ALLOC_BLOCK_SIZE 1024 +#define UDF_ALLOC_BLOCK_SIZE 1024 +#define TABLE_ALLOC_BLOCK_SIZE 1024 + /* The following parameters is to decide when to use an extra cache to optimise seeks when reading a big table in sorted order diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1bb51ea8e91..c4739a060e1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3242,7 +3242,10 @@ enum options { OPT_BDB_LOG_BUFFER_SIZE, OPT_BDB_MAX_LOCK, OPT_ERROR_LOG_FILE, - OPT_DEFAULT_WEEK_FORMAT + OPT_DEFAULT_WEEK_FORMAT, + OPT_RANGE_ALLOC_BLOCK_SIZE, + OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, + OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE }; @@ -3976,6 +3979,11 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.", (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 65535, 0, 1, 0}, + {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE, + "Allocation block size for query parsing and execution", + (gptr*) &global_system_variables.query_alloc_block_size, + (gptr*) &max_system_variables.query_alloc_block_size, 0, GET_ULONG, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, #ifdef HAVE_QUERY_CACHE {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, "Don't cache results that are bigger than this.", @@ -3992,6 +4000,11 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ (gptr*) &global_system_variables.query_cache_type, (gptr*) &max_system_variables.query_cache_type, 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0}, + {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE, + "Persistent buffer for query parsing and execution", + (gptr*) &global_system_variables.query_prealloc_size, + (gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG, + REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, #endif /*HAVE_QUERY_CACHE*/ {"read_buffer_size", OPT_RECORD_BUFFER, "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.", @@ -4023,6 +4036,11 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ "Number of seconds to wait for more data from a master/slave connection before aborting the read.", (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, + "Allocation block size for storing ranges during optimization", + (gptr*) &global_system_variables.range_alloc_block_size, + (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG, + REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, {"read-only", OPT_READONLY, "Make all tables readonly, with the expections for replications (slave) threads and users with the SUPER privilege", (gptr*) &opt_readonly, @@ -4059,6 +4077,16 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ "The stack size for each thread.", (gptr*) &thread_stack, (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024, 0}, + {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE, + "Allocation block size for transactions to be stored in binary log", + (gptr*) &global_system_variables.trans_alloc_block_size, + (gptr*) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, + {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE, + "Persistent buffer for transactions to be stored in binary log", + (gptr*) &global_system_variables.trans_prealloc_size, + (gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG, + REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, {"wait_timeout", OPT_WAIT_TIMEOUT, "The number of seconds the server waits for activity on a connection before closing it", (gptr*) &global_system_variables.net_wait_timeout, diff --git a/sql/opt_ft.cc b/sql/opt_ft.cc index b35b3230a39..74349819937 100644 --- a/sql/opt_ft.cc +++ b/sql/opt_ft.cc @@ -26,11 +26,11 @@ ** Create a FT or QUICK RANGE based on a key ****************************************************************************/ -QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab) +QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table, + JOIN_TAB *tab) { if (tab->type == JT_FT) - return new FT_SELECT(table, &tab->ref); - else - return get_quick_select_for_ref(table, &tab->ref); + return new FT_SELECT(thd, table, &tab->ref); + return get_quick_select_for_ref(thd, table, &tab->ref); } diff --git a/sql/opt_ft.h b/sql/opt_ft.h index b055edc107c..69b6b72f3fc 100644 --- a/sql/opt_ft.h +++ b/sql/opt_ft.h @@ -28,13 +28,14 @@ class FT_SELECT: public QUICK_SELECT { public: TABLE_REF *ref; - FT_SELECT(TABLE *table, TABLE_REF *tref) : - QUICK_SELECT (table,tref->key,1), ref(tref) { init(); } + FT_SELECT(THD *thd, TABLE *table, TABLE_REF *tref) : + QUICK_SELECT (thd, table, tref->key, 1), ref(tref) { init(); } int init() { return error=file->ft_init(); } int get_next() { return error=file->ft_read(record); } }; -QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab); +QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table, + JOIN_TAB *tab); #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8dad80d3eba..e932b2c46d6 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -280,6 +280,7 @@ public: typedef struct st_qsel_param { + THD *thd; TABLE *table; KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY]; MEM_ROOT *mem_root; @@ -382,13 +383,14 @@ SQL_SELECT::~SQL_SELECT() #undef index // Fix for Unixware 7 -QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc) +QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc) :dont_free(0),error(0),index(key_nr),max_used_key_length(0),head(table), it(ranges),range(0) { if (!no_alloc) { - init_sql_alloc(&alloc,1024,0); // Allocates everything here + // Allocates everything through the internal memroot + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); my_pthread_setspecific_ptr(THR_MALLOC,&alloc); } else @@ -460,17 +462,17 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) SEL_ARG *tmp; if (type != KEY_RANGE) { - if(!(tmp=new SEL_ARG(type))) - return 0; // out of memory + if (!(tmp= new SEL_ARG(type))) + return 0; // out of memory tmp->prev= *next_arg; // Link into next/prev chain (*next_arg)->next=tmp; (*next_arg)= tmp; } else { - if(!(tmp=new SEL_ARG(field,part, min_value,max_value, - min_flag, max_flag, maybe_flag))) - return 0; // out of memory + if (!(tmp= new SEL_ARG(field,part, min_value,max_value, + min_flag, max_flag, maybe_flag))) + return 0; // OOM tmp->parent=new_parent; tmp->next_key_part=next_key_part; if (left != &null_element) @@ -481,7 +483,8 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) (*next_arg)= tmp; if (right != &null_element) - tmp->right=right->clone(tmp,next_arg); + if (!(tmp->right= right->clone(tmp,next_arg))) + return 0; // OOM } increment_use_count(1); return tmp; @@ -560,10 +563,11 @@ SEL_ARG *SEL_ARG::clone_tree() { SEL_ARG tmp_link,*next_arg,*root; next_arg= &tmp_link; - root=clone((SEL_ARG *) 0, &next_arg); + root= clone((SEL_ARG *) 0, &next_arg); next_arg->next=0; // Fix last link tmp_link.next->prev=0; // Fix first link - root->use_count=0; + if (root) // If not OOM + root->use_count= 0; return root; } @@ -581,7 +585,8 @@ SEL_ARG *SEL_ARG::clone_tree() ** quick_rows ; How many rows the key matches *****************************************************************************/ -int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, +int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, + table_map prev_tables, ha_rows limit, bool force_quick_range) { uint basflag; @@ -624,6 +629,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, PARAM param; /* set up parameter that is passed to all functions */ + param.thd= thd; param.baseflag=basflag; param.prev_tables=prev_tables | const_tables; param.read_tables=read_tables; @@ -632,13 +638,13 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, param.keys=0; param.mem_root= &alloc; - current_thd->no_errors=1; // Don't warn about NULL - init_sql_alloc(&alloc,2048,0); + param.thd->no_errors=1; // Don't warn about NULL + init_sql_alloc(&alloc, param.thd->variables.range_alloc_block_size, 0); if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc, sizeof(KEY_PART)* head->key_parts))) { - current_thd->no_errors=0; + param.thd->no_errors=0; free_root(&alloc,MYF(0)); // Return memory & allocator DBUG_RETURN(0); // Can't use range } @@ -737,7 +743,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, } free_root(&alloc,MYF(0)); // Return memory & allocator my_pthread_setspecific_ptr(THR_MALLOC,old_root); - current_thd->no_errors=0; + param.thd->no_errors=0; } DBUG_EXECUTE("info",print_quick(quick,needed_reg);); /* @@ -765,7 +771,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) while ((item=li++)) { SEL_TREE *new_tree=get_mm_tree(param,item); - if(current_thd->fatal_error) + if (param->thd->fatal_error) DBUG_RETURN(0); // out of memory tree=tree_and(param,tree,new_tree); if (tree && tree->type == SEL_TREE::IMPOSSIBLE) @@ -906,7 +912,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, { SEL_ARG *sel_arg=0; if (!tree && !(tree=new SEL_TREE())) - DBUG_RETURN(0); // out of memory + DBUG_RETURN(0); // OOM if (!value || !(value->used_tables() & ~param->read_tables)) { sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value); @@ -918,10 +924,11 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, DBUG_RETURN(tree); } } - else { + else + { // This key may be used later - if(!(sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY))) - DBUG_RETURN(0); // out of memory + if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY))) + DBUG_RETURN(0); // OOM } sel_arg->part=(uchar) key_part->part; tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg); @@ -1164,8 +1171,8 @@ static bool like_range(const char *ptr,uint ptr_length,char escape, ******************************************************************************/ /* -** Add a new key test to a key when scanning through all keys -** This will never be called for same key parts. + Add a new key test to a key when scanning through all keys + This will never be called for same key parts. */ static SEL_ARG * @@ -1349,7 +1356,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) // key1->part < key2->part key1->use_count--; if (key1->use_count > 0) - key1=key1->clone_tree(); + if (!(key1= key1->clone_tree())) + return 0; // OOM return and_all_keys(key1,key2,clone_flag); } @@ -1368,7 +1376,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) if (key1->use_count > 1) { key1->use_count--; - key1=key1->clone_tree(); + if (!(key1=key1->clone_tree())) + return 0; // OOM key1->use_count++; } if (key1->type == SEL_ARG::MAYBE_KEY) @@ -1412,6 +1421,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) if (!next || next->type != SEL_ARG::IMPOSSIBLE) { SEL_ARG *new_arg= e1->clone_and(e2); + if (!new_arg) + return &null_element; // End of memory new_arg->next_key_part=next; if (!new_tree) { @@ -1499,8 +1510,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) { swap(SEL_ARG *,key1,key2); } - else - key1=key1->clone_tree(); + else if (!(key1=key1->clone_tree())) + return 0; // OOM } // Add tree at key2 to tree at key1 @@ -1526,7 +1537,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) SEL_ARG *key2_next=key2->next; if (key2_shared) { - if(!(key2=new SEL_ARG(*key2))) + if (!(key2=new SEL_ARG(*key2))) return 0; // out of memory key2->increment_use_count(key1->use_count+1); key2->next=key2_next; // New copy of key2 @@ -1568,7 +1579,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) SEL_ARG *next=key2->next; // Keys are not overlapping if (key2_shared) { - key1=key1->insert(new SEL_ARG(*key2)); // Must make copy + SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy + if (!tmp) + return 0; // OOM + key1=key1->insert(tmp); key2->increment_use_count(key1->use_count+1); } else @@ -1614,6 +1628,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0) { // tmp.min <= x < key2.min SEL_ARG *new_arg=tmp->clone_first(key2); + if (!new_arg) + return 0; // OOM if ((new_arg->next_key_part= key1->next_key_part)) new_arg->increment_use_count(key1->use_count+1); tmp->copy_min_to_min(key2); @@ -1627,6 +1643,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) if (tmp->cmp_min_to_min(&key) > 0) { // key.min <= x < tmp.min SEL_ARG *new_arg=key.clone_first(tmp); + if (!new_arg) + return 0; // OOM if ((new_arg->next_key_part=key.next_key_part)) new_arg->increment_use_count(key1->use_count+1); key1=key1->insert(new_arg); @@ -1641,19 +1659,27 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) key.copy_max_to_min(tmp); if (!(tmp=tmp->next)) { - key1=key1->insert(new SEL_ARG(key)); + SEL_ARG *tmp2= new SEL_ARG(key); + if (!tmp2) + return 0; // OOM + key1=key1->insert(tmp2); key2=key2->next; goto end; } if (tmp->cmp_min_to_max(&key) > 0) { - key1=key1->insert(new SEL_ARG(key)); + SEL_ARG *tmp2= new SEL_ARG(key); + if (!tmp2) + return 0; // OOM + key1=key1->insert(tmp2); break; } } else { SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max + if (!new_arg) + return 0; // OOM tmp->copy_max_to_min(&key); tmp->increment_use_count(key1->use_count+1); new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part); @@ -1670,8 +1696,11 @@ end: SEL_ARG *next=key2->next; if (key2_shared) { + SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy + if (!tmp) + return 0; key2->increment_use_count(key1->use_count+1); - key1=key1->insert(new SEL_ARG(*key2)); // Must make copy + key1=key1->insert(tmp); } else key1=key1->insert(key2); // Will destroy key2_root @@ -2247,7 +2276,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree) { QUICK_SELECT *quick; DBUG_ENTER("get_quick_select"); - if ((quick=new QUICK_SELECT(param->table,param->real_keynr[idx]))) + if ((quick=new QUICK_SELECT(param->thd, param->table, + param->real_keynr[idx]))) { if (quick->error || get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0, @@ -2351,11 +2381,11 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, } /* Get range for retrieving rows in QUICK_SELECT::get_next */ - if(!(range= new QUICK_RANGE(param->min_key, - (uint) (tmp_min_key - param->min_key), - param->max_key, - (uint) (tmp_max_key - param->max_key), - flag))) + if (!(range= new QUICK_RANGE(param->min_key, + (uint) (tmp_min_key - param->min_key), + param->max_key, + (uint) (tmp_max_key - param->max_key), + flag))) return 1; // out of memory set_if_bigger(quick->max_used_key_length,range->min_length); @@ -2411,10 +2441,10 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) ** Create a QUICK RANGE based on a key ****************************************************************************/ -QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) +QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { table->file->index_end(); // Remove old cursor - QUICK_SELECT *quick=new QUICK_SELECT(table, ref->key, 1); + QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; uint part; @@ -2423,7 +2453,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) return 0; /* no ranges found */ if (cp_buffer_from_ref(ref)) { - if (current_thd->fatal_error) + if (thd->fatal_error) return 0; // out of memory return quick; // empty range } diff --git a/sql/opt_range.h b/sql/opt_range.h index 6a6b5ae3810..cda8ad51c3f 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -80,7 +80,7 @@ public: ha_rows records; double read_time; - QUICK_SELECT(TABLE *table,uint index_arg,bool no_alloc=0); + QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0); virtual ~QUICK_SELECT(); void reset(void) { next=0; it.rewind(); } int init() { return error=file->index_init(index); } @@ -124,13 +124,15 @@ class SQL_SELECT :public Sql_alloc { SQL_SELECT(); ~SQL_SELECT(); - bool check_quick(bool force_quick_range=0, ha_rows limit = HA_POS_ERROR) - { return test_quick_select(~0L,0,limit, force_quick_range) < 0; } + bool check_quick(THD *thd, bool force_quick_range= 0, + ha_rows limit= HA_POS_ERROR) + { return test_quick_select(thd, ~0L,0,limit, force_quick_range) < 0; } inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; } - int test_quick_select(key_map keys,table_map prev_tables,ha_rows limit, - bool force_quick_range=0); + int test_quick_select(THD *thd, key_map keys, table_map prev_tables, + ha_rows limit, bool force_quick_range=0); }; -QUICK_SELECT *get_quick_select_for_ref(TABLE *table, struct st_table_ref *ref); +QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, + struct st_table_ref *ref); #endif diff --git a/sql/set_var.cc b/sql/set_var.cc index 8c0859fbca4..dd2f90845c9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -201,6 +201,18 @@ sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank", sys_var_long_ptr sys_query_cache_size("query_cache_size", &query_cache_size, fix_query_cache_size); + +sys_var_thd_ulong sys_range_alloc_block_size("range_alloc_block_size", + &SV::range_alloc_block_size); +sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size", + &SV::query_alloc_block_size); +sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size", + &SV::query_prealloc_size); +sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size", + &SV::trans_alloc_block_size); +sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size", + &SV::trans_prealloc_size); + #ifdef HAVE_QUERY_CACHE sys_var_long_ptr sys_query_cache_limit("query_cache_limit", &query_cache.query_cache_limit); @@ -372,7 +384,9 @@ sys_var *sys_variables[]= &sys_net_wait_timeout, &sys_net_write_timeout, &sys_new_mode, + &sys_query_alloc_block_size, &sys_query_cache_size, + &sys_query_prealloc_size, #ifdef HAVE_QUERY_CACHE &sys_query_cache_limit, &sys_query_cache_type, @@ -382,6 +396,7 @@ sys_var *sys_variables[]= &sys_rand_seed2, &sys_read_buff_size, &sys_read_rnd_buff_size, + &sys_range_alloc_block_size, &sys_rpl_recovery_rank, &sys_safe_updates, &sys_select_limit, @@ -401,6 +416,8 @@ sys_var *sys_variables[]= &sys_thread_cache_size, &sys_timestamp, &sys_tmp_table_size, + &sys_trans_alloc_block_size, + &sys_trans_prealloc_size, &sys_tx_isolation, #ifdef HAVE_INNOBASE_DB &sys_innodb_max_dirty_pages_pct, @@ -530,14 +547,19 @@ struct show_var_st init_vars[]= { {"log_error", (char*) log_error_file, SHOW_CHAR}, {"port", (char*) &mysql_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, + {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size, + SHOW_SYS}, #ifdef HAVE_QUERY_CACHE {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS}, {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ + {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, + {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size, + SHOW_SYS}, {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, @@ -563,6 +585,9 @@ struct show_var_st init_vars[]= { #endif {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR}, + {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size, + SHOW_SYS}, + {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS}, {"version", server_version, SHOW_CHAR}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {NullS, NullS, SHOW_LONG} diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0dbbb1cee70..065394c87d0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -183,7 +183,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) thd->net.last_error); goto end; } - init_sql_alloc(&mem,1024,0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) @@ -2417,7 +2417,7 @@ my_bool grant_init(THD *org_thd) grant_option = FALSE; (void) hash_init(&hash_tables,0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); - init_sql_alloc(&memex,1024,0); + init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); /* Don't do anything if running with --skip-grant */ if (!initialized) diff --git a/sql/sql_class.h b/sql/sql_class.h index 2ed9cb7b877..15631472895 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -327,6 +327,11 @@ struct system_variables ulong table_type; ulong default_week_format; ulong max_seeks_for_key; + ulong range_alloc_block_size; + ulong query_alloc_block_size; + ulong query_prealloc_size; + ulong trans_alloc_block_size; + ulong trans_prealloc_size; my_bool log_warnings; my_bool low_priority_updates; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 45acbaaa7ef..34a79ecd78d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -76,7 +76,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, select=make_select(table,0,0,conds,&error); if (error) DBUG_RETURN(-1); - if ((select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES), + if ((select && select->check_quick(thd, + test(thd->options & OPTION_SAFE_UPDATES), limit)) || !limit) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0c4e3cad763..c913b29cdeb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -46,11 +46,6 @@ #endif /* HAVE_OPENSSL */ #define SCRAMBLE_LENGTH 8 -#define MEM_ROOT_BLOCK_SIZE 8192 -#define MEM_ROOT_PREALLOC 8192 -#define TRANS_MEM_ROOT_BLOCK_SIZE 4096 -#define TRANS_MEM_ROOT_PREALLOC 4096 - extern int yyparse(void); extern "C" pthread_mutex_t THR_LOCK_keycache; #ifdef SOLARIS @@ -714,9 +709,12 @@ pthread_handler_decl(handle_one_connection,arg) thd->command=COM_SLEEP; thd->version=refresh_version; thd->set_time(); - init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); init_sql_alloc(&thd->transaction.mem_root, - TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC); + thd->variables.trans_alloc_block_size, + thd->variables.trans_prealloc_size); + while (!net->error && net->vio != 0 && !thd->killed) { if (do_command(thd)) @@ -791,9 +789,11 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME)); buff= (char*) thd->net.buff; - init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); init_sql_alloc(&thd->transaction.mem_root, - TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC); + thd->variables.trans_alloc_block_size, + thd->variables.trans_prealloc_size); while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bffe3cd7968..353a4623962 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1000,7 +1000,8 @@ err: Approximate how many records will be used in each table *****************************************************************************/ -static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, +static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, + TABLE *table, key_map keys,ha_rows limit) { int error; @@ -1009,7 +1010,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, { select->head=table; table->reginfo.impossible_range=0; - if ((error=select->test_quick_select(keys,(table_map) 0,limit)) + if ((error=select->test_quick_select(thd, keys,(table_map) 0,limit)) == 1) DBUG_RETURN(select->quick->records); if (error == -1) @@ -1290,8 +1291,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, found_const_table_map, s->on_expr ? s->on_expr : conds, &error); - records= get_quick_record_count(select,s->table, s->const_keys, - join->row_limit); + records= get_quick_record_count(join->thd, select, s->table, + s->const_keys, join->row_limit); s->quick=select->quick; s->needed_reg=select->needed_reg; select->quick=0; @@ -2687,7 +2688,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* Join with outer join condition */ COND *orig_cond=sel->cond; sel->cond=and_conds(sel->cond,tab->on_expr); - if (sel->test_quick_select(tab->keys, + if (sel->test_quick_select(join->thd, tab->keys, used_tables & ~ current_map, (join->select_options & OPTION_FOUND_ROWS ? @@ -2697,7 +2698,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) we have to check isn't it only "impossible ON" instead */ sel->cond=orig_cond; if (!tab->on_expr || - sel->test_quick_select(tab->keys, + sel->test_quick_select(join->thd, tab->keys, used_tables & ~ current_map, (join->select_options & OPTION_FOUND_ROWS ? @@ -5047,7 +5048,8 @@ test_if_quick_select(JOIN_TAB *tab) { delete tab->select->quick; tab->select->quick=0; - return tab->select->test_quick_select(tab->keys,(table_map) 0,HA_POS_ERROR); + return tab->select->test_quick_select(tab->join->thd, tab->keys, + (table_map) 0, HA_POS_ERROR); } @@ -6014,7 +6016,8 @@ create_sort_index(JOIN_TAB *tab, ORDER *order, ha_rows filesort_limit, For impossible ranges (like when doing a lookup on NULL on a NOT NULL field, quick will contain an empty record set. */ - if (!(select->quick=get_ft_or_quick_select_for_ref(table, tab))) + if (!(select->quick=get_ft_or_quick_select_for_ref(tab->join->thd, + table, tab))) goto err; } } diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 6816bb62047..fc3147db784 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -22,6 +22,7 @@ #include "sql_select.h" #include #include +#include /* Intern key cache variables */ extern "C" pthread_mutex_t THR_LOCK_keycache; @@ -257,6 +258,32 @@ Next alarm time: %lu\n", thd->proc_info="malloc"; my_checkmalloc(); TERMINATE(stdout); // Write malloc information + +#ifdef HAVE_MALLINFO + struct mallinfo info= mallinfo(); + printf("\nMemory status:\n\ +Non-mmapped space allocated from system: %d\n\ +Number of free chunks: %d\n\ +Number of fastbin blocks: %d\n\ +Number of mmapped regions: %d\n\ +Space in mmapped regions: %d\n\ +Maximum total allocated space: %d\n\ +Space available in freed fastbin blocks: %d\n\ +Total allocated space: %d\n\ +Total free space: %d\n\ +Top-most, releasable space: %d\n", + (int) info.arena, + (int) info.ordblks, + (int) info.smblks, + (int) info.hblks, + (int) info.hblkhd, + (int) info.usmblks, + (int) info.fsmblks, + (int) info.uordblks, + (int) info.fordblks, + (int) info.keepcost); +#endif + puts(""); if (thd) thd->proc_info=0; } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 8a1c19568ae..54613f82f00 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -124,7 +124,7 @@ void udf_init() pthread_mutex_init(&THR_LOCK_udf,MY_MUTEX_INIT_SLOW); - init_sql_alloc(&mem, 1024,0); + init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0); THD *new_thd = new THD; if (!new_thd || hash_init(&udf_hash,32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE)) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2f3f917a962..d5034644830 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -130,7 +130,7 @@ int mysql_update(THD *thd, table->used_keys=0; select=make_select(table,0,0,conds,&error); if (error || - (select && select->check_quick(safe_update, limit)) || !limit) + (select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; if (error) diff --git a/sql/table.cc b/sql/table.cc index e938757cf6c..422202301f1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -70,7 +70,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->db_stat = db_stat; error=1; - init_sql_alloc(&outparam->mem_root,1024,0); + init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root); From 0cdddbf144de80d1c4da00ee681632bc0ac6c7c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2003 23:26:39 +0300 Subject: [PATCH 16/50] Add warnings for single line inserts. To do this I had to convert count_cuted_fields to an enum (to be able to detect setting a NOT NULL field to NULL) mysql-test/r/ctype_mb.result: update results after adding more warnings mysql-test/r/null.result: update results after adding more warnings mysql-test/r/select_found.result: update results after adding more warnings mysql-test/r/warnings.result: update results after adding more warnings mysql-test/t/ctype_mb.test: Add missing drop table mysql-test/t/myisam.test: Disable some warnings mysql-test/t/select_found.test: update results after adding more warnings sql/field_conv.cc: Add warnings for single line inserts sql/item_func.cc: Remove compile warnings sql/sql_class.cc: Add warnings for single line inserts sql/sql_class.h: Add warnings for single line inserts sql/sql_insert.cc: Add warnings for single line inserts sql/sql_load.cc: Add warnings for single line inserts sql/sql_select.cc: Add warnings for single line inserts sql/sql_table.cc: Add warnings for single line inserts sql/sql_update.cc: Add warnings for single line inserts --- mysql-test/r/ctype_mb.result | 5 +++++ mysql-test/r/null.result | 2 ++ mysql-test/r/select_found.result | 2 +- mysql-test/r/warnings.result | 2 ++ mysql-test/t/ctype_mb.test | 7 +++++++ mysql-test/t/myisam.test | 2 ++ mysql-test/t/select_found.test | 2 +- sql/field_conv.cc | 4 ++-- sql/item_func.cc | 9 +++++++++ sql/sql_class.cc | 3 ++- sql/sql_class.h | 6 +++++- sql/sql_insert.cc | 19 ++++++++++++------- sql/sql_load.cc | 4 ++-- sql/sql_select.cc | 4 ++-- sql/sql_table.cc | 4 ++-- sql/sql_update.cc | 8 ++++---- 16 files changed, 60 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/ctype_mb.result b/mysql-test/r/ctype_mb.result index 298e774186d..ce4a4f98b42 100644 --- a/mysql-test/r/ctype_mb.result +++ b/mysql-test/r/ctype_mb.result @@ -1,3 +1,4 @@ +drop table if exists t1; CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'теÑÑ‚' as c2; SHOW CREATE TABLE t1; Table Create Table @@ -15,6 +16,10 @@ t1 CREATE TABLE `t1` ( `c3` char(4) character set utf8 default NULL ) TYPE=MyISAM CHARSET=latin1 INSERT INTO t1 VALUES ('aaaabbbbccccdddd','aaaabbbbccccdddd','aaaabbbbccccdddd'); +Warnings: +Warning 1264 Data truncated for column 'c1' at row 1 +Warning 1264 Data truncated for column 'c2' at row 1 +Warning 1264 Data truncated for column 'c3' at row 1 SELECT * FROM t1; c1 c2 c3 aaaabbbbcccc aaaabbbbcccc aaaabbbbcccc diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 479a7f049d9..2ef1f0c86f9 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -75,6 +75,8 @@ NULL this is null drop table t1; CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; +Warnings: +Warning 1264 Data truncated for column 'd' at row 1 UPDATE t1 SET d=1/NULL; Warnings: Warning 1264 Data truncated for column 'd' at row 1 diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index c8991696b5e..d79f45a9334 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -136,7 +136,7 @@ email104 email105 email106 email107 -INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150'); +INSERT INTO `t1` (`id`, `kid`) VALUES ('0', '150'); SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10; email email1 diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 9d4710ff729..26353785733 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -92,6 +92,8 @@ Warning 1264 Data truncated for column 'b' at row 3 Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 4 Warning 1264 Data truncated for column 'b' at row 4 insert into t2(b) values('mysqlab'); +Warnings: +Warning 1264 Data truncated for column 'b' at row 1 set sql_warnings=1; insert into t2(b) values('mysqlab'); Warnings: diff --git a/mysql-test/t/ctype_mb.test b/mysql-test/t/ctype_mb.test index 96bb634deb3..b0ccab8e345 100644 --- a/mysql-test/t/ctype_mb.test +++ b/mysql-test/t/ctype_mb.test @@ -1,3 +1,10 @@ +# +# Test of alter table +# +--disable_warnings +drop table if exists t1; +--enable_warnings + CREATE TABLE t1 SELECT _utf8'test' as c1, _utf8'теÑÑ‚' as c2; SHOW CREATE TABLE t1; DELETE FROM t1; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 8c43ce1937f..5dceb2b4598 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -34,6 +34,7 @@ create table t1 (a tinyint not null auto_increment, b blob not null, primary key let $1=100; disable_query_log; +--disable_warnings SET SQL_WARNINGS=0; while ($1) { @@ -41,6 +42,7 @@ while ($1) dec $1; } SET SQL_WARNINGS=1; +--enable_warnings enable_query_log; check table t1; repair table t1; diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test index 06624d50a43..e8be902606c 100644 --- a/mysql-test/t/select_found.test +++ b/mysql-test/t/select_found.test @@ -64,7 +64,7 @@ SELECT FOUND_ROWS(); SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10; SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10; -INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150'); +INSERT INTO `t1` (`id`, `kid`) VALUES ('0', '150'); SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10; SELECT FOUND_ROWS(); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 6510a03f5a6..5f08c91372b 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -119,7 +119,7 @@ set_field_to_null(Field *field) return 0; } field->reset(); - if (current_thd->count_cuted_fields) + if (current_thd->count_cuted_fields == CHECK_FIELD_WARN) { field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,ER_WARN_DATA_TRUNCATED); return 0; @@ -176,7 +176,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) field->table->auto_increment_field_not_null= false; return 0; // field is set in handler.cc } - if (current_thd->count_cuted_fields) + if (current_thd->count_cuted_fields == CHECK_FIELD_WARN) { field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,ER_WARN_NULL_TO_NOTNULL); return 0; diff --git a/sql/item_func.cc b/sql/item_func.cc index bc7c95d8929..929f85a112d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2200,6 +2200,9 @@ double user_var_entry::val(my_bool *null_value) return (double) *(longlong*) value; case STRING_RESULT: return atof(value); // This is null terminated + case ROW_RESULT: + DBUG_ASSERT(1); // Impossible + break; } return 0.0; // Impossible } @@ -2219,6 +2222,9 @@ longlong user_var_entry::val_int(my_bool *null_value) return *(longlong*) value; case STRING_RESULT: return strtoull(value,NULL,10); // String is null terminated + case ROW_RESULT: + DBUG_ASSERT(1); // Impossible + break; } return LL(0); // Impossible } @@ -2242,6 +2248,9 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, case STRING_RESULT: if (str->copy(value, length, collation.collation)) str= 0; // EOM error + case ROW_RESULT: + DBUG_ASSERT(1); // Impossible + break; } return(str); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cdca7454698..2ac7b0856bd 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -90,8 +90,9 @@ THD::THD():user_time(0), is_fatal_error(0), { host=user=priv_user=db=query=ip=0; host_or_ip= "connecting host"; - locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= + locked=killed=some_tables_deleted=no_errors=password= query_start_used=prepare_command=0; + count_cuted_fields= CHECK_FIELD_IGNORE; db_length=query_length=col_access=0; query_error= tmp_table_used= 0; next_insert_id=last_insert_id=0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 5e5d0335e9d..5c84f39c91b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -34,6 +34,9 @@ enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN} enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; +enum enum_check_fields { CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, + CHECK_FIELD_ERROR_FOR_NULL }; + extern char internal_table_name[2]; /* log info errors */ @@ -568,6 +571,7 @@ public: uint select_number; //number of select (used for EXPLAIN) /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; + enum_check_fields count_cuted_fields; /* for user variables replication*/ DYNAMIC_ARRAY user_var_events; @@ -575,7 +579,7 @@ public: char scramble[SCRAMBLE_LENGTH+1]; bool slave_thread; - bool set_query_id,locked,count_cuted_fields,some_tables_deleted; + bool set_query_id,locked,some_tables_deleted; bool last_cuted_field; bool no_errors, allow_sum_func, password, is_fatal_error; bool query_start_used,last_insert_id_used,insert_id_used,rand_used; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0ad66beec2e..b65245b04c1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -240,9 +240,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, info.handle_duplicates=duplic; info.update_fields=&update_fields; info.update_values=&update_values; - // Don't count warnings for simple inserts - if (values_list.elements > 1 || (thd->options & OPTION_WARNINGS)) - thd->count_cuted_fields = 1; + /* + Count warnings for all inserts. + For single line insert, generate an error if try to set a NOT NULL field + to NULL + */ + thd->count_cuted_fields= ((values_list.elements == 1) ? + CHECK_FIELD_ERROR_FOR_NULL : + CHECK_FIELD_WARN); thd->cuted_fields = 0L; table->next_number_field=table->found_next_number_field; @@ -394,7 +399,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, } thd->proc_info="end"; table->next_number_field=0; - thd->count_cuted_fields=0; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->next_insert_id=0; // Reset this if wrongly used if (duplic != DUP_ERROR) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); @@ -1391,7 +1396,7 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) restore_record(table,default_values); // Get empty record table->next_number_field=table->found_next_number_field; - thd->count_cuted_fields=1; // calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0; if (info.handle_duplicates != DUP_REPLACE) table->file->extra(HA_EXTRA_WRITE_CACHE); @@ -1409,7 +1414,7 @@ select_insert::~select_insert() table->next_number_field=0; table->file->extra(HA_EXTRA_RESET); } - thd->count_cuted_fields=0; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; } @@ -1559,7 +1564,7 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) table->next_number_field=table->found_next_number_field; restore_record(table,default_values); // Get empty record - thd->count_cuted_fields=1; // count warnings + thd->count_cuted_fields= CHECK_FIELD_WARN; // count warnings thd->cuted_fields=0; if (info.handle_duplicates == DUP_IGNORE || info.handle_duplicates == DUP_REPLACE) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 0a5c544c2e7..0e7895689b5 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -252,7 +252,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, restore_record(table,default_values); - thd->count_cuted_fields=1; /* calc cuted fields */ + thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ thd->cuted_fields=0L; if (ex->line_term->length() && field_term->length()) { @@ -293,7 +293,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (file >= 0) my_close(file,MYF(0)); free_blobs(table); /* if pack_blob was used */ table->copy_blobs=0; - thd->count_cuted_fields=0; /* Don`t calc cuted fields */ + thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* We must invalidate the table in query cache before binlog writing and diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4bab97d4a46..96b80f89bda 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3218,9 +3218,9 @@ store_val_in_field(Field *field,Item *item) bool error; THD *thd=current_thd; ha_rows cuted_fields=thd->cuted_fields; - thd->count_cuted_fields=1; + thd->count_cuted_fields= CHECK_FIELD_WARN; error= item->save_in_field(field, 1); - thd->count_cuted_fields=0; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; return error || cuted_fields != thd->cuted_fields; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 16afd592e59..8a736d91ffa 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2236,7 +2236,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (use_timestamp) new_table->time_stamp=0; new_table->next_number_field=new_table->found_next_number_field; - thd->count_cuted_fields=1; // calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0L; thd->proc_info="copy to tmp table"; next_insert_id=thd->next_insert_id; // Remember for loggin @@ -2246,7 +2246,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, handle_duplicates, order_num, order, &copied, &deleted); thd->last_insert_id=next_insert_id; // Needed for correct log - thd->count_cuted_fields=0; // Don`t calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_IGNORE; new_table->time_stamp=save_time_stamp; if (table->tmp_table) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2ecc526a612..f2185d265e1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -295,7 +295,7 @@ int mysql_update(THD *thd, init_read_record(&info,thd,table,select,0,1); updated= found= 0; - thd->count_cuted_fields=1; /* calc cuted fields */ + thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ thd->cuted_fields=0L; thd->proc_info="Updating"; query_id=thd->query_id; @@ -386,7 +386,7 @@ int mysql_update(THD *thd, thd->insert_id_used ? thd->insert_id() : 0L,buff); DBUG_PRINT("info",("%d records updated",updated)); } - thd->count_cuted_fields=0; /* calc cuted fields */ + thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ free_io_cache(table); DBUG_RETURN(0); @@ -492,7 +492,7 @@ int multi_update::prepare(List ¬_used_values, SELECT_LEX_UNIT *unit) uint i, max_fields; DBUG_ENTER("multi_update::prepare"); - thd->count_cuted_fields=1; + thd->count_cuted_fields= CHECK_FIELD_WARN; thd->cuted_fields=0L; thd->proc_info="updating main table"; @@ -733,7 +733,7 @@ multi_update::~multi_update() } if (copy_field) delete [] copy_field; - thd->count_cuted_fields=0; // Restore this setting + thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting if (!trans_safe) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; } From 6159df3ee3195ea7bd9bedf565851baa9df1d11e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Oct 2003 16:10:40 +0300 Subject: [PATCH 17/50] fixed fix_fields() parameters for GROUP_CONCAT() ORDER BY clause (BUG#1537) mysql-test/r/func_gconcat.result: test of BUG#1537 mysql-test/t/func_gconcat.test: test of BUG#1537 sql/item_sum.cc: passing correct address of pointer to item to fix_dields(), using that addres to get access to item after fix_fields --- mysql-test/r/func_gconcat.result | 11 +++++++++++ mysql-test/t/func_gconcat.test | 9 ++++++++- sql/item_sum.cc | 4 ++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 2b6079d5ffd..5eae6b4b871 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -196,3 +196,14 @@ insert into t1 values('test'),('test2'); select * from t1 having group_concat(bar)=''; bar drop table t1; +create table t1 (a int, a1 varchar(10)); +create table t2 (a0 int); +insert into t1 values (0,"a"),(0,"b"),(1,"c"); +insert into t2 values (1),(2),(3); +select group_concat(a1 order by (t1.a IN (select a0 from t2))) from t1; +group_concat(a1 order by (t1.a IN (select a0 from t2))) +b,a,c +select group_concat(a1 order by (t1.a)) from t1; +group_concat(a1 order by (t1.a)) +b,a,c +drop table t1, t2; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e82d732d42c..041225bdaf5 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -119,4 +119,11 @@ insert into t1 values('test'),('test2'); select * from t1 having group_concat(bar)=''; drop table t1; - +# ORDER BY fix_fields() +create table t1 (a int, a1 varchar(10)); +create table t2 (a0 int); +insert into t1 values (0,"a"),(0,"b"),(1,"c"); +insert into t2 values (1),(2),(3); +select group_concat(a1 order by (t1.a IN (select a0 from t2))) from t1; +select group_concat(a1 order by (t1.a)) from t1; +drop table t1, t2; \ No newline at end of file diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 967abbc5ab8..6a213962c6a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1773,8 +1773,8 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (i= 0 ; i < arg_count_order ; i++) { ORDER *order_item= order[i]; - Item *item=*order_item->item; - if (item->fix_fields(thd, tables, &item) || item->check_cols(1)) + if ((*order_item->item)->fix_fields(thd, tables, order_item->item) || + (*order_item->item)->check_cols(1)) return 1; } result_field= 0; From 1862f671606e086c68228903abb64d9727f95b72 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Oct 2003 15:16:45 +0200 Subject: [PATCH 18/50] wrong ER_TOO_BIG_FOR_UNCOMPRESS error in UNCOMPRESS() fixed. typo in error message text corrected. new tests added mysql-test/r/func_compress.result: new tests added mysql-test/t/func_compress.test: new tests added sql/item_strfunc.cc: max size of uncompressed data is max_allowed_packet not 8K sql/share/czech/errmsg.txt: typo fixed sql/share/danish/errmsg.txt: typo fixed sql/share/dutch/errmsg.txt: typo fixed sql/share/english/errmsg.txt: typo fixed sql/share/estonian/errmsg.txt: typo fixed sql/share/french/errmsg.txt: typo fixed sql/share/german/errmsg.txt: typo fixed sql/share/greek/errmsg.txt: typo fixed sql/share/hungarian/errmsg.txt: typo fixed sql/share/italian/errmsg.txt: typo fixed sql/share/japanese/errmsg.txt: typo fixed sql/share/korean/errmsg.txt: typo fixed sql/share/norwegian-ny/errmsg.txt: typo fixed sql/share/norwegian/errmsg.txt: typo fixed sql/share/polish/errmsg.txt: typo fixed sql/share/portuguese/errmsg.txt: typo fixed sql/share/romanian/errmsg.txt: typo fixed sql/share/russian/errmsg.txt: typo fixed sql/share/serbian/errmsg.txt: typo fixed sql/share/slovak/errmsg.txt: typo fixed sql/share/spanish/errmsg.txt: typo fixed sql/share/swedish/errmsg.txt: typo fixed sql/share/ukrainian/errmsg.txt: typo fixed --- mysql-test/r/func_compress.result | 20 ++++++++++++++++---- mysql-test/t/func_compress.test | 10 +++++++--- sql/item_strfunc.cc | 5 +++-- sql/share/czech/errmsg.txt | 4 ++-- sql/share/danish/errmsg.txt | 4 ++-- sql/share/dutch/errmsg.txt | 4 ++-- sql/share/english/errmsg.txt | 4 ++-- sql/share/estonian/errmsg.txt | 4 ++-- sql/share/french/errmsg.txt | 4 ++-- sql/share/german/errmsg.txt | 4 ++-- sql/share/greek/errmsg.txt | 4 ++-- sql/share/hungarian/errmsg.txt | 4 ++-- sql/share/italian/errmsg.txt | 4 ++-- sql/share/japanese/errmsg.txt | 4 ++-- sql/share/korean/errmsg.txt | 4 ++-- sql/share/norwegian-ny/errmsg.txt | 4 ++-- sql/share/norwegian/errmsg.txt | 4 ++-- sql/share/polish/errmsg.txt | 4 ++-- sql/share/portuguese/errmsg.txt | 4 ++-- sql/share/romanian/errmsg.txt | 4 ++-- sql/share/russian/errmsg.txt | 4 ++-- sql/share/serbian/errmsg.txt | 4 ++-- sql/share/slovak/errmsg.txt | 4 ++-- sql/share/spanish/errmsg.txt | 4 ++-- sql/share/swedish/errmsg.txt | 4 ++-- sql/share/ukrainian/errmsg.txt | 4 ++-- 26 files changed, 72 insertions(+), 55 deletions(-) diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 57eef44b3bb..85842f28e64 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -40,9 +40,21 @@ uncompress(compress("")) select uncompressed_length(""); uncompressed_length("") 0 -select compress(NULL); -compress(NULL) +create table t1 (a text); +insert t1 values (compress(null)), ('A\0\0\0BBBBBBBB'), (compress(space(50000))), (space(50000)); +select length(a) from t1; +length(a) NULL -select uncompress(NULL); -uncompress(NULL) +12 +76 +50000 +select length(uncompress(a)) from t1; +length(uncompress(a)) NULL +NULL +50000 +NULL +Warnings: +Error 1258 Z_DATA_ERROR: Input data was corrupted for zlib +Error 1255 Too big size of uncompressed data. The maximum size is 1048576. (probably, length of uncompressed data was corrupted) +drop table t1; diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 7462c020357..069fbed8562 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -24,8 +24,12 @@ select uncompress(compress("")); select uncompressed_length(""); # -# NULL (Bug #1333) +# errors # -select compress(NULL); -select uncompress(NULL); +create table t1 (a text); +insert t1 values (compress(null)), ('A\0\0\0BBBBBBBB'), (compress(space(50000))), (space(50000)); +select length(a) from t1; +select length(uncompress(a)) from t1; +drop table t1; + diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c8ee64dc707..55a20908894 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2609,11 +2609,12 @@ String *Item_func_uncompress::val_str(String *str) int err= Z_OK; uint code; - if (new_size > MAX_BLOB_WIDTH) + if (new_size > current_thd->variables.max_allowed_packet) { push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, ER_TOO_BIG_FOR_UNCOMPRESS, - ER(ER_TOO_BIG_FOR_UNCOMPRESS),MAX_BLOB_WIDTH); + ER(ER_TOO_BIG_FOR_UNCOMPRESS), + current_thd->variables.max_allowed_packet); null_value= 0; return 0; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 29d8b255251..e7cc54746b5 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -268,8 +268,8 @@ character-set=latin2 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index d603555727b..379865a775b 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -262,8 +262,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 53a19464745..ffe76be0d42 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -270,8 +270,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index c54f56b2529..c352b143ef1 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -259,8 +259,8 @@ character-set=latin1 "Slave is already running" "Slave has already been stopped" "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)" -"Z_BUF_ERROR: Not enough memory available for zlib" -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)" +"Z_MEM_ERROR: Not enough memory available for zlib" +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)" "Z_DATA_ERROR: Input data was corrupted for zlib" "%d line(s) was(were) cut by group_concat()" "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 2997a4d4501..657c5a24539 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -264,8 +264,8 @@ character-set=latin7 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index cd346270ea8..ab7936aff48 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -259,8 +259,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index bbace563bcb..f50169251f7 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -271,8 +271,8 @@ character-set=latin1 "Slave läuft bereits", "Slave wurde bereits angehalten", "Unkomprimierte Daten sind zu groß. Die maximale Größe beträgt %d", -"Z_BUF_ERROR: Für zlib steht nicht genug Speicher zur Verfügung", -"Z_MEM_ERROR: Im Ausgabepuffer ist nicht genug Platz für zlib vorhanden (wahrscheinlich wurde die Länge der unkomprimierten Daten beschädigt)", +"Z_MEM_ERROR: Für zlib steht nicht genug Speicher zur Verfügung", +"Z_BUF_ERROR: Im Ausgabepuffer ist nicht genug Platz für zlib vorhanden (wahrscheinlich wurde die Länge der unkomprimierten Daten beschädigt)", "Z_DATA_ERROR: Eingabedaten für zlib beschädigt", "%d Zeile(n) durch group_concat() abgeschnitten", "Anzahl der Datensätze in Zeile %ld geringer als Anzahl der Spalten", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 31259e9e02f..93f78bf2a93 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -259,8 +259,8 @@ character-set=greek "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 52dfb702231..f12fbbc938b 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -261,8 +261,8 @@ character-set=latin2 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 7efca542348..8d44a83ed3b 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -259,8 +259,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index f7d6d7be29b..dcd3db0d7a9 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -261,8 +261,8 @@ character-set=ujis "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 654081c6895..363d81e4dea 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -259,8 +259,8 @@ character-set=euckr "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 76f725a9419..e2427327c77 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -261,8 +261,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index fe15f7c9b8b..7083bd80085 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -261,8 +261,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 12e1d539e76..f770b2e3030 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin2 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 49ca7ee5c56..3c265349cdf 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -260,8 +260,8 @@ character-set=latin1 "O slave já está rodando", "O slave já está parado", "Tamanho muito grande dos dados des comprimidos. O máximo tamanho é %d. (provavelmente, o comprimento dos dados descomprimidos está corrupto)", -"Z_BUF_ERROR: Não suficiente memória disponível para zlib", -"Z_MEM_ERROR: Não suficiente espaço no buffer emissor para zlib (provavelmente, o comprimento dos dados descomprimidos está corrupto)", +"Z_MEM_ERROR: Não suficiente memória disponível para zlib", +"Z_BUF_ERROR: Não suficiente espaço no buffer emissor para zlib (provavelmente, o comprimento dos dados descomprimidos está corrupto)", "Z_DATA_ERROR: Dados de entrada está corrupto para zlib", "%d linha(s) foi(foram) cortada(s) por group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 30e87fe3d0a..c1c495d39c3 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin2 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index b444348612f..572d515453a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -261,8 +261,8 @@ character-set=koi8r "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 32b94548bc5..a81b5f56838 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -254,8 +254,8 @@ character-set=cp1250 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 45e40caedee..6ca9bcecf1c 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -267,8 +267,8 @@ character-set=latin2 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index bce03456941..62d32757719 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -261,8 +261,8 @@ character-set=latin1 "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 827419d76e7..f06a760bb24 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -259,8 +259,8 @@ character-set=latin1 "Slaven har redan startat", "Slaven har redan stoppat", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d rad(er) kapades av group_concat()", "Record count is fewer than the column count at row %ld"; diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index fcf0c695c29..675e9899d58 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -264,8 +264,8 @@ character-set=koi8u "Slave is already running", "Slave has already been stopped", "Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", -"Z_BUF_ERROR: Not enough memory available for zlib", -"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_MEM_ERROR: Not enough memory available for zlib", +"Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", "Record count is fewer than the column count at row %ld"; From d212ba604b22f8fad80489319a7ddc09d126ba67 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Oct 2003 11:20:19 +0300 Subject: [PATCH 19/50] Many files: ALTER TABLE ... DISCARD/IMPORT TABLESPACE Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x sql/ha_innodb.cc: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_class.cc: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_parse.cc: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_table.cc: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/ha_innodb.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/handler.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/lex.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/mysql_priv.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_class.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_lex.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE sql/sql_yacc.yy: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/ha/ha0ha.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/ha/hash0hash.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/buf/buf0buf.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/buf/buf0flu.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/buf/buf0lru.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/buf/buf0rea.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/btr/btr0btr.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/btr/btr0sea.c: Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x innobase/fil/fil0fil.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/buf0buf.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/ha0ha.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/hash0hash.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/row0mysql.h: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/buf0buf.ic: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/ha0ha.ic: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/include/ibuf0ibuf.ic: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/page/page0page.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/row/row0mysql.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/row/row0purge.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/row/row0uins.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE innobase/row/row0umod.c: ALTER TABLE ... DISCARD/IMPORT TABLESPACE --- innobase/btr/btr0btr.c | 3 +- innobase/btr/btr0sea.c | 4 +- innobase/buf/buf0buf.c | 32 ++++++++++++-- innobase/buf/buf0flu.c | 26 +++++++---- innobase/buf/buf0lru.c | 83 +++++++++++++++++++++++++---------- innobase/buf/buf0rea.c | 3 +- innobase/fil/fil0fil.c | 41 ++++++++++------- innobase/ha/ha0ha.c | 69 +++++++++++++++++++++++++---- innobase/ha/hash0hash.c | 1 + innobase/include/buf0buf.h | 7 +++ innobase/include/buf0buf.ic | 11 ++--- innobase/include/ha0ha.h | 2 +- innobase/include/ha0ha.ic | 35 +++------------ innobase/include/hash0hash.h | 4 +- innobase/include/ibuf0ibuf.ic | 2 +- innobase/include/row0mysql.h | 39 ++++++++++++++++ innobase/page/page0page.c | 3 +- innobase/row/row0mysql.c | 3 -- innobase/row/row0purge.c | 8 ++++ innobase/row/row0uins.c | 7 +++ innobase/row/row0umod.c | 7 +++ sql/ha_innodb.cc | 51 ++++++++++++++++++--- sql/ha_innodb.h | 1 + sql/handler.h | 1 + sql/lex.h | 3 ++ sql/mysql_priv.h | 1 + sql/sql_class.cc | 1 + sql/sql_class.h | 1 + sql/sql_lex.h | 6 +++ sql/sql_parse.cc | 4 +- sql/sql_table.cc | 77 +++++++++++++++++++++++++++++--- sql/sql_yacc.yy | 6 +++ 32 files changed, 424 insertions(+), 118 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 1af9336ce72..3d11cbe1748 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -426,7 +426,8 @@ btr_page_free_for_ibuf( flst_add_first(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr); - ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr)); + ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, + mtr)); } /****************************************************************** diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 8dbffd82a20..e49ee15f5ea 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -776,8 +776,8 @@ btr_search_guess_on_hash( goto failure; } - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); - ut_ad(page_rec_is_user_rec(rec)); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(page_rec_is_user_rec(rec)); btr_cur_position(index, rec, cursor); diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 1e1c6b25c1d..b403cc4df0d 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -468,6 +468,11 @@ buf_block_init( block->check_index_page_at_flush = FALSE; + block->in_free_list = FALSE; + block->in_LRU_list = FALSE; + + block->n_pointers = 0; + rw_lock_create(&(block->lock)); ut_ad(rw_lock_validate(&(block->lock))); @@ -687,6 +692,7 @@ buf_pool_init( } UT_LIST_ADD_LAST(free, buf_pool->free, block); + block->in_free_list = TRUE; } mutex_exit(&(buf_pool->mutex)); @@ -830,7 +836,7 @@ buf_page_make_young( block = buf_block_align(frame); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); buf_LRU_make_block_young(block); @@ -845,7 +851,7 @@ buf_block_free( /*===========*/ buf_block_t* block) /* in, own: block to be freed */ { - ut_ad(block->state != BUF_BLOCK_FILE_PAGE); + ut_a(block->state != BUF_BLOCK_FILE_PAGE); mutex_enter(&(buf_pool->mutex)); @@ -1109,6 +1115,8 @@ loop: goto loop; } + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + must_read = FALSE; if (block->io_fix == BUF_IO_READ) { @@ -1407,6 +1415,8 @@ buf_page_get_known_nowait( return(FALSE); } + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + #ifdef UNIV_SYNC_DEBUG buf_block_buf_fix_inc_debug(block, file, line); #else @@ -1517,7 +1527,7 @@ buf_page_init( buf_block_t* block) /* in: block to init */ { ut_ad(mutex_own(&(buf_pool->mutex))); - ut_ad(block->state == BUF_BLOCK_READY_FOR_USE); + ut_a(block->state != BUF_BLOCK_FILE_PAGE); /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; @@ -1533,6 +1543,18 @@ buf_page_init( /* Insert into the hash table of file pages */ + if (buf_page_hash_get(space, offset)) { + fprintf(stderr, +"InnoDB: Error: page %lu %lu already found from the hash table\n", space, + offset); + buf_print(); + buf_LRU_print(); + buf_validate(); + buf_LRU_validate(); + + ut_a(0); + } + HASH_INSERT(buf_block_t, hash, buf_pool->page_hash, buf_page_address_fold(space, offset), block); @@ -1605,7 +1627,7 @@ buf_page_init_for_read( block = buf_block_alloc(); - ut_ad(block); + ut_a(block); mutex_enter(&(buf_pool->mutex)); @@ -1769,6 +1791,8 @@ buf_page_io_complete( ut_ad(block); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + io_type = block->io_fix; if (io_type == BUF_IO_READ) { diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 3f8022f36bc..27a1829942d 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -50,6 +50,8 @@ buf_flush_insert_into_flush_list( { ut_ad(mutex_own(&(buf_pool->mutex))); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL) || (ut_dulint_cmp( (UT_LIST_GET_FIRST(buf_pool->flush_list)) @@ -131,7 +133,7 @@ buf_flush_ready_for_flush( ulint flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */ { ut_ad(mutex_own(&(buf_pool->mutex))); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) && (block->io_fix == 0)) { @@ -163,6 +165,8 @@ buf_flush_write_complete( ut_ad(block); ut_ad(mutex_own(&(buf_pool->mutex))); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + block->oldest_modification = ut_dulint_zero; UT_LIST_REMOVE(flush_list, buf_pool->flush_list, block); @@ -282,6 +286,8 @@ buf_flush_buffered_writes(void) for (i = 0; i < trx_doublewrite->first_free; i++) { block = trx_doublewrite->buf_block_arr[i]; + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER, FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE, (void*)block->frame, (void*)block); @@ -321,6 +327,8 @@ buf_flush_post_to_doublewrite_buf( try_again: mutex_enter(&(trx_doublewrite->mutex)); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + if (trx_doublewrite->first_free >= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { mutex_exit(&(trx_doublewrite->mutex)); @@ -395,6 +403,8 @@ buf_flush_write_block_low( /*======================*/ buf_block_t* block) /* in: buffer block to write */ { + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + #ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(block->space, block->offset) == 0); #endif @@ -443,7 +453,7 @@ buf_flush_try_page( block = buf_page_hash_get(space, offset); - ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); if (flush_type == BUF_FLUSH_LIST && block && buf_flush_ready_for_flush(block, flush_type)) { @@ -635,6 +645,7 @@ buf_flush_try_neighbors( for (i = low; i < high; i++) { block = buf_page_hash_get(space, i); + ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE); if (block && flush_type == BUF_FLUSH_LRU && i != offset && !block->old) { @@ -703,10 +714,10 @@ buf_flush_batch( ulint offset; ibool found; - ut_ad((flush_type == BUF_FLUSH_LRU) || (flush_type == BUF_FLUSH_LIST)); - ut_ad((flush_type != BUF_FLUSH_LIST) || - sync_thread_levels_empty_gen(TRUE)); - + ut_ad((flush_type == BUF_FLUSH_LRU) + || (flush_type == BUF_FLUSH_LIST)); + ut_ad((flush_type != BUF_FLUSH_LIST) + || sync_thread_levels_empty_gen(TRUE)); mutex_enter(&(buf_pool->mutex)); if ((buf_pool->n_flush[flush_type] > 0) @@ -737,7 +748,6 @@ buf_flush_batch( ut_ad(flush_type == BUF_FLUSH_LIST); block = UT_LIST_GET_LAST(buf_pool->flush_list); - if (!block || (ut_dulint_cmp(block->oldest_modification, lsn_limit) >= 0)) { @@ -756,6 +766,7 @@ buf_flush_batch( function a pointer to a block in the list! */ while ((block != NULL) && !found) { + ut_a(block->state == BUF_BLOCK_FILE_PAGE); if (buf_flush_ready_for_flush(block, flush_type)) { @@ -781,7 +792,6 @@ buf_flush_batch( } else if (flush_type == BUF_FLUSH_LRU) { block = UT_LIST_GET_PREV(LRU, block); - } else { ut_ad(flush_type == BUF_FLUSH_LIST); diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 5d48d460745..55a5ecbeba5 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -82,6 +82,8 @@ scan_again: block = UT_LIST_GET_LAST(buf_pool->LRU); while (block != NULL) { + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + if (block->space == id && (block->buf_fix_count > 0 || block->io_fix != 0)) { @@ -199,19 +201,16 @@ buf_LRU_search_and_free_block( mutex_enter(&(buf_pool->mutex)); freed = FALSE; - block = UT_LIST_GET_LAST(buf_pool->LRU); while (block != NULL) { - + ut_a(block->in_LRU_list); if (buf_flush_ready_for_replace(block)) { - if (buf_debug_prints) { printf( "Putting space %lu page %lu to free list\n", block->space, block->offset); } - buf_LRU_block_remove_hashed_page(block); mutex_exit(&(buf_pool->mutex)); @@ -223,25 +222,21 @@ buf_LRU_search_and_free_block( if (block->frame) { btr_search_drop_page_hash_index(block->frame); } - mutex_enter(&(buf_pool->mutex)); ut_a(block->buf_fix_count == 0); buf_LRU_block_free_hashed_page(block); - freed = TRUE; break; } - block = UT_LIST_GET_PREV(LRU, block); distance++; if (!freed && n_iterations <= 10 && distance > 100 + (n_iterations * buf_pool->curr_size) / 10) { - buf_pool->LRU_flush_ended = 0; mutex_exit(&(buf_pool->mutex)); @@ -249,15 +244,12 @@ buf_LRU_search_and_free_block( return(FALSE); } } - if (buf_pool->LRU_flush_ended > 0) { buf_pool->LRU_flush_ended--; } - - if (!freed) { + if (!freed) { buf_pool->LRU_flush_ended = 0; } - mutex_exit(&(buf_pool->mutex)); return(freed); @@ -355,7 +347,11 @@ loop: if (UT_LIST_GET_LEN(buf_pool->free) > 0) { block = UT_LIST_GET_FIRST(buf_pool->free); + ut_a(block->in_free_list); UT_LIST_REMOVE(free, buf_pool->free, block); + block->in_free_list = FALSE; + ut_a(block->state != BUF_BLOCK_FILE_PAGE); + ut_a(!block->in_LRU_list); if (srv_use_awe) { if (block->frame) { @@ -466,7 +462,7 @@ buf_LRU_old_adjust_len(void) ulint old_len; ulint new_len; - ut_ad(buf_pool->LRU_old); + ut_a(buf_pool->LRU_old); ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(3 * (BUF_LRU_OLD_MIN_LEN / 8) > BUF_LRU_OLD_TOLERANCE + 5); @@ -474,6 +470,8 @@ buf_LRU_old_adjust_len(void) old_len = buf_pool->LRU_old_len; new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8); + ut_a(buf_pool->LRU_old->in_LRU_list); + /* Update the LRU_old pointer if necessary */ if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) { @@ -490,7 +488,7 @@ buf_LRU_old_adjust_len(void) buf_pool->LRU_old); buf_pool->LRU_old_len--; } else { - ut_ad(buf_pool->LRU_old); /* Check that we did not + ut_a(buf_pool->LRU_old); /* Check that we did not fall out of the LRU list */ return; } @@ -498,9 +496,8 @@ buf_LRU_old_adjust_len(void) } /*********************************************************************** -Initializes the old blocks pointer in the LRU list. -This function should be called when the LRU list grows to -BUF_LRU_OLD_MIN_LEN length. */ +Initializes the old blocks pointer in the LRU list. This function should be +called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */ static void buf_LRU_old_init(void) @@ -508,7 +505,7 @@ buf_LRU_old_init(void) { buf_block_t* block; - ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN); + ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN); /* We first initialize all blocks in the LRU list as old and then use the adjust function to move the LRU_old pointer to the right @@ -517,6 +514,8 @@ buf_LRU_old_init(void) block = UT_LIST_GET_FIRST(buf_pool->LRU); while (block != NULL) { + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->in_LRU_list); block->old = TRUE; block = UT_LIST_GET_NEXT(LRU, block); } @@ -539,6 +538,9 @@ buf_LRU_remove_block( ut_ad(block); ut_ad(mutex_own(&(buf_pool->mutex))); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->in_LRU_list); + /* If the LRU_old pointer is defined and points to just this block, move it backward one step */ @@ -552,11 +554,12 @@ buf_LRU_remove_block( (buf_pool->LRU_old)->old = TRUE; buf_pool->LRU_old_len++; - ut_ad(buf_pool->LRU_old); + ut_a(buf_pool->LRU_old); } /* Remove the block from the LRU list */ UT_LIST_REMOVE(LRU, buf_pool->LRU, block); + block->in_LRU_list = FALSE; if (srv_use_awe && block->frame) { /* Remove from the list of mapped pages */ @@ -599,6 +602,8 @@ buf_LRU_add_block_to_end_low( ut_ad(block); ut_ad(mutex_own(&(buf_pool->mutex))); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + block->old = TRUE; last_block = UT_LIST_GET_LAST(buf_pool->LRU); @@ -609,7 +614,9 @@ buf_LRU_add_block_to_end_low( block->LRU_position = buf_pool_clock_tic(); } + ut_a(!block->in_LRU_list); UT_LIST_ADD_LAST(LRU, buf_pool->LRU, block); + block->in_LRU_list = TRUE; if (srv_use_awe && block->frame) { /* Add to the list of mapped pages */ @@ -658,6 +665,9 @@ buf_LRU_add_block_low( ut_ad(block); ut_ad(mutex_own(&(buf_pool->mutex))); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(!block->in_LRU_list); + block->old = old; cl = buf_pool_clock_tic(); @@ -687,6 +697,8 @@ buf_LRU_add_block_low( block->LRU_position = (buf_pool->LRU_old)->LRU_position; } + block->in_LRU_list = TRUE; + if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) { ut_ad(buf_pool->LRU_old); @@ -755,9 +767,12 @@ buf_LRU_block_free_non_file_page( ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(block); - ut_ad((block->state == BUF_BLOCK_MEMORY) + ut_a((block->state == BUF_BLOCK_MEMORY) || (block->state == BUF_BLOCK_READY_FOR_USE)); + ut_a(block->n_pointers == 0); + ut_a(!block->in_free_list); + block->state = BUF_BLOCK_NOT_USED; #ifdef UNIV_DEBUG @@ -765,6 +780,7 @@ buf_LRU_block_free_non_file_page( memset(block->frame, '\0', UNIV_PAGE_SIZE); #endif UT_LIST_ADD_FIRST(free, buf_pool->free, block); + block->in_free_list = TRUE; if (srv_use_awe && block->frame) { /* Add to the list of mapped pages */ @@ -788,8 +804,7 @@ buf_LRU_block_remove_hashed_page( ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(block); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); - + ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->io_fix == 0); ut_a(block->buf_fix_count == 0); ut_a(ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) == 0); @@ -802,6 +817,28 @@ buf_LRU_block_remove_hashed_page( buf_block_modify_clock_inc(block); + if (block != buf_page_hash_get(block->space, block->offset)) { + fprintf(stderr, +"InnoDB: Error: page %lu %lu not found from the hash table\n", + block->space, + block->offset); + if (buf_page_hash_get(block->space, block->offset)) { + fprintf(stderr, +"InnoDB: From hash table we find block %lx of %lu %lu which is not %lx\n", + (ulint)buf_page_hash_get(block->space, block->offset), + buf_page_hash_get(block->space, block->offset)->space, + buf_page_hash_get(block->space, block->offset)->offset, + (ulint)block); + } + + buf_print(); + buf_LRU_print(); + buf_validate(); + buf_LRU_validate(); + + ut_a(0); + } + HASH_DELETE(buf_block_t, hash, buf_pool->page_hash, buf_page_address_fold(block->space, block->offset), block); @@ -819,7 +856,7 @@ buf_LRU_block_free_hashed_page( be in a state where it can be freed */ { ut_ad(mutex_own(&(buf_pool->mutex))); - ut_ad(block->state == BUF_BLOCK_REMOVE_HASH); + ut_a(block->state == BUF_BLOCK_REMOVE_HASH); block->state = BUF_BLOCK_MEMORY; diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 8cc379e75d8..0fa6912ba1d 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -129,6 +129,8 @@ buf_read_page_low( offset, sync); } + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + *err = fil_io(OS_FILE_READ | wake_later, sync, space, offset, 0, UNIV_PAGE_SIZE, @@ -604,7 +606,6 @@ buf_read_ibuf_merge_pages( } for (i = 0; i < n_stored; i++) { - if ((i + 1 == n_stored) && sync) { buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space_ids[i], space_versions[i], page_nos[i]); diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 2b0138ccb5a..f96d98c7b2d 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1517,8 +1517,8 @@ try_again: if (space == NULL) { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: Error: cannot delete tablespace %lu because it is not found\n" -"InnoDB: in the tablespace memory cache.\n", id); +" InnoDB: Error: cannot delete tablespace %lu\n" +"InnoDB: because it is not found in the tablespace memory cache.\n", id); mutex_exit(&(system->mutex)); @@ -2426,19 +2426,24 @@ fil_space_for_table_exists_in_mem( if (namespace == NULL) { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: Error: table %s in InnoDB data dictionary has tablespace\n" -"InnoDB: id %lu, but tablespace with that id or name does not exist. Have\n" -"InnoDB: you deleted or moved .ibd files? We cannot open table %s now.\n", - name, id, name); +" InnoDB: Error: table %s\n" +"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n" +"InnoDB: but tablespace with that id or name does not exist. Have\n" +"InnoDB: you deleted or moved .ibd files?\n", + name, id); } else { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: Error: table %s in InnoDB data dictionary has tablespace\n" -"InnoDB: id %lu, but tablespace with that id does not exist. There is\n" +" InnoDB: Error: table %s\n" +"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n" +"InnoDB: but tablespace with that id does not exist. There is\n" "InnoDB: a tablespace of name %s and id %lu, though. Have\n" -"InnoDB: you deleted or moved .ibd files? We cannot open table %s now.\n", - name, id, namespace->name, namespace->id, name); +"InnoDB: you deleted or moved .ibd files?\n", + name, id, namespace->name, namespace->id); } + fprintf(stderr, +"InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" +"InnoDB: how to resolve the issue.\n"); mutex_exit(&(system->mutex)); @@ -2448,16 +2453,20 @@ fil_space_for_table_exists_in_mem( if (0 != strcmp(space->name, path)) { ut_print_timestamp(stderr); fprintf(stderr, -" InnoDB: Error: table %s in InnoDB data dictionary has tablespace\n" -"InnoDB: id %lu, but tablespace with that id has name %s. Have you\n" -"InnoDB: deleted or moved .ibd files? We cannot open table %s now.\n", - name, id, space->name, name); +" InnoDB: Error: table %s\n" +"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n" +"InnoDB: but tablespace with that id has name %s.\n" +"InnoDB: Have you deleted or moved .ibd files?", name, id, space->name); if (namespace != NULL) { fprintf(stderr, -"InnoDB: There is a tablespace with the right name %s, but its id is %lu.\n", - namespace->name, namespace->id); +"InnoDB: There is a tablespace with the right name\n" +"InnoDB: %s, but its id is %lu.\n", namespace->name, namespace->id); } + fprintf(stderr, +"InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" +"InnoDB: how to resolve the issue.\n"); + mutex_exit(&(system->mutex)); return(FALSE); diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index c7e23d0be1e..87c32bf5dbd 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -34,6 +34,12 @@ ha_create( table = hash_create(n); + if (in_btr_search) { + table->adaptive = TRUE; + } else { + table->adaptive = FALSE; + } + if (n_mutexes == 0) { if (in_btr_search) { table->heap = mem_heap_create_in_btr_search(4096); @@ -106,6 +112,7 @@ ha_insert_for_fold( hash_cell_t* cell; ha_node_t* node; ha_node_t* prev_node; + buf_block_t* prev_block; ulint hash; ut_ad(table && data); @@ -119,6 +126,12 @@ ha_insert_for_fold( while (prev_node != NULL) { if (prev_node->fold == fold) { + if (table->adaptive) { + prev_block = buf_block_align(prev_node->data); + ut_a(prev_block->n_pointers > 0); + prev_block->n_pointers--; + buf_block_align(data)->n_pointers++; + } prev_node->data = data; @@ -142,6 +155,11 @@ ha_insert_for_fold( } ha_node_set_data(node, data); + + if (table->adaptive) { + buf_block_align(data)->n_pointers++; + } + node->fold = fold; node->next = NULL; @@ -174,6 +192,11 @@ ha_delete_hash_node( hash_table_t* table, /* in: hash table */ ha_node_t* del_node) /* in: node to be deleted */ { + if (table->adaptive) { + ut_a(buf_block_align(del_node->data)->n_pointers > 0); + buf_block_align(del_node->data)->n_pointers--; + } + HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node); } @@ -199,6 +222,35 @@ ha_delete( ha_delete_hash_node(table, node); } +/************************************************************* +Looks for an element when we know the pointer to the data, and updates +the pointer to data, if found. */ + +void +ha_search_and_update_if_found( +/*==========================*/ + hash_table_t* table, /* in: hash table */ + ulint fold, /* in: folded value of the searched data */ + void* data, /* in: pointer to the data */ + void* new_data)/* in: new pointer to the data */ +{ + ha_node_t* node; + + ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); + + node = ha_search_with_data(table, fold, data); + + if (node) { + if (table->adaptive) { + ut_a(buf_block_align(node->data)->n_pointers > 0); + buf_block_align(node->data)->n_pointers--; + buf_block_align(new_data)->n_pointers++; + } + + node->data = new_data; + } +} + /********************************************************************* Removes from the chain determined by fold all nodes whose data pointer points to the page given. */ @@ -229,10 +281,10 @@ ha_remove_all_nodes_to_page( node = ha_chain_get_first(table, fold); } else { - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } } - +#ifdef UNIV_DEBUG /* Check that all nodes really got deleted */ node = ha_chain_get_first(table, fold); @@ -240,8 +292,9 @@ ha_remove_all_nodes_to_page( while (node) { ut_a(buf_frame_align(ha_node_get_data(node)) != page); - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } +#endif } /***************************************************************** @@ -293,12 +346,10 @@ ha_print_info( hash_table_t* table) /* in: hash table */ { hash_cell_t* cell; -/* - ha_node_t* node; - ulint len = 0; - ulint max_len = 0; - ulint nodes = 0; -*/ +/* ha_node_t* node; + ulint nodes = 0; + ulint len = 0; + ulint max_len = 0; */ ulint cells = 0; ulint n_bufs; ulint i; diff --git a/innobase/ha/hash0hash.c b/innobase/ha/hash0hash.c index 1f7edf9d7d2..facdea66198 100644 --- a/innobase/ha/hash0hash.c +++ b/innobase/ha/hash0hash.c @@ -91,6 +91,7 @@ hash_create( array = ut_malloc(sizeof(hash_cell_t) * prime); + table->adaptive = FALSE; table->array = array; table->n_cells = prime; table->n_mutexes = 0; diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 0457da60534..3f2fd5bbbe0 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -755,12 +755,16 @@ struct buf_block_struct{ UT_LIST_NODE_T(buf_block_t) free; /* node of the free block list */ + ibool in_free_list; /* TRUE if in the free list; used in + debugging */ UT_LIST_NODE_T(buf_block_t) LRU; /* node of the LRU list */ UT_LIST_NODE_T(buf_block_t) awe_LRU_free_mapped; /* in the AWE version node in the list of free and LRU blocks which are mapped to a frame */ + ibool in_LRU_list; /* TRUE of the page is in the LRU list; + used in debugging */ ulint LRU_position; /* value which monotonically decreases (or may stay constant if the block is in the old blocks) toward @@ -821,6 +825,9 @@ struct buf_block_struct{ complete, though: there may have been hash collisions, record deletions, etc. */ + ulint n_pointers; /* used in debugging: the number of + pointers in the adaptive hash index + pointing to this frame */ ulint curr_n_fields; /* prefix length for hash indexing: number of full fields */ ulint curr_n_bytes; /* number of bytes in hash indexing */ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index d4e7122f3f9..281bb1ea527 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -28,7 +28,6 @@ buf_block_peek_if_too_old( { if (buf_pool->freed_page_clock >= block->freed_page_clock + 1 + (buf_pool->curr_size / 1024)) { - return(TRUE); } @@ -169,7 +168,7 @@ buf_block_get_space( ut_ad(block); ut_ad(block >= buf_pool->blocks); ut_ad(block < buf_pool->blocks + buf_pool->max_size); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->buf_fix_count > 0); return(block->space); @@ -187,7 +186,7 @@ buf_block_get_page_no( ut_ad(block); ut_ad(block >= buf_pool->blocks); ut_ad(block < buf_pool->blocks + buf_pool->max_size); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->buf_fix_count > 0); return(block->offset); @@ -550,6 +549,8 @@ buf_page_hash_get( HASH_SEARCH(hash, buf_pool->page_hash, fold, block, (block->space == space) && (block->offset == offset)); + ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE); + return(block); } @@ -617,8 +618,8 @@ buf_page_release( mutex_enter_fast(&(buf_pool->mutex)); - ut_ad(block->state == BUF_BLOCK_FILE_PAGE); - ut_ad(block->buf_fix_count > 0); + ut_a(block->state == BUF_BLOCK_FILE_PAGE); + ut_a(block->buf_fix_count > 0); if (rw_latch == RW_X_LATCH && mtr->modifications) { diff --git a/innobase/include/ha0ha.h b/innobase/include/ha0ha.h index 0beac928b7e..c3fc04b47bb 100644 --- a/innobase/include/ha0ha.h +++ b/innobase/include/ha0ha.h @@ -28,7 +28,7 @@ ha_search_and_get_data( /************************************************************* Looks for an element when we know the pointer to the data and updates the pointer to data if found. */ -UNIV_INLINE + void ha_search_and_update_if_found( /*==========================*/ diff --git a/innobase/include/ha0ha.ic b/innobase/include/ha0ha.ic index 761bc3b20de..22da7107659 100644 --- a/innobase/include/ha0ha.ic +++ b/innobase/include/ha0ha.ic @@ -49,7 +49,6 @@ ha_node_t* ha_chain_get_next( /*==============*/ /* out: next node, NULL if none */ - hash_table_t* table __attribute__((unused)), /* in: hash table */ ha_node_t* node) /* in: hash chain node */ { ut_ad(table); @@ -94,7 +93,7 @@ ha_search( return(node); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); @@ -124,7 +123,7 @@ ha_search_and_get_data( return(node->data); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); @@ -139,7 +138,6 @@ ha_next( /* out: pointer to the next hash table node in chain with the fold value, NULL if not found */ - hash_table_t* table, /* in: hash table */ ha_node_t* node) /* in: hash table node */ { ulint fold; @@ -148,7 +146,7 @@ ha_next( ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); while (node) { if (node->fold == fold) { @@ -156,7 +154,7 @@ ha_next( return(node); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); @@ -186,35 +184,12 @@ ha_search_with_data( return(node); } - node = ha_chain_get_next(table, node); + node = ha_chain_get_next(node); } return(NULL); } -/************************************************************* -Looks for an element when we know the pointer to the data, and updates -the pointer to data, if found. */ -UNIV_INLINE -void -ha_search_and_update_if_found( -/*==========================*/ - hash_table_t* table, /* in: hash table */ - ulint fold, /* in: folded value of the searched data */ - void* data, /* in: pointer to the data */ - void* new_data)/* in: new pointer to the data */ -{ - ha_node_t* node; - - ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); - - node = ha_search_with_data(table, fold, data); - - if (node) { - node->data = new_data; - } -} - /************************************************************* Looks for an element when we know the pointer to the data, and deletes it from the hash table, if found. */ diff --git a/innobase/include/hash0hash.h b/innobase/include/hash0hash.h index 378925a5bea..2e9ab498116 100644 --- a/innobase/include/hash0hash.h +++ b/innobase/include/hash0hash.h @@ -100,7 +100,7 @@ Deletes a struct from a hash table. */ \ while (struct3333->NAME != DATA) {\ \ - ut_ad(struct3333)\ + ut_a(struct3333)\ struct3333 = struct3333->NAME;\ }\ \ @@ -322,6 +322,8 @@ struct hash_cell_struct{ /* The hash table structure */ struct hash_table_struct { + ibool adaptive;/* TRUE if this is the hash table of the + adaptive hash index */ ulint n_cells;/* number of cells in the hash table */ hash_cell_t* array; /* pointer to cell array */ ulint n_mutexes;/* if mutexes != NULL, then the number of diff --git a/innobase/include/ibuf0ibuf.ic b/innobase/include/ibuf0ibuf.ic index 0886c8c02cc..68f7ce9c1d0 100644 --- a/innobase/include/ibuf0ibuf.ic +++ b/innobase/include/ibuf0ibuf.ic @@ -218,7 +218,7 @@ ibuf_update_free_bits_if_full( } if (after == 0) { - /* We move the page to front of the buffer pool LRU list: + /* We move the page to the front of the buffer pool LRU list: the purpose of this is to prevent those pages to which we cannot make inserts using the insert buffer from slipping out of the buffer pool */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 1964f53dabb..fade3709631 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -339,6 +339,45 @@ row_drop_table_for_mysql( char* name, /* in: table name */ trx_t* trx); /* in: transaction handle */ /************************************************************************* +Discards the tablespace of a table which stored in an .ibd file. Discarding +means that this function deletes the .ibd file and assigns a new table id for +the table. Also the flag table->ibd_file_missing is set TRUE. + +How do we prevent crashes caused by ongoing operations on the table? Old +operations could try to access non-existent pages. + +1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock +on the table before we can do DISCARD TABLESPACE. Then there are no running +queries on the table. +2) Purge and rollback: we assign a new table id for the table. Since purge and +rollback look for the table based on the table id, they see the table as +'dropped' and discard their operations. +3) Insert buffer: we remove all entries for the tablespace in the insert +buffer tree; as long as the tablespace mem object does not exist, ongoing +insert buffer page merges are discarded in buf0rea.c. If we recreate the +tablespace mem object with IMPORT TABLESPACE later, then the tablespace will +have the same id, but the tablespace_version field in the mem object is +different, and ongoing old insert buffer page merges get discarded. +4) Linear readahead and random readahead: we use the same method as in 3) to +discard ongoing operations. */ + +int +row_discard_tablespace_for_mysql( +/*=============================*/ + /* out: error code or DB_SUCCESS */ + char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ +/********************************************************************* +Imports a tablespace. The space id in the .ibd file must match the space id +of the table in the data dictionary. */ + +int +row_import_tablespace_for_mysql( +/*============================*/ + /* out: error code or DB_SUCCESS */ + char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ +/************************************************************************* Drops a database for MySQL. */ int diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index e087941a970..2422f0ff87e 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -582,7 +582,8 @@ byte* page_parse_delete_rec_list( /*=======================*/ /* out: end of log record or NULL */ - byte type, /* in: MLOG_LIST_END_DELETE or MLOG_LIST_START_DELETE */ + byte type, /* in: MLOG_LIST_END_DELETE or + MLOG_LIST_START_DELETE */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ page_t* page, /* in: page or NULL */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 497b74fd320..5d5985d16af 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2007,9 +2007,6 @@ row_import_tablespace_for_mysql( success = fil_open_single_table_tablespace(table->space, table->name); - printf( -"Remember to stop purge + undo if table->ibd_file_is_missing!!!\n"); - if (success) { table->ibd_file_missing = FALSE; table->tablespace_discarded = FALSE; diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 104d71eda2d..99332dc275d 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -529,6 +529,14 @@ row_purge_parse_undo_rec( return(FALSE); } + if (node->table->ibd_file_missing) { + /* We skip purge of missing .ibd files */ + + node->table = NULL; + + return; + } + clust_index = dict_table_get_first_index(node->table); if (clust_index == NULL) { diff --git a/innobase/row/row0uins.c b/innobase/row/row0uins.c index fff67dcd627..08f0e29c839 100644 --- a/innobase/row/row0uins.c +++ b/innobase/row/row0uins.c @@ -258,6 +258,13 @@ row_undo_ins_parse_undo_rec( return; } + if (node->table->ibd_file_missing) { + /* We skip undo operations to missing .ibd files */ + node->table = NULL; + + return; + } + clust_index = dict_table_get_first_index(node->table); ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index b22e494f891..0a050e0a1b6 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -620,6 +620,13 @@ row_undo_mod_parse_undo_rec( return; } + if (node->table->ibd_file_missing) { + /* We skip undo operations to missing .ibd files */ + node->table = NULL; + + return; + } + clust_index = dict_table_get_first_index(node->table); ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f1072c3137a..d07b166d9e2 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1451,7 +1451,7 @@ ha_innobase::open( DBUG_RETURN(1); } - if (ib_table->ibd_file_missing) { + if (ib_table->ibd_file_missing && !current_thd->tablespace_op) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to open a table handle but the .ibd file for\n" @@ -3628,6 +3628,42 @@ ha_innobase::create( DBUG_RETURN(0); } +/********************************************************************* +Discards or imports an InnoDB tablespace. */ + +int +ha_innobase::discard_or_import_tablespace( +/*======================================*/ + /* out: 0 == success, -1 == error */ + my_bool discard) /* in: TRUE if discard, else import */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + dict_table_t* table; + trx_t* trx; + int err; + + DBUG_ENTER("ha_innobase::discard_or_import_tablespace"); + + ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + + table = prebuilt->table; + trx = prebuilt->trx; + + if (discard) { + err = row_discard_tablespace_for_mysql(table->name, trx); + } else { + err = row_import_tablespace_for_mysql(table->name, trx); + } + + if (err == DB_SUCCESS) { + DBUG_RETURN(0); + } + + DBUG_RETURN(-1); +} + /********************************************************************* Drops a table from an InnoDB database. Before calling this function, MySQL calls innobase_commit to commit the transaction of the current user. @@ -3647,7 +3683,7 @@ ha_innobase::delete_table( trx_t* trx; char norm_name[1000]; - DBUG_ENTER("ha_innobase::delete_table"); + DBUG_ENTER("ha_innobase::delete_table"); /* Get the transaction associated with the current thd, or create one if not yet created */ @@ -4536,7 +4572,8 @@ ha_innobase::external_lock( update_thd(thd); - if (lock_type != F_UNLCK && prebuilt->table->ibd_file_missing) { + if (lock_type != F_UNLCK && prebuilt->table->ibd_file_missing + && !current_thd->tablespace_op) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" @@ -4546,6 +4583,7 @@ ha_innobase::external_lock( "Look from section 15.1 of http://www.innodb.com/ibman.html\n" "how you can resolve the problem.\n", prebuilt->table->name); + DBUG_RETURN(HA_ERR_CRASHED); } trx = prebuilt->trx; @@ -4793,11 +4831,12 @@ ha_innobase::store_lock( if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { - /* If we are not doing a LOCK TABLE, then allow multiple - writers */ + /* If we are not doing a LOCK TABLE or DISCARD/IMPORT + TABLESPACE, then allow multiple writers */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && - lock_type <= TL_WRITE) && !thd->in_lock_tables) { + lock_type <= TL_WRITE) && !thd->in_lock_tables + && !thd->tablespace_op) { lock_type = TL_WRITE_ALLOW_WRITE; } diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index b17097b3c57..0c89a9d29ce 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -160,6 +160,7 @@ class ha_innobase: public handler void info(uint); int analyze(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd,HA_CHECK_OPT* check_opt); + int discard_or_import_tablespace(my_bool discard); int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); diff --git a/sql/handler.h b/sql/handler.h index b74e06c6edf..b756d9a09fb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -317,6 +317,7 @@ public: virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; } virtual void deactivate_non_unique_index(ha_rows rows) {} virtual bool activate_all_index(THD *thd) {return 0;} + virtual int discard_or_import_tablespace(my_bool discard) {return -1;} // not implemented by default virtual int net_read_dump(NET* net) { return ER_DUMP_NOT_IMPLEMENTED; } diff --git a/sql/lex.h b/sql/lex.h index e11b50ed16d..859f92dd752 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -130,6 +130,7 @@ static SYMBOL symbols[] = { { "DESCRIBE", SYM(DESCRIBE),0,0}, { "DIRECTORY", SYM(DIRECTORY_SYM),0,0}, { "DISABLE", SYM(DISABLE_SYM),0,0}, + { "DISCARD", SYM(DISCARD),0,0}, { "DISTINCT", SYM(DISTINCT),0,0}, { "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */ { "DIV", SYM(DIV_SYM),0,0}, @@ -200,6 +201,7 @@ static SYMBOL symbols[] = { { "INNER", SYM(INNER_SYM),0,0}, { "INNOBASE", SYM(INNOBASE_SYM),0,0}, { "INNODB", SYM(INNOBASE_SYM),0,0}, + { "IMPORT", SYM(IMPORT),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, @@ -387,6 +389,7 @@ static SYMBOL symbols[] = { { "SUPER", SYM(SUPER_SYM),0,0}, { "TABLE", SYM(TABLE_SYM),0,0}, { "TABLES", SYM(TABLES),0,0}, + { "TABLESPACE", SYM(TABLESPACE),0,0}, { "TEMPORARY", SYM(TEMPORARY),0,0}, { "TERMINATED", SYM(TERMINATED),0,0}, { "TEXT", SYM(TEXT_SYM),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index afbda2b4ad1..a1919bf1a0e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -486,6 +486,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, + enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, bool simple_alter=0); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cdca7454698..c7d77c67236 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -173,6 +173,7 @@ THD::THD():user_time(0), is_fatal_error(0), protocol_simple.init(this); protocol_prep.init(this); + tablespace_op=FALSE; #ifdef USING_TRANSACTIONS bzero((char*) &transaction,sizeof(transaction)); if (opt_using_transactions) diff --git a/sql/sql_class.h b/sql/sql_class.h index 5e5d0335e9d..146ee18e3e2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -502,6 +502,7 @@ public: time_t connect_time,thr_create_time; // track down slow pthread_create thr_lock_type update_lock_default; delayed_insert *di; + my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ struct st_transactions { IO_CACHE trans_log; THD_TRANS all; // Trans since BEGIN WORK diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8ce028020c2..0166951ab9d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -110,6 +110,11 @@ enum olap_type UNSPECIFIED_OLAP_TYPE, CUBE_TYPE, ROLLUP_TYPE }; +enum tablespace_op_type +{ + NO_TABLESPACE_OP, DISCARD_TABLESPACE, IMPORT_TABLESPACE +}; + /* The state of the lex parsing for selects @@ -530,6 +535,7 @@ typedef struct st_lex enum ha_rkey_function ha_rkey_mode; enum enum_enable_or_disable alter_keys_onoff; enum enum_var_type option_type; + enum tablespace_op_type tablespace_op; uint uint_geom_type; uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e30fd0acfae..248dfc0e47a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2207,7 +2207,9 @@ mysql_execute_command(THD *thd) select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, lex->drop_primary, lex->duplicates, - lex->alter_keys_onoff, lex->simple_alter); + lex->alter_keys_onoff, + lex->tablespace_op, + lex->simple_alter); } break; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 16afd592e59..3840e29f04a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1748,6 +1748,70 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) &handler::check)); } +/* table_list should contain just one table */ +int mysql_discard_or_import_tablespace(THD *thd, + TABLE_LIST *table_list, + enum tablespace_op_type tablespace_op) +{ + TABLE *table; + my_bool discard; + int error; + DBUG_ENTER("mysql_discard_or_import_tablespace"); + + /* Note that DISCARD/IMPORT TABLESPACE always is the only operation in an + ALTER TABLE */ + + thd->proc_info="discard_or_import_tablespace"; + + if (tablespace_op == DISCARD_TABLESPACE) + discard = TRUE; + else + discard = FALSE; + + thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open + and ::external_lock() do not complain when we + lock the table */ + mysql_ha_closeall(thd, table_list); + + if (!(table=open_ltable(thd,table_list,TL_WRITE))) + { + thd->tablespace_op=FALSE; + DBUG_RETURN(-1); + } + + thd->tablespace_op=FALSE; + + error=table->file->discard_or_import_tablespace(discard); + + thd->proc_info="end"; + + if (error) + goto err; + + /* The 0 in the call below means 'not in a transaction', which means + immediate invalidation; that is probably what we wish here */ + query_cache_invalidate3(thd, table_list, 0); + + /* The ALTER TABLE is always in its own transaction */ + error = ha_commit_stmt(thd); + if (ha_commit(thd)) + error=1; + if (error) + goto err; + mysql_update_log.write(thd, thd->query,thd->query_length); + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); + } +err: + close_thread_tables(thd); + if (error == 0) { + send_ok(thd); + DBUG_RETURN(0); + } + DBUG_RETURN(error); +} int mysql_alter_table(THD *thd,char *new_db, char *new_name, HA_CREATE_INFO *create_info, @@ -1759,6 +1823,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff, + enum tablespace_op_type tablespace_op, bool simple_alter) { TABLE *table,*new_table; @@ -1771,6 +1836,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ulonglong next_insert_id; uint save_time_stamp,db_create_options, used_fields; enum db_type old_db_type,new_db_type; + thr_lock_type lock_type; DBUG_ENTER("mysql_alter_table"); thd->proc_info="init"; @@ -1781,6 +1847,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, used_fields=create_info->used_fields; mysql_ha_closeall(thd, table_list); + + if (tablespace_op != NO_TABLESPACE_OP) + DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, + tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -1834,8 +1904,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; - /* In some simple cases we need not to recreate the table */ - thd->proc_info="setup"; if (simple_alter && !table->tmp_table) { @@ -1860,6 +1928,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } VOID(pthread_mutex_unlock(&LOCK_open)); } + if (!error) { switch (keys_onoff) { @@ -2395,8 +2464,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } } - - /* The ALTER TABLE is always in it's own transaction */ + /* The ALTER TABLE is always in its own transaction */ error = ha_commit_stmt(thd); if (ha_commit(thd)) error=1; @@ -2695,4 +2763,3 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) table->table=0; DBUG_RETURN(-1); } - diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 81a59196e3c..f917e4ec027 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -211,6 +211,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token DESCRIBE %token DES_KEY_FILE %token DISABLE_SYM +%token DISCARD %token DISTINCT %token DUPLICATE_SYM %token DYNAMIC_SYM @@ -244,6 +245,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token HOSTS_SYM %token IDENT %token IGNORE_SYM +%token IMPORT %token INDEX %token INDEXES %token INFILE @@ -360,6 +362,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SUBJECT_SYM %token TABLES %token TABLE_SYM +%token TABLESPACE %token TEMPORARY %token TERMINATED %token TEXT_STRING @@ -1635,6 +1638,7 @@ alter: lex->create_info.table_charset= thd->variables.collation_database; lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->alter_keys_onoff=LEAVE_AS_IS; + lex->tablespace_op=NO_TABLESPACE_OP; lex->simple_alter=1; } alter_list @@ -1648,6 +1652,8 @@ alter: alter_list: + | DISCARD TABLESPACE { Lex->tablespace_op=DISCARD_TABLESPACE; } + | IMPORT TABLESPACE { Lex->tablespace_op=IMPORT_TABLESPACE; } | alter_list_item | alter_list ',' alter_list_item; From 184ebe591e7c3739a36e3bcf6c10ae086250da77 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 01:52:03 +0300 Subject: [PATCH 20/50] sql_yacc.yy: Add DISCARD etc. in the keyword: rule of sql_yacc.yy sql_table.cc: Add comment that DISCARD/IMPORT TABLESPACE is always the only clause in an ALTER TABLE sql/sql_table.cc: Add comment that DISCARD/IMPORT TABLESPACE is always the only clause in an ALTER TABLE sql/sql_yacc.yy: Add DISCARD etc. in the keyword: rule of sql_yacc.yy --- sql/sql_table.cc | 4 ++-- sql/sql_yacc.yy | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3840e29f04a..9de4ef1a1ac 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1779,8 +1779,6 @@ int mysql_discard_or_import_tablespace(THD *thd, DBUG_RETURN(-1); } - thd->tablespace_op=FALSE; - error=table->file->discard_or_import_tablespace(discard); thd->proc_info="end"; @@ -1806,6 +1804,7 @@ int mysql_discard_or_import_tablespace(THD *thd, } err: close_thread_tables(thd); + thd->tablespace_op=FALSE; if (error == 0) { send_ok(thd); DBUG_RETURN(0); @@ -1848,6 +1847,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, mysql_ha_closeall(thd, table_list); + /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (tablespace_op != NO_TABLESPACE_OP) DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, tablespace_op)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f917e4ec027..569fa984973 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4515,6 +4515,7 @@ keyword: | DELAY_KEY_WRITE_SYM {} | DES_KEY_FILE {} | DIRECTORY_SYM {} + | DISCARD {} | DO_SYM {} | DUAL_SYM {} | DUMPFILE {} @@ -4546,6 +4547,7 @@ keyword: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} + | IMPORT {} | INDEXES {} | ISOLATION {} | ISAM_SYM {} @@ -4654,6 +4656,7 @@ keyword: | SUBDATE_SYM {} | SUBJECT_SYM {} | SUPER_SYM {} + | TABLESPACE {} | TEMPORARY {} | TEXT_SYM {} | TRANSACTION_SYM {} From cec45b6acf218cc620f2f0abc97d788bc503af52 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 12:19:54 +0200 Subject: [PATCH 21/50] do not add DROP TABLE and LOCK TABLES to the dump in --xml mode --- client/mysqldump.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 5e57f6480db..8cdefdaec74 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -426,7 +426,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'V': print_version(); exit(0); case 'X': opt_xml = 1; - opt_disable_keys=0; + extended_insert= opt_drop= opt_lock= + opt_disable_keys= opt_autocommit= opt_create_db= 0; break; case 'I': case '?': @@ -1153,7 +1154,7 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } - if (extended_insert && !opt_xml) + if (extended_insert) { ulong length = lengths[i]; if (i == 0) @@ -1238,7 +1239,7 @@ static void dumpTable(uint numFields, char *table) if (opt_xml) fprintf(md_result_file, "\t\n"); - if (extended_insert && !opt_xml) + if (extended_insert) { ulong row_length; dynstr_append(&extended_row,")"); @@ -1251,15 +1252,12 @@ static void dumpTable(uint numFields, char *table) } else { - if (row_break && !opt_xml) + if (row_break) fputs(";\n", md_result_file); row_break=1; /* This is first row */ - if (!opt_xml) - { - fputs(insert_pat,md_result_file); - fputs(extended_row.str,md_result_file); - } + fputs(insert_pat,md_result_file); + fputs(extended_row.str,md_result_file); total_length = row_length+init_length; } } @@ -1394,9 +1392,9 @@ static int init_dumping(char *database) char qbuf[128]; MYSQL_ROW row; MYSQL_RES *dbinfo; - + sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",database); - + if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) { /* Old server version, dump generic CREATE DATABASE */ @@ -1420,7 +1418,7 @@ static int init_dumping(char *database) (opt_quoted ? "`" : "")); } } - if (extended_insert && !opt_xml) + if (extended_insert) if (init_dynamic_string(&extended_row, "", 1024, 1024)) exit(EX_EOM); return 0; @@ -1683,15 +1681,15 @@ MASTER_LOG_POS=%s ;\n",row[0],row[1]); if (mysql_query(sock, "COMMIT")) { my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s", - MYF(0), mysql_error(sock)); - } + MYF(0), mysql_error(sock)); + } } dbDisconnect(current_host); write_footer(md_result_file); if (md_result_file != stdout) my_fclose(md_result_file, MYF(0)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); - if (extended_insert & !opt_xml) + if (extended_insert) dynstr_free(&extended_row); my_end(0); return(first_error); From aa22ba81fc7bcb7def7a31f34852da142f7f2445 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 13:10:41 +0200 Subject: [PATCH 22/50] make LOCK TABLES to work when Lock_tables_priv is granted on the DB level and Select_priv is granted on the table level. --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0c4e3cad763..0d743e1d56e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2693,7 +2693,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, /* grant_option is set if there exists a single table or column grant */ if (db_access == want_access || ((grant_option && !dont_check_global_grants) && - !(want_access & ~TABLE_ACLS))) + !(want_access & ~(db_access | TABLE_ACLS)))) DBUG_RETURN(FALSE); /* Ok */ if (!no_errors) net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, From d9709ffeb0be95c5f2ceb9c12525f2a958b86121 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 14:53:16 +0300 Subject: [PATCH 23/50] row0purge.c, row0mysql.c, os0file.c, os0file.h, fil0fil.h, fil0fil.c: IMPORT TABLESPACE must reset lsns if they are too high ha_innodb.cc: DISCARD/IMPORT TABLESPACE must have a TL_WRITE lock on the table sql/ha_innodb.cc: DISCARD/IMPORT TABLESPACE must have a TL_WRITE lock on the table innobase/fil/fil0fil.c: IMPORT TABLESPACE must reset lsns if they are too high innobase/include/fil0fil.h: IMPORT TABLESPACE must reset lsns if they are too high innobase/include/os0file.h: IMPORT TABLESPACE must reset lsns if they are too high innobase/os/os0file.c: IMPORT TABLESPACE must reset lsns if they are too high innobase/row/row0mysql.c: IMPORT TABLESPACE must reset lsns if they are too high innobase/row/row0purge.c: IMPORT TABLESPACE must reset lsns if they are too high --- innobase/fil/fil0fil.c | 161 +++++++++++++++++++++++++++++++++++-- innobase/include/fil0fil.h | 19 +++++ innobase/include/os0file.h | 8 ++ innobase/os/os0file.c | 23 ++++++ innobase/row/row0mysql.c | 45 +++++++++++ innobase/row/row0purge.c | 2 +- sql/ha_innodb.cc | 3 +- 7 files changed, 250 insertions(+), 11 deletions(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index f96d98c7b2d..c09590358e2 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -1302,11 +1302,13 @@ fil_write_flushed_lsn_to_data_files( space = UT_LIST_GET_FIRST(fil_system->space_list); while (space) { - /* We only write the lsn to the system tablespace - (space id == 0) files */ + /* We only write the lsn to all existing data files which have + been open during the lifetime of the mysqld process; they are + represented by the space objects in the tablespace memory + cache. Note that all data files in the system tablespace 0 are + always open. */ - if (space->id == 0) { - ut_a(space->purpose == FIL_TABLESPACE); + if (space->purpose == FIL_TABLESPACE) { sum_of_sizes = 0; node = UT_LIST_GET_FIRST(space->chain); @@ -1326,8 +1328,6 @@ fil_write_flushed_lsn_to_data_files( sum_of_sizes += node->size; node = UT_LIST_GET_NEXT(chain, node); } - - break; /* there is only one space with id == 0 */ } space = UT_LIST_GET_NEXT(space_list, space); } @@ -1937,6 +1937,147 @@ fil_create_new_single_table_tablespace( return(DB_SUCCESS); } +/************************************************************************ +It is possible, though very improbable, that the lsn's in the tablespace to be +imported have risen above the current system lsn, if a lengthy purge, ibuf +merge, or rollback was performed on a backup taken with ibbackup. If that is +the case, reset page lsn's in the file. We assume that mysqld was shut down +after it performed these cleanup operations on the .ibd file, so that it at +the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the +first page of the .ibd file, and we can determine whether we need to reset the +lsn's just by looking at that flush lsn. */ + +ibool +fil_reset_too_high_lsns( +/*====================*/ + /* out: TRUE if success */ + char* name, /* in: table name in the databasename/tablename + format */ + dulint current_lsn) /* in: reset lsn's if the lsn stamped to + FIL_PAGE_FILE_FLUSH_LSN in the first page is + too high */ +{ + os_file_t file; + char* filepath; + byte* page; + dulint flush_lsn; + ulint space_id; + ib_longlong file_size; + ib_longlong offset; + ulint page_no; + ibool success; + + filepath = ut_malloc(OS_FILE_MAX_PATH); + + ut_a(strlen(name) < OS_FILE_MAX_PATH - 10); + + sprintf(filepath, "./%s.ibd", name); + + srv_normalize_path_for_win(filepath); + + file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN, + OS_FILE_READ_WRITE, &success); + if (!success) { + ut_free(filepath); + + return(FALSE); + } + + /* Read the first page of the tablespace */ + + page = ut_malloc(UNIV_PAGE_SIZE); + + success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE); + if (!success) { + + goto func_exit; + } + + /* We have to read the file flush lsn from the header of the file */ + + flush_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); + + if (ut_dulint_cmp(current_lsn, flush_lsn) >= 0) { + /* Ok */ + success = TRUE; + + goto func_exit; + } + + space_id = fsp_header_get_space_id(page); + + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Flush lsn in the tablespace file %lu to be imported\n" +"InnoDB: is %lu %lu, which exceeds current system lsn %lu %lu.\n" +"InnoDB: We reset the lsn's in the file %s.\n", + space_id, + ut_dulint_get_high(flush_lsn), + ut_dulint_get_low(flush_lsn), + ut_dulint_get_high(current_lsn), + ut_dulint_get_low(current_lsn), filepath); + + /* Loop through all the pages in the tablespace and reset the lsn and + the page checksum if necessary */ + + file_size = os_file_get_size_as_iblonglong(file); + + for (offset = 0; offset < file_size; offset += UNIV_PAGE_SIZE) { + success = os_file_read(file, page, + (ulint)(offset & 0xFFFFFFFFUL), + (ulint)(offset >> 32), UNIV_PAGE_SIZE); + if (!success) { + + goto func_exit; + } + if (ut_dulint_cmp(mach_read_from_8(page + FIL_PAGE_LSN), + current_lsn) > 0) { + /* We have to reset the lsn */ + space_id = mach_read_from_4(page + + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); + + buf_flush_init_for_writing(page, current_lsn, space_id, + page_no); + success = os_file_write(filepath, file, page, + (ulint)(offset & 0xFFFFFFFFUL), + (ulint)(offset >> 32), UNIV_PAGE_SIZE); + if (!success) { + + goto func_exit; + } + } + } + + success = os_file_flush(file); + if (!success) { + + goto func_exit; + } + + /* We now update the flush_lsn stamp at the start of the file */ + success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE); + if (!success) { + + goto func_exit; + } + + mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn); + + success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE); + if (!success) { + + goto func_exit; + } + success = os_file_flush(file); +func_exit: + os_file_close(file); + ut_free(page); + ut_free(filepath); + + return(success); +} + /************************************************************************ Tries to open a single-table tablespace and checks the space id is right in it. If does not succeed, prints an error message to the .err log. This @@ -1982,7 +2123,9 @@ fil_open_single_table_tablespace( "InnoDB: open the tablespace file %s!\n", filepath); fprintf(stderr, "InnoDB: have you moved InnoDB .ibd files around without using the\n" -"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n"); +"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n" +"InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" +"InnoDB: how to resolve the issue.\n"); ut_free(filepath); @@ -2007,7 +2150,9 @@ fil_open_single_table_tablespace( "InnoDB: data dictionary it is %lu.\n", filepath, space_id, id); fprintf(stderr, "InnoDB: Have you moved InnoDB .ibd files around without using the\n" -"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n"); +"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n" +"InnoDB: You can look from section 15.1 of http://www.innodb.com/ibman.html\n" +"InnoDB: how to resolve the issue.\n"); ret = FALSE; diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index c76c87395b4..506bc6c1870 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -326,6 +326,25 @@ fil_open_single_table_tablespace( char* name); /* in: table name in the databasename/tablename format */ /************************************************************************ +It is possible, though very improbable, that the lsn's in the tablespace to be +imported have risen above the current system lsn, if a lengthy purge, ibuf +merge, or rollback was performed on a backup taken with ibbackup. If that is +the case, reset page lsn's in the file. We assume that mysqld was shut down +after it performed these cleanup operations on the .ibd file, so that it at +the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the +first page of the .ibd file, and we can determine whether we need to reset the +lsn's just by looking at that flush lsn. */ + +ibool +fil_reset_too_high_lsns( +/*====================*/ + /* out: TRUE if success */ + char* name, /* in: table name in the databasename/tablename + format */ + dulint current_lsn); /* in: reset lsn's if the lsn stamped to + FIL_PAGE_FILE_FLUSH_LSN in the first page is + too high */ +/************************************************************************ At the server startup, if we need crash recovery, scans the database directories under the MySQL datadir, looking for .ibd files. Those files are single-table tablespaces. We need to know the space id in each of them so that diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 52303e735ff..d1dc9dea18b 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -301,6 +301,14 @@ os_file_get_size( size */ ulint* size_high);/* out: most significant 32 bits of size */ /*************************************************************************** +Gets file size as a 64-bit integer ib_longlong. */ + +ib_longlong +os_file_get_size_as_iblonglong( +/*===========================*/ + /* out: size in bytes, -1 if error */ + os_file_t file); /* in: handle to a file */ +/*************************************************************************** Sets a file size. This function can be used to extend or truncate a file. */ ibool diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 0e44104a53c..3682c160e5d 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1204,6 +1204,29 @@ os_file_get_size( #endif } +/*************************************************************************** +Gets file size as a 64-bit integer ib_longlong. */ + +ib_longlong +os_file_get_size_as_iblonglong( +/*===========================*/ + /* out: size in bytes, -1 if error */ + os_file_t file) /* in: handle to a file */ +{ + ulint size; + ulint size_high; + ibool success; + + success = os_file_get_size(file, &size, &size_high); + + if (!success) { + + return(-1); + } + + return((((ib_longlong)size_high) << 32) + (ib_longlong)size); +} + /*************************************************************************** Sets a file size. This function can be used to extend or truncate a file. */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 5d5985d16af..661aec3d9a9 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1871,6 +1871,16 @@ row_discard_tablespace_for_mysql( goto funct_exit; } + if (table->space == 0) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: table %s\n" +"InnoDB: is in the system tablespace 0 which cannot be discarded\n", name); + err = DB_ERROR; + + goto funct_exit; + } + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); sprintf(buf, @@ -1967,6 +1977,7 @@ row_import_tablespace_for_mysql( { dict_table_t* table; ibool success; + dulint current_lsn; ulint err = DB_SUCCESS; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1975,6 +1986,30 @@ row_import_tablespace_for_mysql( trx->op_info = (char*) "importing tablespace"; + current_lsn = log_get_lsn(); + + /* It is possible, though very improbable, that the lsn's in the + tablespace to be imported have risen above the current system lsn, if + a lengthy purge, ibuf merge, or rollback was performed on a backup + taken with ibbackup. If that is the case, reset page lsn's in the + file. We assume that mysqld was shut down after it performed these + cleanup operations on the .ibd file, so that it stamped the latest lsn + to the FIL_PAGE_FILE_FLUSH_LSN in the first page of the .ibd file. + + TODO: reset also the trx id's in clustered index records and write + a new space id to each data page. That would allow us to import clean + .ibd files from another MySQL installation. */ + + success = fil_reset_too_high_lsns(name, current_lsn); + + if (!success) { + err = DB_ERROR; + + row_mysql_lock_data_dictionary(trx); + + goto funct_exit; + } + /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -1988,6 +2023,16 @@ row_import_tablespace_for_mysql( goto funct_exit; } + if (table->space == 0) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: table %s\n" +"InnoDB: is in the system tablespace 0 which cannot be imported\n", name); + err = DB_ERROR; + + goto funct_exit; + } + if (!table->tablespace_discarded) { ut_print_timestamp(stderr); fprintf(stderr, diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 99332dc275d..a455722f15a 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -534,7 +534,7 @@ row_purge_parse_undo_rec( node->table = NULL; - return; + return(FALSE); } clust_index = dict_table_get_first_index(node->table); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d07b166d9e2..7f8c99f7c15 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4572,8 +4572,7 @@ ha_innobase::external_lock( update_thd(thd); - if (lock_type != F_UNLCK && prebuilt->table->ibd_file_missing - && !current_thd->tablespace_op) { + if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" From d1ed51db824c8335dc6b4617d09b600f3c918506 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 16:30:42 +0300 Subject: [PATCH 24/50] Fixed bug in SET enum_system_variable=NULL BitKeeper/etc/ignore: added scripts/make_sharedlib_distribution mysql-test/r/variables.result: Add test for enum_system_variable=NULL mysql-test/t/variables.test: Add test for enum_system_variable=NULL sql/set_var.cc: Fixed bug in SET enum_system_variable=NULL Moved some array elements to get result sorted --- .bzrignore | 1 + mysql-test/r/variables.result | 2 ++ mysql-test/t/variables.test | 2 ++ sql/set_var.cc | 11 ++++++----- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.bzrignore b/.bzrignore index 7bdc90fd76a..3dcf46841d9 100644 --- a/.bzrignore +++ b/.bzrignore @@ -539,3 +539,4 @@ scripts/make_win_src_distribution libmysql/vio_priv.h libmysql_r/vio_priv.h hardcopy.0 +scripts/make_sharedlib_distribution diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 50e97120de6..8afdced206b 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -244,6 +244,8 @@ set myisam_max_sort_file_size=100; Variable 'myisam_max_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL set myisam_max_extra_sort_file_size=100; Variable 'myisam_max_extra_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL +set @@SQL_WARNINGS=NULL; +Variable 'sql_warnings' can't be set to the value of 'NULL' set autocommit=1; set big_tables=1; select @@autocommit, @@big_tables; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 6a3264741ad..8e38160c60b 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -153,6 +153,8 @@ select @@global.sql_auto_is_null; set myisam_max_sort_file_size=100; --error 1229 set myisam_max_extra_sort_file_size=100; +--error 1231 +set @@SQL_WARNINGS=NULL; # Test setting all variables diff --git a/sql/set_var.cc b/sql/set_var.cc index dd2f90845c9..642f7c21ce3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -394,9 +394,9 @@ sys_var *sys_variables[]= &sys_quote_show_create, &sys_rand_seed1, &sys_rand_seed2, + &sys_range_alloc_block_size, &sys_read_buff_size, &sys_read_rnd_buff_size, - &sys_range_alloc_block_size, &sys_rpl_recovery_rank, &sys_safe_updates, &sys_select_limit, @@ -555,11 +555,11 @@ struct show_var_st init_vars[]= { {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS}, + {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size, + SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, - {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size, - SHOW_SYS}, {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, @@ -972,7 +972,8 @@ byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type) bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) { - char buff[80], *value; + char buff[80]; + const char *value; String str(buff,sizeof(buff)), *res; if (var->value->result_type() == STRING_RESULT) @@ -982,7 +983,7 @@ bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) (ulong) find_type(res->c_ptr(), enum_names, 3)-1)) < 0) { - value=res->c_ptr(); + value= res ? res->c_ptr() : "NULL"; goto err; } } From cad75f4a429830e1dd9713a16bd13ace17623dc4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 10:45:03 -0500 Subject: [PATCH 25/50] Identical mysql.ico and MYSQL.ICO existed, causing problems on non-case-sensitive OSes. Deleted conflicting file. BitKeeper/deleted/.del-MYSQL.ICO~d93519b5f0d6ee1: Delete: VC++Files/mysqlshutdown/MYSQL.ICO --- VC++Files/mysqlshutdown/MYSQL.ICO | Bin 318 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 VC++Files/mysqlshutdown/MYSQL.ICO diff --git a/VC++Files/mysqlshutdown/MYSQL.ICO b/VC++Files/mysqlshutdown/MYSQL.ICO deleted file mode 100644 index 1fe0b7115bbe95b1108cd2ef025f539cad262181..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmZvUD-Hrd5JcZ5m~pGnNG`<*&;-dE{Mfn8Bxu&55QK0D6ltnvMWz)B3Y@jseC!89!*R!Xf^>Or(1!kHj<%hW7GDWsB>AX214Q+0Zs``j1a z(@j@PPTpHIC8_LJ_1=$lliIOY^&;L8mot10@Dd)vQ+0fVtLJb(3VXP9%sZG*+7-U9 Cr%L_+ From a14c1e411cb763688a0673b326cdd09c589fecf0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 23:33:09 +0300 Subject: [PATCH 26/50] os0file.c: Fix Visual C++ compilation errors reported by Miguel innobase/os/os0file.c: Fix Visual C++ compilation errors reported by Miguel --- innobase/os/os0file.c | 87 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 3682c160e5d..4b9289d2b93 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -213,24 +213,27 @@ os_file_get_last_error( if (report_all_errors || (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS)) { + ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Operating system error number %lu in a file operation.\n" - "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", - err); + " InnoDB: Operating system error number %lu in a file operation.\n", err); if (err == ERROR_PATH_NOT_FOUND) { - fprintf(stderr, - "InnoDB: The error means the system cannot find the path specified.\n" - "InnoDB: In installation you must create directories yourself, InnoDB\n" - "InnoDB: does not create them.\n"); + fprintf(stderr, + "InnoDB: The error means the system cannot find the path specified.\n"); + + if (srv_is_being_started) { + fprintf(stderr, + "InnoDB: If you are installing InnoDB, remember that you must create\n" + "InnoDB: directories yourself, InnoDB does not create them.\n"); + } } else if (err == ERROR_ACCESS_DENIED) { - fprintf(stderr, + fprintf(stderr, "InnoDB: The error means mysqld does not have the access rights to\n" "InnoDB: the directory. It may also be you have created a subdirectory\n" "InnoDB: of the same name as a data file.\n"); } else { - fprintf(stderr, + fprintf(stderr, "InnoDB: See section 13.2 at http://www.innodb.com/ibman.html\n" "InnoDB: about operating system error numbers.\n"); } @@ -252,29 +255,31 @@ os_file_get_last_error( if (report_all_errors || (err != ENOSPC && err != EEXIST)) { - ut_print_timestamp(stderr); + ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Operating system error number %lu in a file operation.\n" - "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", - err); + " InnoDB: Operating system error number %lu in a file operation.\n", err); if (err == ENOENT) { - fprintf(stderr, - "InnoDB: The error means the system cannot find the path specified.\n" - "InnoDB: In installation you must create directories yourself, InnoDB\n" - "InnoDB: does not create them.\n"); + fprintf(stderr, + "InnoDB: The error means the system cannot find the path specified.\n"); + + if (srv_is_being_started) { + fprintf(stderr, + "InnoDB: If you are installing InnoDB, remember that you must create\n" + "InnoDB: directories yourself, InnoDB does not create them.\n"); + } } else if (err == EACCES) { - fprintf(stderr, + fprintf(stderr, "InnoDB: The error means mysqld does not have the access rights to\n" "InnoDB: the directory.\n"); } else { - if (strerror((int)err) != NULL) { + if (strerror((int)err) != NULL) { fprintf(stderr, "InnoDB: Error number %lu means '%s'.\n", err, strerror((int)err)); - } + } - fprintf(stderr, + fprintf(stderr, "InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" "InnoDB: about operating system error numbers.\n"); } @@ -404,7 +409,7 @@ os_file_opendir( ut_a(strlen(dirname) < OS_FILE_MAX_PATH); strcpy(path, dirname); - strcpy(path + strlen(path), "\*"); + strcpy(path + strlen(path), "\\"); /* Note that in Windows opening the 'directory stream' also retrieves the first entry in the directory. Since it is '.', that is no problem, @@ -493,18 +498,18 @@ next_file: ret = FindNextFile(dir, lpFindFileData); if (ret) { - ut_a(strlen(lpFindFileData->cFilename) < OS_FILE_MAX_PATH); + ut_a(strlen(lpFindFileData->cFileName) < OS_FILE_MAX_PATH); - if (strcmp(lpFindFileData->cFilename, ".") == 0 - || strcmp(lpFindFileData->cFilename, "..") == 0) { + if (strcmp(lpFindFileData->cFileName, ".") == 0 + || strcmp(lpFindFileData->cFileName, "..") == 0) { goto next_file; } - strcpy(info->name, lpFindFileData->cFilename); + strcpy(info->name, lpFindFileData->cFileName); - info->size = (ib_longlong)(buf->nFileSizeLow) - + (((ib_longlong)(buf->nFileSizeHigh)) << 32); + info->size = (ib_longlong)(lpFindFileData->nFileSizeLow) + + (((ib_longlong)(lpFindFileData->nFileSizeHigh)) << 32); if (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -827,14 +832,13 @@ os_file_create( DWORD create_flag; DWORD attributes; ibool retry; - try_again: ut_a(name); if (create_mode == OS_FILE_OPEN_RAW) { create_flag = OPEN_EXISTING; share_mode = FILE_SHARE_WRITE; - if (create_mode == OS_FILE_OPEN) { + } else if (create_mode == OS_FILE_OPEN) { create_flag = OPEN_EXISTING; } else if (create_mode == OS_FILE_CREATE) { create_flag = CREATE_NEW; @@ -927,15 +931,12 @@ try_again: if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW) { mode_str = "OPEN"; - create_flag = O_RDWR; } else if (create_mode == OS_FILE_CREATE) { mode_str = "CREATE"; - create_flag = O_RDWR | O_CREAT | O_EXCL; } else if (create_mode == OS_FILE_OVERWRITE) { mode_str = "OVERWRITE"; - create_flag = O_RDWR | O_CREAT | O_TRUNC; } else { create_flag = 0; @@ -1015,8 +1016,7 @@ os_file_delete( char* name) /* in: file path as a null-terminated string */ { #ifdef __WIN__ - os_file_t dummy = NULL; - BOOL ret; + BOOL ret; ret = DeleteFile((LPCTSTR)name); @@ -1024,17 +1024,16 @@ os_file_delete( return(TRUE); } - os_file_handle_error(dummy, name, "delete"); + os_file_handle_error(NULL, name, "delete"); return(FALSE); #else - os_file_t dummy = 0; - int ret; + int ret; ret = unlink((const char*)name); if (ret != 0) { - os_file_handle_error(dummy, name, "delete"); + os_file_handle_error(0, name, "delete"); return(FALSE); } @@ -1056,8 +1055,7 @@ os_file_rename( char* newpath) /* in: new file path */ { #ifdef __WIN__ - os_file_t dummy = NULL; - BOOL ret; + BOOL ret; ret = MoveFile((LPCTSTR)oldpath, (LPCTSTR)newpath); @@ -1065,17 +1063,16 @@ os_file_rename( return(TRUE); } - os_file_handle_error(dummy, oldpath, "delete"); + os_file_handle_error(NULL, oldpath, "delete"); return(FALSE); #else - os_file_t dummy = 0; - int ret; + int ret; ret = rename((const char*)oldpath, (const char*)newpath); if (ret != 0) { - os_file_handle_error(dummy, oldpath, "rename"); + os_file_handle_error(0, oldpath, "rename"); return(FALSE); } From acb47c93be78fbc59ca75fc1195444e7d8dc3568 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 02:11:03 -0400 Subject: [PATCH 27/50] Add in bit_xor function (approved by Sergei) sql/item_sum.cc: Add in bit_xor class functions. sql/item_sum.h: Add bit_xor class. sql/lex.h: Add in bit_xor symbol. sql/sql_yacc.yy: Add in bit_xor function BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql/item_sum.cc | 23 +++++++++++++++++++++++ sql/item_sum.h | 12 ++++++++++++ sql/lex.h | 1 + sql/sql_yacc.yy | 3 +++ 5 files changed, 40 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 177107f8779..9df789c0340 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -30,6 +30,7 @@ greg@mysql.com guilhem@mysql.com gweir@build.mysql.com gweir@work.mysql.com +harrison@mysql.com heikki@donna.mysql.fi heikki@hundin.mysql.fi heikki@rescue. diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 6a213962c6a..672126a2664 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -625,6 +625,20 @@ bool Item_sum_or::add() return 0; } +Item *Item_sum_xor::copy_or_same(THD* thd) +{ + return new (&thd->mem_root) Item_sum_xor(thd, *this); +} + + +bool Item_sum_xor::add() +{ + ulonglong value= (ulonglong) args[0]->val_int(); + if (!args[0]->null_value) + bits^=value; + return 0; +} + Item *Item_sum_and::copy_or_same(THD* thd) { return new (&thd->mem_root) Item_sum_and(thd, *this); @@ -912,6 +926,15 @@ void Item_sum_or::update_field() int8store(res,nr); } +void Item_sum_xor::update_field() +{ + ulonglong nr; + char *res=result_field->ptr; + + nr=uint8korr(res); + nr^= (ulonglong) args[0]->val_int(); + int8store(res,nr); +} void Item_sum_and::update_field() { diff --git a/sql/item_sum.h b/sql/item_sum.h index d6184bcdbac..e5061e1e05a 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -484,6 +484,18 @@ class Item_sum_and :public Item_sum_bit Item *copy_or_same(THD* thd); }; +class Item_sum_xor :public Item_sum_bit +{ + public: + Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} + Item_sum_xor(THD *thd, Item_sum_xor &item) :Item_sum_bit(thd, item) {} + bool add(); + void update_field(); + const char *func_name() const { return "bit_xor"; } + Item *copy_or_same(THD* thd); +}; + + /* ** user defined aggregates */ diff --git a/sql/lex.h b/sql/lex.h index 859f92dd752..f8bb34c5c5b 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -465,6 +465,7 @@ static SYMBOL sql_functions[] = { { "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)}, { "BIT_OR", SYM(BIT_OR),0,0}, { "BIT_AND", SYM(BIT_AND),0,0}, + { "BIT_XOR", SYM(BIT_XOR),0,0}, { "CAST", SYM(CAST_SYM),0,0}, { "CEIL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, { "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 569fa984973..51df4e358b4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -449,6 +449,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token BETWEEN_SYM %token BIT_AND %token BIT_OR +%token BIT_XOR %token CASE_SYM %token CONCAT %token CONCAT_WS @@ -2846,6 +2847,8 @@ sum_expr: { $$=new Item_sum_and($3); } | BIT_OR '(' in_sum_expr ')' { $$=new Item_sum_or($3); } + | BIT_XOR '(' in_sum_expr ')' + { $$=new Item_sum_xor($3); } | COUNT_SYM '(' opt_all '*' ')' { $$=new Item_sum_count(new Item_int((int32) 0L,1)); } | COUNT_SYM '(' in_sum_expr ')' From 59b62b86009afa8cf0b4102289df6f1660c5f1e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 09:55:26 +0300 Subject: [PATCH 28/50] fil0fil.c: Visual C++ apparently does not know what -1LL (= -1 in longlong type) means innobase/fil/fil0fil.c: Visual C++ apparently does not know what -1LL (= -1 in longlong type) means --- innobase/fil/fil0fil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index c09590358e2..3b729938ea7 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -2466,7 +2466,8 @@ fil_tablespace_deleted_or_being_deleted_in_mem( return(TRUE); } - if (version != -1LL && space->tablespace_version != version) { + if (version != ((ib_longlong)-1) + && space->tablespace_version != version) { mutex_exit(&(system->mutex)); return(TRUE); From 547b056d6d6b6b351663612f8c7b4949788f33b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 14:50:36 +0500 Subject: [PATCH 29/50] WL#1106: Switch = --maxdb rather than --sapdb --- mysql-test/r/sql_mode.result | 4 ++-- mysql-test/t/sql_mode.test | 2 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 2 +- sql/set_var.cc | 2 +- sql/sql_show.cc | 2 +- sql/sql_yacc.yy | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 9b80b965d10..06451b8ac34 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -71,10 +71,10 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`a`), UNIQUE KEY `email` (`email`) ) TYPE=HEAP ROW_FORMAT=DYNAMIC -set sql_mode="postgresql,oracle,mssql,db2,sapdb"; +set sql_mode="postgresql,oracle,mssql,db2,maxdb"; select @@sql_mode; @@sql_mode -PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,SAPDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS +PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS show create table t1; Table Create Table t1 CREATE TABLE "t1" ( diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index d3531f0c440..d96fd030207 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -24,7 +24,7 @@ show create table t1; set @@sql_mode="no_field_options,mysql323,mysql40"; show variables like 'sql_mode'; show create table t1; -set sql_mode="postgresql,oracle,mssql,db2,sapdb"; +set sql_mode="postgresql,oracle,mssql,db2,maxdb"; select @@sql_mode; show create table t1; drop table t1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d6e6256c388..626b26fb74e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -214,7 +214,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define MODE_ORACLE 512 #define MODE_MSSQL 1024 #define MODE_DB2 2048 -#define MODE_SAPDB 4096 +#define MODE_MAXDB 4096 #define MODE_NO_KEY_OPTIONS 8192 #define MODE_NO_TABLE_OPTIONS 16384 #define MODE_NO_FIELD_OPTIONS 32768 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 17b4dad9d1c..ea50f6746da 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -211,7 +211,7 @@ const char *sql_mode_names[] = "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", "NO_DIR_IN_CREATE", - "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "SAPDB", "NO_KEY_OPTIONS", + "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI", "NO_AUTO_VALUE_ON_ZERO", NullS }; diff --git a/sql/set_var.cc b/sql/set_var.cc index a5024363545..bf1c8a52a88 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2204,7 +2204,7 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_SAPDB) + if (sql_mode & MODE_MAXDB) sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8550973ff88..fce25da2cd0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1073,7 +1073,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) MODE_ORACLE | MODE_MSSQL | MODE_DB2 | - MODE_SAPDB | + MODE_MAXDB | MODE_ANSI)) != 0; my_bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 | diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 81a59196e3c..7ca9c1153cb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1250,7 +1250,7 @@ type: | TIME_SYM { $$=FIELD_TYPE_TIME; } | TIMESTAMP { - if (YYTHD->variables.sql_mode & MODE_SAPDB) + if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; else $$=FIELD_TYPE_TIMESTAMP; From 4f5887b22d5d900a0e6166ff26f50d8c09e969f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 15:21:50 +0300 Subject: [PATCH 30/50] Add more information about memory usage to debug log sql/sql_test.cc: Add more information about memory usage --- sql/sql_test.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index fc3147db784..6498a52cc09 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -194,6 +194,8 @@ void mysql_print_status(THD *thd) printf("\nStatus information:\n\n"); my_getwd(current_dir, sizeof(current_dir),MYF(0)); printf("Current dir: %s\n", current_dir); + printf("Running threads: %d Stack size: %ld\n", thread_count, + (long) thread_stack); if (thd) thd->proc_info="locks"; thr_print_locks(); // Write some debug info @@ -271,8 +273,9 @@ Maximum total allocated space: %d\n\ Space available in freed fastbin blocks: %d\n\ Total allocated space: %d\n\ Total free space: %d\n\ -Top-most, releasable space: %d\n", - (int) info.arena, +Top-most, releasable space: %d\n\ +Estimated memory (with thread stack): %ld\n", + (int) info.arena , (int) info.ordblks, (int) info.smblks, (int) info.hblks, @@ -281,7 +284,8 @@ Top-most, releasable space: %d\n", (int) info.fsmblks, (int) info.uordblks, (int) info.fordblks, - (int) info.keepcost); + (int) info.keepcost, + (long) (thread_count * thread_stack + info.hblkhd + info.arena)); #endif puts(""); if (thd) From 14573a71910c2a345d5bd1dc3d1bffd73319ba50 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 17:34:28 +0500 Subject: [PATCH 31/50] ctype-simple.c, ctype-mb.c: Win compilation problem fix ctype-bin.c: Win compilation problem fix , , m_ctype.h: Win compilation problem fix , include/m_ctype.h: Win compilation problem fix , strings/ctype-bin.c: Win compilation problem fix , , strings/ctype-mb.c: Win compilation problem fix strings/ctype-simple.c: Win compilation problem fix --- include/m_ctype.h | 12 ++++++------ strings/ctype-bin.c | 14 +++++++------- strings/ctype-mb.c | 22 +++++++++++----------- strings/ctype-simple.c | 14 +++++++------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index b1557e5293b..e344c434f81 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -123,8 +123,8 @@ typedef struct my_collation_handler_st int (*strcasecmp)(struct charset_info_st *, const char *, const char *); uint (*instr)(struct charset_info_st *, - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch); /* Hash calculation */ @@ -257,8 +257,8 @@ extern void my_hash_sort_simple(CHARSET_INFO *cs, extern uint my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, uint length); extern uint my_instr_simple(struct charset_info_st *, - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch); @@ -326,8 +326,8 @@ int my_wildcmp_mb(CHARSET_INFO *, uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); uint my_instr_mb(struct charset_info_st *, - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch); diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 340084ad848..ebf915398a8 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -264,8 +264,8 @@ static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), static uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch) { register const uchar *str, *search, *end, *search_end; @@ -283,10 +283,10 @@ uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), return 1; /* Empty string is always found */ } - str= (const uchar*) big; - search= (const uchar*) small; - end= (const uchar*) big+b_length-s_length+1; - search_end= (const uchar*) small + s_length; + str= (const uchar*) b; + search= (const uchar*) s; + end= (const uchar*) b+b_length-s_length+1; + search_end= (const uchar*) s + s_length; skipp: while (str != end) @@ -305,7 +305,7 @@ skipp: if (nmatch > 0) { match[0].beg= 0; - match[0].end= str- (const uchar*)big-1; + match[0].end= str- (const uchar*)b-1; match[0].mblen= match[0].end; if (nmatch > 1) diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 813a33fd229..271c56b8a0a 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -275,11 +275,11 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), } uint my_instr_mb(CHARSET_INFO *cs, - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch) { - register const char *end, *big0; + register const char *end, *b0; int res= 0; if (s_length <= b_length) @@ -295,20 +295,20 @@ uint my_instr_mb(CHARSET_INFO *cs, return 1; /* Empty string is always found */ } - big0= big; - end= big+b_length-s_length+1; + b0= b; + end= b+b_length-s_length+1; - while (big < end) + while (b < end) { int mblen; - if (!cs->coll->strnncoll(cs, (unsigned char*) big, s_length, - (unsigned char*) small, s_length)) + if (!cs->coll->strnncoll(cs, (unsigned char*) b, s_length, + (unsigned char*) s, s_length)) { if (nmatch) { match[0].beg= 0; - match[0].end= big-big0; + match[0].end= b-b0; match[0].mblen= res; if (nmatch > 1) { @@ -319,8 +319,8 @@ uint my_instr_mb(CHARSET_INFO *cs, } return 2; } - mblen= (mblen= my_ismbchar(cs, big, end)) ? mblen : 1; - big+= mblen; + mblen= (mblen= my_ismbchar(cs, b, end)) ? mblen : 1; + b+= mblen; b_length-= mblen; res++; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index f85ce5e7a2b..aba15f13d4b 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1031,8 +1031,8 @@ uint my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)), uint my_instr_simple(CHARSET_INFO *cs, - const char *big, uint b_length, - const char *small, uint s_length, + const char *b, uint b_length, + const char *s, uint s_length, my_match_t *match, uint nmatch) { register const uchar *str, *search, *end, *search_end; @@ -1050,10 +1050,10 @@ uint my_instr_simple(CHARSET_INFO *cs, return 1; /* Empty string is always found */ } - str= (const uchar*) big; - search= (const uchar*) small; - end= (const uchar*) big+b_length-s_length+1; - search_end= (const uchar*) small + s_length; + str= (const uchar*) b; + search= (const uchar*) s; + end= (const uchar*) b+b_length-s_length+1; + search_end= (const uchar*) s + s_length; skipp: while (str != end) @@ -1072,7 +1072,7 @@ skipp: if (nmatch > 0) { match[0].beg= 0; - match[0].end= str- (const uchar*)big-1; + match[0].end= str- (const uchar*)b-1; match[0].mblen= match[0].end; if (nmatch > 1) From 48446c0f73a99f7cb6a1f00700e6ea066ed28984 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 16:55:24 +0300 Subject: [PATCH 32/50] Updated comments mysys/queues.c: Comments for new functions (no code change) mysys/thr_alarm.c: Updated comment --- mysys/queues.c | 26 +++++++++++++++++++++++--- mysys/thr_alarm.c | 8 ++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/mysys/queues.c b/mysys/queues.c index ae69684f9e4..93d4c303f22 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -61,6 +61,24 @@ int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key, DBUG_RETURN(0); } + +/* + Resize queue + + SYNOPSIS + resize_queue() + queue Queue + max_elements New max size for queue + + NOTES + If you resize queue to be less than the elements you have in it, + the extra elements will be deleted + + RETURN + 0 ok + 1 Error. In this case the queue is unchanged +*/ + int resize_queue(QUEUE *queue, uint max_elements) { byte **new_root; @@ -68,14 +86,16 @@ int resize_queue(QUEUE *queue, uint max_elements) if (queue->max_elements == max_elements) DBUG_RETURN(0); if ((new_root= (byte **) my_realloc((void *)queue->root, - (max_elements+1)*sizeof(void*), MYF(MY_WME))) == 0) + (max_elements+1)*sizeof(void*), + MYF(MY_WME))) == 0) DBUG_RETURN(1); set_if_smaller(queue->elements, max_elements); - queue->max_elements=max_elements; - queue->root=new_root; + queue->max_elements= max_elements; + queue->root= new_root; DBUG_RETURN(0); } + void delete_queue(QUEUE *queue) { DBUG_ENTER("delete_queue"); diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 5d2ac8b0099..36bbac16fef 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -120,16 +120,20 @@ void init_thr_alarm(uint max_alarms) DBUG_VOID_RETURN; } + void resize_thr_alarm(uint max_alarms) { pthread_mutex_lock(&LOCK_alarm); - /* it's ok not to shrink the queue sometimes */ + /* + It's ok not to shrink the queue as there may be more pending alarms than + than max_alarms + */ if (alarm_queue.elements < max_alarms) resize_queue(&alarm_queue,max_alarms+1); pthread_mutex_unlock(&LOCK_alarm); - return; } + /* Request alarm after sec seconds. From e115c1f46d5007e9bd4abfdd2f2214e7ba7f9428 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 17:10:47 +0200 Subject: [PATCH 33/50] dummy resize_thr_alarm for Netware --- include/thr_alarm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/thr_alarm.h b/include/thr_alarm.h index a54c192b1ed..0dbb700b4fc 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -60,9 +60,10 @@ typedef my_bool ALARM; #define thr_end_alarm(A) #define thr_alarm(A,B,C) ((*(A)=1)-1) /* The following should maybe be (*(A)) */ -#define thr_got_alarm(A) 0 +#define thr_got_alarm(A) 0 #define init_thr_alarm(A) #define thr_alarm_kill(A) +#define resize_thr_alarm(N) #define end_thr_alarm() #else From b06eb4d81a82be2a215e8b9b726d214c559e3f40 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 21:41:13 +0300 Subject: [PATCH 34/50] Better fix for CREATE TABLE IF NOT EXISTS ... SELECT Fixed chsize() problem on windows Extend default timeout on windows clients to 1 year (to avoid timeout problems) include/mysql.h: Added client timeouts (for TCP/IP) libmysql/libmysql.c: Added client timeouts (for TCP/IP) mysql-test/r/create.result: More tests for CREATE TABLE IF NOT EXISTS ... SELECT mysql-test/t/create.test: More tests for CREATE TABLE IF NOT EXISTS ... SELECT mysys/my_chsize.c: Fix for windows sql/handler.h: Remove not used field 'if_not_exists' Ordered fields to be more optimized for new CPU's Added field 'table_existed' sql/slave.cc: Cleanup temporary tables when slave ends sql/sql_class.h: Remove not used 'do_not_drop' field sql/sql_insert.cc: Better fix for CREATE TABLE IF NOT EXISTS ... SELECT sql/sql_table.cc: Better fix for CREATE TABLE IF NOT EXISTS ... SELECT --- include/mysql.h | 3 +++ libmysql/libmysql.c | 4 ++-- mysql-test/r/create.result | 16 +++++++++++++ mysql-test/t/create.test | 49 ++++++++++++++++++++++++++++---------- mysys/my_chsize.c | 13 +++++----- sql/handler.h | 18 +++++++------- sql/slave.cc | 2 ++ sql/sql_class.h | 4 ++-- sql/sql_insert.cc | 3 +-- sql/sql_table.cc | 7 ++++++ 10 files changed, 86 insertions(+), 33 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index 95730c0f2f5..0c91266e19c 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -60,6 +60,9 @@ typedef int my_socket; extern unsigned int mysql_port; extern char *mysql_unix_port; +#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ +#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ + #ifdef __NETWARE__ #pragma pack(push, 8) /* 8 byte alignment */ #endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index cd4e8c77f20..d8966b30fb9 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -64,8 +64,8 @@ uint mysql_port=0; my_string mysql_unix_port=0; ulong net_buffer_length=8192; ulong max_allowed_packet= 1024L*1024L*1024L; -ulong net_read_timeout= NET_READ_TIMEOUT; -ulong net_write_timeout= NET_WRITE_TIMEOUT; +ulong net_read_timeout= CLIENT_NET_READ_TIMEOUT; +ulong net_write_timeout= CLIENT_NET_WRITE_TIMEOUT; #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 3ebe6df21b9..627913939fb 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -200,3 +200,19 @@ select * from t1; 0 1 2 0 0 1 drop table t1; +create table t1 (a int not null, b int, primary key (a)); +insert into t1 values (1,1); +create table if not exists t1 select 2; +select * from t1; +a b +1 1 +0 2 +create table if not exists t1 select 3 as 'a',4 as 'b'; +create table if not exists t1 select 3 as 'a',3 as 'b'; +Duplicate entry '3' for key 1 +select * from t1; +a b +1 1 +0 2 +3 4 +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 815aad560b1..8aee586268f 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -18,21 +18,30 @@ drop table if exists t1; # Test of some CREATE TABLE'S that should fail # -!$1146 create table t2 type=heap select * from t1; -!$1146 create table t2 select auto+1 from t1; +--error 1146 +create table t2 type=heap select * from t1; +--error 1146 +create table t2 select auto+1 from t1; drop table if exists t1,t2; -!$1167 create table t1 (b char(0) not null, index(b)); -!$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap; -!$1163 create table t1 (a int not null,b text) type=heap; +--error 1167 +create table t1 (b char(0) not null, index(b)); +--error 1164 +create table t1 (a int not null auto_increment,primary key (a)) type=heap; +--error 1163 +create table t1 (a int not null,b text) type=heap; drop table if exists t1; -!$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap; +--error 1164 +create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap; -- error 1044,1 create table not_existing_database.test (a int); -!$1103 create table `a/a` (a int); -!$1103 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int); -!$1059 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int); +--error 1103 +create table `a/a` (a int); +--error 1103 +create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int); +--error 1059 +create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int); # # test of dummy table names @@ -123,9 +132,12 @@ drop table t1; # create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2)); insert into t1 values ("a", 1), ("b", 2); -!$1048 insert into t1 values ("c", NULL); -!$1048 insert into t1 values (NULL, 3); -!$1048 insert into t1 values (NULL, NULL); +--error 1048 +insert into t1 values ("c", NULL); +--error 1048 +insert into t1 values (NULL, 3); +--error 1048 +insert into t1 values (NULL, NULL); drop table t1; # @@ -154,3 +166,16 @@ create table if not exists t1 select 1; select * from t1; drop table t1; +# +# Test create table if not exists with duplicate key error +# + +create table t1 (a int not null, b int, primary key (a)); +insert into t1 values (1,1); +create table if not exists t1 select 2; +select * from t1; +create table if not exists t1 select 3 as 'a',4 as 'b'; +--error 1062 +create table if not exists t1 select 3 as 'a',3 as 'b'; +select * from t1; +drop table t1; diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index 8e46b0808c0..653ea569172 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -51,16 +51,17 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) #if defined(HAVE_SETFILEPOINTER) /* This is for the moment only true on windows */ { + long is_success; HANDLE win_file= (HANDLE) _get_osfhandle(fd); long length_low, length_high; length_low= (long) (ulong) newlength; length_high= (long) ((ulonglong) newlength >> 32); - if (SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN)) - { - if (SetEndOfFile(win_file)) - DBUG_RETURN(0); - } - my_errno= errno; + is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN); + if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR) + goto err; + if (SetEndOfFile(win_file)) + DBUG_RETURN(0); + my_errno= GetLastError(); goto err; } #elif defined(HAVE_FTRUNCATE) diff --git a/sql/handler.h b/sql/handler.h index dfcfa44fbcd..03568e2e070 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -149,21 +149,21 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { - ulong table_options; - enum db_type db_type; - enum row_type row_type; - ulong avg_row_length; - ulonglong max_rows,min_rows; - ulonglong auto_increment_value; char *comment,*password; char *data_file_name, *index_file_name; - uint options; /* OR of HA_CREATE_ options */ - uint raid_type,raid_chunks; + ulonglong max_rows,min_rows; + ulonglong auto_increment_value; + ulong table_options; + ulong avg_row_length; ulong raid_chunksize; - bool if_not_exists; ulong used_fields; SQL_LIST merge_list; + enum db_type db_type; + enum row_type row_type; + uint options; /* OR of HA_CREATE_ options */ + uint raid_type,raid_chunks; uint merge_insert_method; + bool table_existed; /* 1 in create if table existed */ } HA_CREATE_INFO; diff --git a/sql/slave.cc b/sql/slave.cc index 12698c8eda4..9c380408291 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2719,6 +2719,8 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); err: + /* Free temporary tables etc */ + thd->cleanup(); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety VOID(pthread_mutex_unlock(&LOCK_thread_count)); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7c663ce831b..27258c025d8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -708,7 +708,6 @@ class select_create: public select_insert { HA_CREATE_INFO *create_info; MYSQL_LOCK *lock; Field **field; - my_bool do_not_drop; public: select_create (const char *db_name, const char *table_name, HA_CREATE_INFO *create_info_par, @@ -717,7 +716,7 @@ public: List &select_fields,enum_duplicates duplic) :select_insert (NULL, &select_fields, duplic), db(db_name), name(table_name), extra_fields(&fields_par),keys(&keys_par), - create_info(create_info_par), lock(0), do_not_drop(0) + create_info(create_info_par), lock(0) {} int prepare(List &list); bool send_data(List &values); @@ -725,6 +724,7 @@ public: void abort(); }; + class select_union :public select_result { public: TABLE *table; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ad08ad6ccd6..3aefee61c27 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1440,7 +1440,6 @@ select_create::prepare(List &values) if (table->fields < values.elements) { - do_not_drop=1; my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, ER(ER_WRONG_VALUE_COUNT_ON_ROW), MYF(0),1); @@ -1528,7 +1527,7 @@ void select_create::abort() enum db_type table_type=table->db_type; if (!table->tmp_table) hash_delete(&open_cache,(byte*) table); - if (!do_not_drop) + if (!create_info->table_existed) quick_rm_table(table_type,db,name); table=0; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 79105a94dec..94ecf33b9c6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -728,7 +728,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, && find_temporary_table(thd,db,table_name)) { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + { + create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); + } my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); DBUG_RETURN(-1); } @@ -739,13 +742,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { VOID(pthread_mutex_unlock(&LOCK_open)); if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + { + create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); + } my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); DBUG_RETURN(-1); } } thd->proc_info="creating table"; + create_info->table_existed= 0; // Mark that table is created if (thd->sql_mode & MODE_NO_DIR_IN_CREATE) create_info->data_file_name= create_info->index_file_name= 0; From ddbc8428546da197a031d24cfcafd1a545467e9b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 22:40:36 +0300 Subject: [PATCH 35/50] Portability fixes for windows After merge fixes include/my_base.h: Fix comment syntax libmysql/client_settings.h: Portability fixes for windows libmysql/libmysql.c: Portability fixes for windows libmysql/libmysql.def: Portability fixes for windows mysql-test/r/variables.result: Fix result after merge sql-common/client.c: Portability fixes for windows sql/ha_berkeley.cc: Use defines instead of constants sql/item_strfunc.cc: Portability fixes for windows sql/mysql_priv.h: Use defines instead of defines sql/mysqld.cc: After merge fix sql/opt_range.h: After merge fix sql/set_var.h: Portability fixes for windows sql/sql_class.cc: Defines instead of constants sql/sql_help.cc: after merge fixes More OOM error checking sql/sql_prepare.cc: After merge fixes sql/sql_table.cc: Portability fixes for windows --- include/my_base.h | 28 ++++++++++++++++------------ libmysql/client_settings.h | 6 +++--- libmysql/libmysql.c | 2 +- libmysql/libmysql.def | 2 +- mysql-test/r/variables.result | 2 +- sql-common/client.c | 4 ++-- sql/ha_berkeley.cc | 3 ++- sql/item_strfunc.cc | 2 ++ sql/mysql_priv.h | 3 +++ sql/mysqld.cc | 1 - sql/opt_range.h | 3 +-- sql/set_var.h | 2 +- sql/sql_class.cc | 8 +++++--- sql/sql_help.cc | 4 +++- sql/sql_prepare.cc | 18 ++++++++++++------ sql/sql_table.cc | 9 +++++---- 16 files changed, 58 insertions(+), 39 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index e36f73afe75..5af8a968cd0 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -49,20 +49,24 @@ /* The following is parameter to ha_rkey() how to use key */ -/* We define a complete-field prefix of a key value as a prefix where the -last included field in the prefix contains the full field, not just some bytes -from the start of the field. A partial-field prefix is allowed to -contain only a few first bytes from the last included field. +/* + We define a complete-field prefix of a key value as a prefix where + the last included field in the prefix contains the full field, not + just some bytes from the start of the field. A partial-field prefix + is allowed to contain only a few first bytes from the last included + field. -Below HA_READ_KEY_EXACT, ..., HA_READ_BEFORE_KEY can take a -complete-field prefix of a key value as the search key. HA_READ_PREFIX -and HA_READ_PREFIX_LAST could also take a partial-field prefix, but -currently (4.0.10) they are only used with complete-field prefixes. MySQL uses -a padding trick to implement LIKE 'abc%' queries. + Below HA_READ_KEY_EXACT, ..., HA_READ_BEFORE_KEY can take a + complete-field prefix of a key value as the search + key. HA_READ_PREFIX and HA_READ_PREFIX_LAST could also take a + partial-field prefix, but currently (4.0.10) they are only used with + complete-field prefixes. MySQL uses a padding trick to implement + LIKE 'abc%' queries. -NOTE that in InnoDB HA_READ_PREFIX_LAST will NOT work with a partial-field -prefix because InnoDB currently strips spaces from the end of varchar -fields! */ + NOTE that in InnoDB HA_READ_PREFIX_LAST will NOT work with a + partial-field prefix because InnoDB currently strips spaces from the + end of varchar fields! +*/ enum ha_rkey_function { HA_READ_KEY_EXACT, /* Find first record else error */ diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index b9c47c1dd55..582f9613ee0 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -52,9 +52,9 @@ void STDCALL cli_mysql_close(MYSQL *mysql); MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql); my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt); -MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - uint fields); +MYSQL_DATA * STDCALL cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + uint fields); int STDCALL cli_stmt_execute(MYSQL_STMT *stmt); -MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt); +MYSQL_DATA * STDCALL cli_read_binary_rows(MYSQL_STMT *stmt); int STDCALL cli_unbuffered_fetch(MYSQL *mysql, char **row); const char * STDCALL cli_read_statistic(MYSQL *mysql); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 08ea9deb11e..af39d3228e0 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3098,7 +3098,7 @@ no_data: Read all rows of data from server (binary format) */ -MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt) +MYSQL_DATA * STDCALL cli_read_binary_rows(MYSQL_STMT *stmt) { ulong pkt_len; uchar *cp; diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 1abc924e9c0..787aa645017 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -81,7 +81,7 @@ EXPORTS mysql_param_result mysql_ping mysql_prepare - mysql_prepare_result + mysql_get_metadata mysql_query mysql_read_query_result mysql_real_connect diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 3674d058bee..d65b44e7846 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -235,7 +235,7 @@ ERROR HY000: Variable 'myisam_max_sort_file_size' is a GLOBAL variable and shoul set myisam_max_extra_sort_file_size=100; ERROR HY000: Variable 'myisam_max_extra_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL set @@SQL_WARNINGS=NULL; -ERROR HY000: Variable 'sql_warnings' can't be set to the value of 'NULL' +ERROR 42000: Variable 'sql_warnings' can't be set to the value of 'NULL' set autocommit=1; set big_tables=1; select @@autocommit, @@big_tables; diff --git a/sql-common/client.c b/sql-common/client.c index 80a5a719376..15f906f4e34 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1137,8 +1137,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* Read all rows (fields or data) from server */ -MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - unsigned int fields) +MYSQL_DATA * STDCALL cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + unsigned int fields) { uint field; ulong pkt_len; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 0795c9d6a96..5b0fc95442c 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -238,7 +238,8 @@ int berkeley_show_logs(Protocol *protocol) MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); DBUG_ENTER("berkeley_show_logs"); - init_sql_alloc(&show_logs_root, 1024, 1024); + init_sql_alloc(&show_logs_root, BDB_LOG_ALLOC_BLOCK_SIZE, + BDB_LOG_ALLOC_BLOCK_SIZE); my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root); if ((error= db_env->log_archive(db_env, &all_logs, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c8ee64dc707..aa7a69769aa 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -33,7 +33,9 @@ #include "md5.h" #include "sha1.h" #include "my_aes.h" +C_MODE_START #include "../mysys/my_static.h" // For soundex_map +C_MODE_END String my_empty_string("",default_charset_info); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d1fe1abb2bd..f8ce32c6607 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -94,6 +94,9 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define ACL_ALLOC_BLOCK_SIZE 1024 #define UDF_ALLOC_BLOCK_SIZE 1024 #define TABLE_ALLOC_BLOCK_SIZE 1024 +#define BDB_LOG_ALLOC_BLOCK_SIZE 1024 +#define WARN_ALLOC_BLOCK_SIZE 2048 +#define WARN_ALLOC_PREALLOC_SIZE 1024 /* The following parameters is to decide when to use an extra cache to diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0664175d2a2..e3da3a31a3a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3575,7 +3575,6 @@ enum options OPT_SHARED_MEMORY_BASE_NAME, OPT_OLD_PASSWORDS, OPT_EXPIRE_LOGS_DAYS, - OPT_DEFAULT_WEEK_FORMAT, OPT_GROUP_CONCAT_MAX_LEN, OPT_DEFAULT_COLLATION, OPT_SECURE_AUTH, diff --git a/sql/opt_range.h b/sql/opt_range.h index 4c1aba7b829..128f6259055 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -127,8 +127,7 @@ class SQL_SELECT :public Sql_alloc { SQL_SELECT(); ~SQL_SELECT(); - bool check_quick(THD *thd, bool force_quick_range= 0, - ha_rows limit= HA_POS_ERROR) + bool check_quick(THD *thd, bool force_quick_range, ha_rows limit) { return test_quick_select(thd, ~0L,0,limit, force_quick_range) < 0; } inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; } int test_quick_select(THD *thd, key_map keys, table_map prev_tables, diff --git a/sql/set_var.h b/sql/set_var.h index 812bd6c9420..70667c719e5 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -693,7 +693,7 @@ public: uint name_length_arg, gptr data_arg) :name_length(name_length_arg), data(data_arg) { - name= my_memdup(name_arg, name_length, MYF(MY_WME)); + name= my_memdup((byte*) name_arg, name_length, MYF(MY_WME)); links->push_back(this); } inline bool cmp(const char *name_cmp, uint length) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2ac7b0856bd..2a869679adf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -148,7 +148,7 @@ THD::THD():user_time(0), is_fatal_error(0), bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root)); bzero((char*) &con_root,sizeof(con_root)); bzero((char*) &warn_root,sizeof(warn_root)); - init_alloc_root(&warn_root, 1024, 0); + init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, @@ -230,9 +230,11 @@ void THD::init(void) void THD::init_for_queries() { - init_sql_alloc(&mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + init_sql_alloc(&mem_root, variables.query_alloc_block_size, + variables.query_prealloc_size); init_sql_alloc(&transaction.mem_root, - TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC); + variables.trans_alloc_block_size, + variables.trans_prealloc_size); } diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 02fc8591370..6af4ffde0e1 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -599,7 +599,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables, { cond->fix_fields(thd, tables, &cond); // can never fail SQL_SELECT *res= make_select(table,0,0,cond,error); - return (*error || (res && res->check_quick(0, HA_POS_ERROR))) ? 0 : res; + return (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR))) ? 0 : res; } /* @@ -627,6 +627,8 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, Item *cond= new Item_func_like(new Item_field(pfname), new Item_string(mask,mlen,pfname->charset()), (char*) "\\"); + if (thd->is_fatal_error) + return 0; // OOM return prepare_simple_select(thd,cond,tables,table,error); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index dd8d5613880..522879c863a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -888,12 +888,15 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) { MEM_ROOT thd_root= thd->mem_root; PREP_STMT stmt; + SELECT_LEX *sl; DBUG_ENTER("mysql_stmt_prepare"); bzero((char*) &stmt, sizeof(stmt)); stmt.stmt_id= ++thd->current_stmt_id; - init_sql_alloc(&stmt.mem_root, 8192, 8192); + init_sql_alloc(&stmt.mem_root, + thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); stmt.thd= thd; stmt.thd->mem_root= stmt.mem_root; @@ -908,7 +911,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) my_pthread_setprio(pthread_self(),WAIT_PRIOR); // save WHERE clause pointers to avoid damaging they by optimisation - for (SELECT_LEX *sl= thd->lex.all_selects_list; + for (sl= thd->lex.all_selects_list; sl; sl= sl->next_select_in_list()) { @@ -943,8 +946,9 @@ err: void mysql_stmt_execute(THD *thd, char *packet) { - ulong stmt_id= uint4korr(packet); - PREP_STMT *stmt; + ulong stmt_id= uint4korr(packet); + PREP_STMT *stmt; + SELECT_LEX *sl; DBUG_ENTER("mysql_stmt_execute"); if (!(stmt=find_prepared_statement(thd, stmt_id, "execute"))) @@ -963,11 +967,13 @@ void mysql_stmt_execute(THD *thd, char *packet) LEX thd_lex= thd->lex; thd->lex= stmt->lex; - for (SELECT_LEX *sl= stmt->lex.all_selects_list; + for (sl= stmt->lex.all_selects_list; sl; sl= sl->next_select_in_list()) { - // copy WHERE clause pointers to avoid damaging they by optimisation + /* + Copy WHERE clause pointers to avoid damaging they by optimisation + */ if (sl->prep_where) sl->where= sl->prep_where->copy_andor_structure(thd); DBUG_ASSERT(sl->join == 0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8a736d91ffa..3c19464d80c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2656,9 +2656,9 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) while (!t->file->rnd_next(t->record[0])) { ha_checksum row_crc= 0; - if (t->record[0] != t->field[0]->ptr) + if (t->record[0] != (byte*) t->field[0]->ptr) row_crc= my_checksum(row_crc, t->record[0], - t->field[0]->ptr - t->record[0]); + ((byte*) t->field[0]->ptr) - t->record[0]); for (uint i= 0; i < t->fields; i++ ) { @@ -2667,10 +2667,11 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { String tmp; f->val_str(&tmp,&tmp); - row_crc= my_checksum(row_crc, tmp.ptr(), tmp.length()); + row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length()); } else - row_crc= my_checksum(row_crc, f->ptr, f->pack_length()); + row_crc= my_checksum(row_crc, (byte*) f->ptr, + f->pack_length()); } crc+= row_crc; From efd76a94dea089de4b51cfc7aa5bc5a61d12273c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 19:46:53 -0400 Subject: [PATCH 36/50] Created small scripts to manage in-tree diffs for NetWare platform, so changes are visible in the tree but cannot affect other platforms --- netware/BUILD/apply-patch | 41 ++++++++++++++++++++++++++++ netware/BUILD/save-patch | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100755 netware/BUILD/apply-patch create mode 100755 netware/BUILD/save-patch diff --git a/netware/BUILD/apply-patch b/netware/BUILD/apply-patch new file mode 100755 index 00000000000..3fe5a077f9a --- /dev/null +++ b/netware/BUILD/apply-patch @@ -0,0 +1,41 @@ +#! /bin/sh + +# debug +#set -x + +# stop on errors +set -e + +# repository directory +repo_dir=`pwd` + +# show usage +show_usage() +{ + cat << EOF + +usage: apply-patch + +Imports netware/current-changes.patch so that current changes +for the platform are present on the local repository. + +Use from the root directory of the repository, with BitKeeper +installed. + +EOF + exit 0; +} + +if test $1 || test -z $BK_USER +then + show_usage +fi + +echo "starting patch..." + +echo "user: $BK_USER" + +# import patch +# Note: In future this should be changed to check whether +# the repo already has this patch +bk import -tpatch $repo_dir/netware/current-changes.patch $repo_dir diff --git a/netware/BUILD/save-patch b/netware/BUILD/save-patch new file mode 100755 index 00000000000..9f9979ace5b --- /dev/null +++ b/netware/BUILD/save-patch @@ -0,0 +1,56 @@ +#! /bin/sh + +# debug +#set -x + +# stop on errors +set -e + +# repository directory +repo_dir=`pwd` + +# show usage +show_usage() +{ + cat << EOF + +usage: save-patch + +Creates a patch file between the latest revision of the current tree +and the latest revision not created by \$BK_USER and places it in +the tree as netware/current-changes.patch + +EOF + exit 0; +} + +if test $1 || test -z $BK_USER +then + show_usage +fi + +echo "starting patch..." + +echo "user: $BK_USER" + +# check for bk and repo_dir +bk help > /dev/null +repo_dir=`bk root $repo_dir` +cd $repo_dir + +# determine version +version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"` +echo "version: $version" + +# user revision +user_rev=`bk changes -e -n -d':REV:' | head -1` +echo "latest revision: $user_rev" + +# tree revision +tree_rev=`bk changes -e -n -d':REV:' -U$BK_USER | head -1` +echo "latest non-$BK_USER revision: $tree_rev" + +# create patch +patch="$repo_dir/netware/current-changes.patch" +echo "creating \"$patch\"..." +bk export -tpatch -r$tree_rev..$user_rev -xnetware/current-changes.patch > $patch From 0b45b5c63263870780b58498e8ad26713e5b37b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 07:44:18 +0300 Subject: [PATCH 37/50] Changing max_insert_delayed_threads now also changes the size of thread alarm buffer. --- sql/set_var.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sql/set_var.cc b/sql/set_var.cc index fbcc341f128..03651967a7a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -47,6 +47,7 @@ #include "slave.h" #include "sql_acl.h" #include +#include #include #ifdef HAVE_BERKELEY_DB #include "ha_berkeley.h" @@ -153,7 +154,8 @@ sys_var_long_ptr sys_max_connections("max_connections", sys_var_long_ptr sys_max_connect_errors("max_connect_errors", &max_connect_errors); sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads", - &max_insert_delayed_threads); + &max_insert_delayed_threads, + fix_max_connections); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); sys_var_thd_ha_rows sys_max_join_size("max_join_size", @@ -753,13 +755,13 @@ static void fix_max_relay_log_size(THD *thd, enum_var_type type) DBUG_VOID_RETURN; } -#include -static void -fix_max_connections(THD *thd, enum_var_type type) + +static void fix_max_connections(THD *thd, enum_var_type type) { - resize_thr_alarm(max_connections); + resize_thr_alarm(max_connections + max_insert_delayed_threads + 10); } + bool sys_var_long_ptr::update(THD *thd, set_var *var) { ulonglong tmp= var->value->val_int(); From a474f8c3199e590217ab099df5f0e30b01bba4a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 08:16:39 +0300 Subject: [PATCH 38/50] Update results after merge --- mysql-test/r/create.result | 10 +++++----- mysql-test/r/mysqldump.result | 3 --- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 805a21d92ca..35565457274 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -220,10 +220,12 @@ ERROR 23000: Column 'k1' cannot be null insert into t1 values (NULL, NULL); ERROR 23000: Column 'k1' cannot be null drop table t1; +create table t1 select x'4132'; +drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; create table if not exists t1 select 1,2,3,4; -Column count doesn't match value count at row 1 +ERROR 21S01: Column count doesn't match value count at row 1 create table if not exists t1 select 1; select * from t1; 1 2 3 @@ -234,7 +236,7 @@ drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; create table if not exists t1 select 1,2,3,4; -Column count doesn't match value count at row 1 +ERROR 21S01: Column count doesn't match value count at row 1 create table if not exists t1 select 1; select * from t1; 1 2 3 @@ -251,7 +253,7 @@ a b 0 2 create table if not exists t1 select 3 as 'a',4 as 'b'; create table if not exists t1 select 3 as 'a',3 as 'b'; -Duplicate entry '3' for key 1 +ERROR 23000: Duplicate entry '3' for key 1 select * from t1; a b 1 1 @@ -358,8 +360,6 @@ t1 CREATE TABLE `t1` ( ) TYPE=MyISAM CHARSET=latin1 SET SESSION table_type=default; drop table t1; -create table t1 select x'4132'; -drop table t1; create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob); insert into t1(a)values(1); insert into t1(a,b,c,d,e,f,g,h) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index cf1ef55ca69..085cf2788f9 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4,8 +4,6 @@ INSERT INTO t1 VALUES (1), (2); -DROP TABLE IF EXISTS t1; -LOCK TABLES t1 WRITE; 1 @@ -14,7 +12,6 @@ LOCK TABLES t1 WRITE; 2
-UNLOCK TABLES;
DROP TABLE t1; From e83a7c2cf7b95247e639d9dc5318edfa91416e79 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 08:34:17 +0300 Subject: [PATCH 39/50] Fix test after merge mysql-test/r/create.result: update test results --- mysql-test/r/create.result | 5 ++++- mysql-test/t/create.test | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 35565457274..90b163c8e19 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -15,6 +15,8 @@ select * from t1; b +drop table t1; +create table t1 (a int not null auto_increment,primary key (a)) type=heap; drop table t1; create table t2 type=heap select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -26,10 +28,11 @@ Note 1051 Unknown table 't1' Note 1051 Unknown table 't2' create table t1 (b char(0) not null, index(b)); ERROR 42000: The used storage engine can't index column 'b' -create table t1 (a int not null auto_increment,primary key (a)) type=heap; create table t1 (a int not null,b text) type=heap; ERROR 42000: The used table type doesn't support BLOB/TEXT columns drop table if exists t1; +Warnings: +Note 1051 Unknown table 't1' create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap; ERROR 42000: Incorrect table definition; There can only be one auto column and it must be defined as a key create table not_existing_database.test (a int); diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 0148fa9431a..bc71c597270 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -17,6 +17,9 @@ insert into t1 values (""),(null); select * from t1; drop table t1; +create table t1 (a int not null auto_increment,primary key (a)) type=heap; +drop table t1; + # # Test of some CREATE TABLE'S that should fail # @@ -28,8 +31,6 @@ create table t2 select auto+1 from t1; drop table if exists t1,t2; --error 1167 create table t1 (b char(0) not null, index(b)); ---error 1164 -create table t1 (a int not null auto_increment,primary key (a)) type=heap; --error 1163 create table t1 (a int not null,b text) type=heap; drop table if exists t1; From ff50211da5efe976c6d356d6e9642c5f10c2f928 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 11:33:44 -0400 Subject: [PATCH 40/50] added checking for empty index name (fixed bug #1419) include/mysqld_error.h: added error "Incorrect index name" mysql-test/r/create.result: added test for empty index name mysql-test/t/create.test: added test for empty index name sql/share/czech/errmsg.txt: added error "Incorrect index name" sql/share/danish/errmsg.txt: added error "Incorrect index name" sql/share/dutch/errmsg.txt: added error "Incorrect index name" sql/share/english/errmsg.txt: added error "Incorrect index name" sql/share/estonian/errmsg.txt: added error "Incorrect index name" sql/share/french/errmsg.txt: added error "Incorrect index name" sql/share/german/errmsg.txt: added error "Incorrect index name" sql/share/greek/errmsg.txt: added error "Incorrect index name" sql/share/hungarian/errmsg.txt: added error "Incorrect index name" sql/share/italian/errmsg.txt: added error "Incorrect index name" sql/share/japanese/errmsg.txt: added error "Incorrect index name" sql/share/korean/errmsg.txt: added error "Incorrect index name" sql/share/norwegian-ny/errmsg.txt: added error "Incorrect index name" sql/share/norwegian/errmsg.txt: added error "Incorrect index name" sql/share/polish/errmsg.txt: added error "Incorrect index name" sql/share/portuguese/errmsg.txt: added error "Incorrect index name" sql/share/romanian/errmsg.txt: added error "Incorrect index name" sql/share/russian/errmsg.txt: added error "Incorrect index name" sql/share/serbian/errmsg.txt: added error "Incorrect index name" sql/share/slovak/errmsg.txt: added error "Incorrect index name" sql/share/spanish/errmsg.txt: added error "Incorrect index name" sql/share/swedish/errmsg.txt: added error "Incorrect index name" sql/share/ukrainian/errmsg.txt: added error "Incorrect index name" sql/sql_table.cc: added checking for wrong index name --- include/mysqld_error.h | 3 ++- mysql-test/r/create.result | 2 ++ mysql-test/t/create.test | 2 ++ sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sql_table.cc | 5 +++++ 27 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 3c20202603f..53714505fc2 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -295,4 +295,5 @@ #define ER_BAD_SLAVE_UNTIL_COND 1276 #define ER_MISSING_SKIP_SLAVE 1277 #define ER_UNTIL_COND_IGNORED 1278 -#define ER_ERROR_MESSAGES 279 +#define ER_WRONG_INDEX_NAME 1279 +#define ER_ERROR_MESSAGES 280 diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 90b163c8e19..143a897429e 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -69,6 +69,8 @@ drop table if exists ``; ERROR 42000: Incorrect table name '' create table t1 (`` int); ERROR 42000: Incorrect column name '' +create table t1 (i int, index `` (i)); +ERROR HY000: Incorrect index name '' drop table if exists t1; Warnings: Note 1051 Unknown table 't1' diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index bc71c597270..4cde963ca4b 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -72,6 +72,8 @@ create table `` (a int); drop table if exists ``; --error 1166 create table t1 (`` int); +--error 1279 +create table t1 (i int, index `` (i)); drop table if exists t1; # diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index e7cc54746b5..bb7cd90b4c4 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -291,3 +291,4 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 379865a775b..48a4fee22f8 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -285,3 +285,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index ffe76be0d42..98fb9278cc2 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -293,3 +293,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index c352b143ef1..9a266c41669 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -282,3 +282,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 657c5a24539..e596863907f 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -287,3 +287,4 @@ character-set=latin7 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index ab7936aff48..a81b8859692 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -282,3 +282,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index f50169251f7..9554822a5ff 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -294,3 +294,4 @@ character-set=latin1 "Falscher Parameter oder falsche Kombination von Parametern für START SLAVE UNTIL", "Es wird empfohlen, mit --skip-slave-start zu starten, wenn mit START SLAVE UNTIL eine Schritt-für-Schritt-Replikation ausgeführt wird. Ansonsten gibt es Probleme, wenn der Slave-Server unerwartet neu startet", "SQL-Thread soll nicht gestartet werden. Daher werden UNTIL-Optionen ignoriert" +"Incorrect index name '%-.100s'", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 93f78bf2a93..073289562b3 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -282,3 +282,4 @@ character-set=greek "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f12fbbc938b..c62a7c7b1ae 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -284,3 +284,4 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 8d44a83ed3b..004d7d00994 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -282,3 +282,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index dcd3db0d7a9..888ac449a8b 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -284,3 +284,4 @@ character-set=ujis "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 363d81e4dea..a72d6c3fdee 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -282,3 +282,4 @@ character-set=euckr "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e2427327c77..3c6dca27016 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -284,3 +284,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 7083bd80085..bafc635a184 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -284,3 +284,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index f770b2e3030..0aa25aabb44 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -286,3 +286,4 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 3c265349cdf..33d8f68291d 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -283,3 +283,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c1c495d39c3..ff46caf2c6c 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -286,3 +286,4 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 572d515453a..f8bdb8bf4a5 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -284,3 +284,4 @@ character-set=koi8r "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index a81b5f56838..cede04e36ed 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -277,3 +277,4 @@ character-set=cp1250 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 6ca9bcecf1c..0759f68a1bb 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -290,3 +290,4 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 62d32757719..b9c1b297e43 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -284,3 +284,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index f06a760bb24..456b93fbc4d 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -282,3 +282,4 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 675e9899d58..dba62fd60c8 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -287,3 +287,4 @@ character-set=koi8u "Wrong parameter or combination of parameters for START SLAVE UNTIL" "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" "SQL thread is not to be started so UNTIL options are ignored" +"Incorrect index name '%-.100s'", diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5417a1b0368..3d07c7e04de 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -861,6 +861,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->name=(char*) key_name; } } + if (!key_info->name || check_column_name(key_info->name)) + { + my_error(ER_WRONG_INDEX_NAME, MYF(0), key_info->name); + DBUG_RETURN(-1); + } if (!(key_info->flags & HA_NULL_PART_KEY)) unique_key=1; key_info->key_length=(uint16) key_length; From 0d28ff8473f0c1c7159d777a3af088bf8ea03ea5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 16:15:45 -0400 Subject: [PATCH 41/50] fixed sqlstate for ER_WRONG_INDEX_NAME removed unnesessary code from create.test include/sql_state.h: added sqlstate for ER_WRONG_INDEX_NAME mysql-test/r/create.result: changed sqlstate for ER_WRONG_INDEX_NAME remove unnesesary warning mysql-test/t/create.test: remove unnesessary drop table --- include/sql_state.h | 1 + mysql-test/r/create.result | 5 +---- mysql-test/t/create.test | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/sql_state.h b/include/sql_state.h index c0b7cf97ea5..222636d3bec 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -159,3 +159,4 @@ ER_WARN_TOO_MANY_RECORDS, "01000", "", ER_WARN_NULL_TO_NOTNULL, "01000", "", ER_WARN_DATA_OUT_OF_RANGE, "01000", "", ER_WARN_DATA_TRUNCATED, "01000", "", +ER_WRONG_INDEX_NAME, "42000", "", diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 143a897429e..d61614180b3 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -70,10 +70,7 @@ ERROR 42000: Incorrect table name '' create table t1 (`` int); ERROR 42000: Incorrect column name '' create table t1 (i int, index `` (i)); -ERROR HY000: Incorrect index name '' -drop table if exists t1; -Warnings: -Note 1051 Unknown table 't1' +ERROR 42000: Incorrect index name '' create table t1 (a int auto_increment not null primary key, B CHAR(20)); insert into t1 (b) values ("hello"),("my"),("world"); create table t2 (key (b)) select * from t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 4cde963ca4b..059808161a3 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -74,7 +74,6 @@ drop table if exists ``; create table t1 (`` int); --error 1279 create table t1 (i int, index `` (i)); -drop table if exists t1; # # Test of CREATE ... SELECT with indexes From d894f23372ad7abd1efd108562574b4d15dd0709 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 22:15:46 +0200 Subject: [PATCH 42/50] - portability fix: fix compile bug on HP-UX (thanks to acurtis for the patch) (BUG#1440: Redundant class name confusing hpux compiler) --- sql/item.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item.h b/sql/item.h index a126a61e32e..517d3f311e5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -322,7 +322,7 @@ public: bool long_data_supplied; uint pos_in_query; - Item_param::Item_param(uint position) + Item_param(uint position) { name= (char*) "?"; pos_in_query= position; From 6795b2642b155e64e73aa7571f30b84b090c3636 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Oct 2003 15:18:57 +0300 Subject: [PATCH 43/50] fixed deleting derived table tree after using (BUG#1536) mysql-test/r/subselect.result: fixed drop table statement test for BUG#1536 mysql-test/t/subselect.test: fixed drop table statement test for BUG#1536 sql/sql_derived.cc: all tree of derived table should be deleted sql/sql_lex.cc: delete subtree method sql/sql_lex.h: delete subtree method --- mysql-test/r/subselect.result | 9 ++++++++- mysql-test/t/subselect.test | 11 ++++++++++- sql/sql_derived.cc | 2 +- sql/sql_lex.cc | 35 ++++++++++++++++++++++++++++++++++- sql/sql_lex.h | 1 + 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6e35b6e78c1..a2460b8f11a 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1438,4 +1438,11 @@ explain select * from t3 where a > all (select max(b) from t2 group by a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort -drop table if exists t2, t3; +drop table t2, t3; +create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) +); +insert into t1 VALUES(1,1,1), (2,2,1); +select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +count(*) +2 +drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9ba91c7e0a6..afc2d1a9328 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -964,4 +964,13 @@ explain select * from t3 where a >= all (select b from t2); insert into t2 values (2,2), (2,1), (3,3), (3,1); select * from t3 where a > all (select max(b) from t2 group by a); explain select * from t3 where a > all (select max(b) from t2 group by a); -drop table if exists t2, t3; +drop table t2, t3; + +# +# deived tables with subquery inside all by one table +# +create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) +); +insert into t1 VALUES(1,1,1), (2,2,1); +select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +drop table t1; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 13d3cc27376..7fd2b751c1d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -220,7 +220,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, } } else - unit->exclude_level(); + unit->exclude_tree(); org_table_list->db= (char *)""; #ifndef DBUG_OFF /* Try to catch errors if this is accessed */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 80d698dfc26..5b05bf096cb 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1097,6 +1097,16 @@ void st_select_lex_node::exclude() */ } + +/* + Exclude level of current unit from tree of SELECTs + + SYNOPSYS + st_select_lex_unit::exclude_level() + + NOTE: units which belong to current will be brought up on level of + currernt unit +*/ void st_select_lex_unit::exclude_level() { SELECT_LEX_UNIT *units= 0, **units_last= &units; @@ -1125,6 +1135,30 @@ void st_select_lex_unit::exclude_level() (*prev)= next; } + +/* + Exclude subtree of current unit from tree of SELECTs + + SYNOPSYS + st_select_lex_unit::exclude_tree() +*/ +void st_select_lex_unit::exclude_tree() +{ + SELECT_LEX_UNIT *units= 0, **units_last= &units; + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + { + if (sl->link_prev && (*sl->link_prev= sl->link_next)) + sl->link_next->link_prev= sl->link_prev; + + for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit()) + { + u->exclude_level(); + } + } + (*prev)= next; +} + + /* st_select_lex_node::mark_as_dependent mark all st_select_lex struct from this to 'last' as dependent @@ -1135,7 +1169,6 @@ void st_select_lex_unit::exclude_level() NOTE 'last' should be reachable from this st_select_lex_node - */ void st_select_lex::mark_as_dependent(SELECT_LEX *last) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0166951ab9d..7545f525082 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -321,6 +321,7 @@ public: st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } st_select_lex* return_after_parsing() { return return_to; } void exclude_level(); + void exclude_tree(); /* UNION methods */ int prepare(THD *thd, select_result *result, bool tables_and_fields_initied); From 6713bb090d81a6e2b48ecf0fb28b85e0d3ae1ee1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Oct 2003 20:31:17 +0300 Subject: [PATCH 44/50] thr0loc.c, srv0start.c, srv0srv.c, srv0srv.h, os0thread.h: Reduce InnoDB memory allocation if buffer pool < 8 MB innobase/include/os0thread.h: Reduce InnoDB memory allocation if buffer pool < 8 MB innobase/include/srv0srv.h: Reduce InnoDB memory allocation if buffer pool < 8 MB innobase/srv/srv0srv.c: Reduce InnoDB memory allocation if buffer pool < 8 MB innobase/srv/srv0start.c: Reduce InnoDB memory allocation if buffer pool < 8 MB innobase/thr/thr0loc.c: Reduce InnoDB memory allocation if buffer pool < 8 MB --- innobase/include/os0thread.h | 11 +++-------- innobase/include/srv0srv.h | 2 ++ innobase/srv/srv0srv.c | 13 +++++++++++-- innobase/srv/srv0start.c | 24 +++++++++++++++++++++++- innobase/thr/thr0loc.c | 1 + 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h index 491d8866af4..554ca0563e4 100644 --- a/innobase/include/os0thread.h +++ b/innobase/include/os0thread.h @@ -15,14 +15,9 @@ Created 9/8/1995 Heikki Tuuri /* Maximum number of threads which can be created in the program; this is also the size of the wait slot array for MySQL threads which can wait inside InnoDB */ -#if defined(__WIN__) || defined(__NETWARE__) -/* Create less event semaphores because Win 98/ME had difficult creating -40000 event semaphores */ -/* TODO: these just take a lot of memory on NetWare. should netware move up? */ -#define OS_THREAD_MAX_N 1000 -#else -#define OS_THREAD_MAX_N 10000 -#endif + +#define OS_THREAD_MAX_N srv_max_n_threads + /* Possible fixed priorities for threads */ #define OS_THREAD_PRIORITY_NONE 100 diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 094b95e68d3..6e47c468d26 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -87,6 +87,8 @@ extern ulint srv_max_dirty_pages_pct; extern ulint srv_force_recovery; extern ulint srv_thread_concurrency; +extern ulint srv_max_n_threads; + extern lint srv_conc_n_threads; extern ibool srv_fast_shutdown; diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index e16073c171c..2f3502f99ad 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -180,6 +180,12 @@ the user from forgetting the innodb_force_recovery keyword to my.cnf */ ulint srv_force_recovery = 0; /*-----------------------*/ +/* We are prepared for a situation that we have this many threads waiting for +a semaphore inside InnoDB. innobase_start_or_create_for_mysql() sets the +value. */ + +ulint srv_max_n_threads = 0; + /* The following controls how many threads we let inside InnoDB concurrently: threads waiting for locks are not counted into the number because otherwise we could get a deadlock. MySQL creates a thread for each user session, and @@ -219,7 +225,7 @@ struct srv_conc_slot_struct{ UT_LIST_BASE_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue of threads waiting to get in */ -srv_conc_slot_t srv_conc_slots[OS_THREAD_MAX_N]; /* array of wait +srv_conc_slot_t* srv_conc_slots; /* array of wait slots */ /* Number of times a thread is allowed to enter InnoDB within the same @@ -1712,6 +1718,8 @@ srv_init(void) UT_LIST_INIT(srv_conc_queue); + srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t)); + for (i = 0; i < OS_THREAD_MAX_N; i++) { conc_slot = srv_conc_slots + i; conc_slot->reserved = FALSE; @@ -1758,7 +1766,7 @@ srv_conc_enter_innodb( thread */ { ibool has_slept = FALSE; - srv_conc_slot_t* slot; + srv_conc_slot_t* slot = NULL; ulint i; char err_buf[1000]; @@ -1835,6 +1843,7 @@ retry: slot = srv_conc_slots + i; if (!slot->reserved) { + break; } } diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 5de87038bde..83cde6e6589 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1138,10 +1138,32 @@ innobase_start_or_create_for_mysql(void) srv_file_flush_method_str); return(DB_ERROR); } + + /* Set the maximum number of threads which can wait for a semaphore + inside InnoDB */ +#if defined(__WIN__) || defined(__NETWARE__) +/* Create less event semaphores because Win 98/ME had difficulty creating +40000 event semaphores. +Comment from Novell, Inc.: also, these just take a lot of memory on +NetWare. */ + srv_max_n_threads = 1000; +#else + if (srv_pool_size >= 8 * 1024) { + /* Here we still have srv_pool_size counted + in kilobytes, srv_boot converts the value to + pages; if buffer pool is less than 8 MB, + assume fewer threads. */ + srv_max_n_threads = 10000; + } else { + srv_max_n_threads = 1000; /* saves several MB of memory, + especially in 64-bit + computers */ + } +#endif /* Note that the call srv_boot() also changes the values of srv_pool_size etc. to the units used by InnoDB internally */ - + err = srv_boot(); if (err != DB_SUCCESS) { diff --git a/innobase/thr/thr0loc.c b/innobase/thr/thr0loc.c index fbf3e3a1dad..839cb024f25 100644 --- a/innobase/thr/thr0loc.c +++ b/innobase/thr/thr0loc.c @@ -14,6 +14,7 @@ Created 10/5/1995 Heikki Tuuri #include "sync0sync.h" #include "hash0hash.h" #include "mem0mem.h" +#include "srv0srv.h" /* IMPLEMENTATION OF THREAD LOCAL STORAGE From be4e254b132987a41ec034217e9fde2c15cfc0d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Oct 2003 14:25:33 +0300 Subject: [PATCH 45/50] correct table name assigned to temporary table field: - correct table name shown in EXPLAIN Iindex reference) - pointer on freed memmory (reallocation of table name in reusing table entry) can't be used in EXPLAIN (BUG#1584) mysql-test/r/derived.result: test moved to derived table tests added test of BUG#1584 mysql-test/r/subselect.result: test moved to derived table tests mysql-test/t/derived.test: test moved to derived table tests added test of BUG#1584 mysql-test/t/subselect.test: test moved to derived table tests sql/item.cc: layout fix sql/sql_select.cc: correct table name assigned to temporary table field --- mysql-test/r/derived.result | 15 +++++++++++++++ mysql-test/r/subselect.result | 7 ------- mysql-test/t/derived.test | 10 ++++++++++ mysql-test/t/subselect.test | 9 --------- sql/item.cc | 12 +++++++----- sql/sql_select.cc | 3 +++ 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index d24ac5e898a..12d8bbaf8ae 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -215,3 +215,18 @@ ERROR 42000: You have an error in your SQL syntax. Check the manual that corres insert into (select * from t1) values (5); 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 '(select * from t1) values (5)' at line 1 drop table t1; +create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) +); +insert into t1 VALUES(1,1,1), (2,2,1); +select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +count(*) +2 +explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1275 Field or reference 'A.E2' of SELECT #3 was resolved in SELECT #2 +drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index a2460b8f11a..14a132531ca 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1439,10 +1439,3 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort drop table t2, t3; -create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) -); -insert into t1 VALUES(1,1,1), (2,2,1); -select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; -count(*) -2 -drop table t1; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index a8583aa5ea3..80b131ac6fe 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -122,3 +122,13 @@ delete from (select * from t1); -- error 1064 insert into (select * from t1) values (5); drop table t1; + +# +# deived tables with subquery inside all by one table +# +create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) +); +insert into t1 VALUES(1,1,1), (2,2,1); +select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index afc2d1a9328..8c0b3fb3919 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -965,12 +965,3 @@ insert into t2 values (2,2), (2,1), (3,3), (3,1); select * from t3 where a > all (select max(b) from t2 group by a); explain select * from t3 where a > all (select max(b) from t2 group by a); drop table t2, t3; - -# -# deived tables with subquery inside all by one table -# -create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) -); -insert into t1 VALUES(1,1,1), (2,2,1); -select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; -drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 4de4951cb51..6fbc3a304d6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -272,11 +272,13 @@ Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) } // Constructor need to process subselect with temporary tables (see Item) -Item_field::Item_field(THD *thd, Item_field &item): - Item_ident(thd, item), - field(item.field), - result_field(item.result_field) -{ collation.set(DERIVATION_IMPLICIT); } +Item_field::Item_field(THD *thd, Item_field &item) + :Item_ident(thd, item), + field(item.field), + result_field(item.result_field) +{ + collation.set(DERIVATION_IMPLICIT); +} void Item_field::set_field(Field *field_par) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 89aae95c951..9bdb989b6a1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4866,6 +4866,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, recinfo->type=FIELD_NORMAL; if (!--hidden_field_count) null_count=(null_count+7) & ~7; // move to next byte + + // fix table name in field entry + field->table_name= table->table_name; } param->copy_field_end=copy; From 2a98f2943e1a4548d3e7fa20d2e517a11c021556 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Oct 2003 16:57:17 -0400 Subject: [PATCH 46/50] made more fine error message in scripts/fill_help_tables.sh scripts/fill_help_tables.sh: made more fine error message --- scripts/fill_help_tables.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/fill_help_tables.sh b/scripts/fill_help_tables.sh index 8ba05910596..cb5437f7178 100644 --- a/scripts/fill_help_tables.sh +++ b/scripts/fill_help_tables.sh @@ -112,6 +112,7 @@ sub add_topic_to_category $categories{$current_category}->{$topic_name}= $topics{$topic_name}; my $category= $categories{$current_category}; + $category->{__name__}= $current_category; if (exists($category->{__parent_category__})) { @@ -132,7 +133,7 @@ sub add_topic_to_category my $old_category= $topics{$topic_name}->{category}; if ($old_category ne $category) { - print_error "wrong category for $topic_name\n"; + print_error "wrong category for $topic_name (first one's \"$old_category->{__name__}\" second one's \"$current_category\")\n"; } } From 299fc6a9f536571998f1fbc69a599800d3c95166 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Oct 2003 13:24:18 +0500 Subject: [PATCH 47/50] Scrum task 835 - text-to-datetime conversion function --- mysql-test/r/date_formats.result | 157 ++++ mysql-test/t/date_formats-master.opt | 1 + mysql-test/t/date_formats.test | 82 ++ sql/field.cc | 71 +- sql/item.cc | 34 +- sql/item.h | 10 +- sql/item_create.cc | 5 + sql/item_create.h | 1 + sql/item_timefunc.cc | 1123 +++++++++++++++++--------- sql/item_timefunc.h | 43 + sql/lex.h | 2 + sql/mysql_priv.h | 27 +- sql/mysqld.cc | 68 +- sql/protocol.cc | 45 +- sql/set_var.cc | 72 ++ sql/set_var.h | 50 ++ sql/sql_class.cc | 3 + sql/sql_class.h | 1 + sql/sql_yacc.yy | 11 + sql/structs.h | 9 +- sql/time.cc | 328 +++++++- 21 files changed, 1649 insertions(+), 494 deletions(-) create mode 100644 mysql-test/r/date_formats.result create mode 100644 mysql-test/t/date_formats-master.opt create mode 100644 mysql-test/t/date_formats.test diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result new file mode 100644 index 00000000000..590a1d6904b --- /dev/null +++ b/mysql-test/r/date_formats.result @@ -0,0 +1,157 @@ +SHOW GLOBAL VARIABLES LIKE "%_format%"; +Variable_name Value +date_format %d.%m.%Y +datetime_format %Y/%d/%m-%H:%i:%s +default_week_format 0 +time_format %H.%i.%s +SHOW SESSION VARIABLES LIKE "%_format%"; +Variable_name Value +date_format %d.%m.%Y +datetime_format %Y/%d/%m-%H:%i:%s +default_week_format 0 +time_format %H.%i.%s +SET date_format="%d.%m.%Y"; +select CAST("01.01.2001" as DATE) as a; +a +01.01.2001 +SET datetime_format="%d.%m.%Y %H.%i.%s"; +select CAST("01.01.2001 05.12.06" as DATETIME) as a; +a +01.01.2001 05.12.06 +SET time_format="%H.%i.%s"; +select CAST("05.12.06" as TIME) as a; +a +05.12.06 +SET datetime_format="%d.%m.%Y %h:%i:%s %p"; +select CAST("01.01.2001 05:12:06AM" as DATETIME) as a; +a +01.01.2001 05:12:06 AM +select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a; +a +01.01.2001 05:12:06 PM +SET time_format="%h:%i:%s %p"; +select CAST("05:12:06 AM" as TIME) as a; +a +05:12:06 AM +select CAST("05:12:06.1234PM" as TIME) as a; +a +05:12:06.001234 PM +SET time_format="%h.%i.%s %p"; +SET date_format='%d.%m.%y'; +SET datetime_format="%d.%m.%y %h.%i.%s %p"; +select CAST("12-12-06" as DATE) as a; +a +12.12.06 +select adddate("01.01.97 11.59.59.000001 PM", 10); +adddate("01.01.97 11.59.59.000001 PM", 10) +11.01.97 11.59.59.000001 PM +select datediff("31.12.97 11.59:59.000001 PM","01.01.98"); +datediff("31.12.97 11.59:59.000001 PM","01.01.98") +-1 +select weekofyear("31.11.97 11:59:59.000001 PM"); +weekofyear("31.11.97 11:59:59.000001 PM") +49 +select makedate(1997,1); +makedate(1997,1) +01.01.97 +select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"); +addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002") +02.01.98 01.01.01.000001 AM +select maketime(23,11,12); +maketime(23,11,12) +11.11.12 PM +select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"); +timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM") +8795.59.59.999999 PM +SET time_format="%H%i%s"; +SET time_format="%h%i%s"; +ERROR HY000: Unknown error +SET date_format='%d.%m.%d'; +ERROR HY000: Unknown error +SET datetime_format="%d.%m.%y %h.%i.%s"; +ERROR HY000: Unknown error +SET GLOBAL date_format=default; +SHOW GLOBAL VARIABLES LIKE "date_format%"; +Variable_name Value +date_format %d.%m.%Y +SET GLOBAL time_format=default; +SHOW GLOBAL VARIABLES LIKE "time_format%"; +Variable_name Value +time_format %H.%i.%s +SET GLOBAL datetime_format=default; +SHOW GLOBAL VARIABLES LIKE "datetime_format%"; +Variable_name Value +datetime_format %Y/%d/%m-%H:%i:%s +SET date_format=default; +SHOW SESSION VARIABLES LIKE "date_format%"; +Variable_name Value +date_format %d.%m.%Y +SET time_format=default; +SHOW SESSION VARIABLES LIKE "time_format%"; +Variable_name Value +time_format %H.%i.%s +SET datetime_format=default; +SHOW SESSION VARIABLES LIKE "datetime_format%"; +Variable_name Value +datetime_format %Y/%d/%m-%H:%i:%s +SET time_format='%i:%s:%H'; +select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME); +cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME) +59:59:12 +SET GLOBAL date_format='%Y-%m-%d'; +SET GLOBAL time_format='%H:%i:%s'; +SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s'; +SET date_format='%Y-%m-%d'; +SET time_format='%H:%i:%s'; +SET datetime_format='%Y-%m-%d %H:%i:%s'; +select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S"); +str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") +2001-01-15 12:59:59 +select str_to_date("15 September 2001", "%d %M %Y"); +str_to_date("15 September 2001", "%d %M %Y") +2001-09-15 00:00:00 +select str_to_date("15 Septembeb 2001", "%d %M %Y"); +str_to_date("15 Septembeb 2001", "%d %M %Y") +NULL +select str_to_date("15 MAY 2001", "%d %b %Y"); +str_to_date("15 MAY 2001", "%d %b %Y") +2001-05-15 00:00:00 +select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y"); +str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y") +2001-05-15 00:00:00 +select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y"); +str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y") +NULL +select str_to_date("Sundai 15 MA", "%W %d %b %Y"); +str_to_date("Sundai 15 MA", "%W %d %b %Y") +NULL +select str_to_date("Tuesday 52 2001", "%W %V %X"); +str_to_date("Tuesday 52 2001", "%W %V %X") +NULL +select str_to_date("Sunday 01 2001", "%W %V %X"); +str_to_date("Sunday 01 2001", "%W %V %X") +NULL +select str_to_date("Tuesday 00 2002", "%W %U %Y"); +str_to_date("Tuesday 00 2002", "%W %U %Y") +2002-01-01 00:00:00 +select str_to_date("Thursday 53 1998", "%W %u %Y"); +str_to_date("Thursday 53 1998", "%W %u %Y") +1998-12-31 00:00:00 +select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S"); +str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S") +2001-01-15 00:00:00 +select str_to_date("15-01-20", "%d-%m-%Y"); +str_to_date("15-01-20", "%d-%m-%Y") +NULL +select str_to_date("15-2001-1", "%d-%Y-%c"); +str_to_date("15-2001-1", "%d-%Y-%c") +2001-01-15 00:00:00 +select get_format(DATE, 'USA') as a; +a +%m.%d.%Y +select get_format(TIME, 'internal') as a; +a +%H%i%s +select get_format(DATETIME, 'eur') as a; +a +%Y-%m-%d-%H.%i.%s diff --git a/mysql-test/t/date_formats-master.opt b/mysql-test/t/date_formats-master.opt new file mode 100644 index 00000000000..7977a601dd7 --- /dev/null +++ b/mysql-test/t/date_formats-master.opt @@ -0,0 +1 @@ +--date_format=%d.%m.%Y --time_format=%H.%i.%s --datetime_format=%Y/%d/%m-%H:%i:%s diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test new file mode 100644 index 00000000000..9551efaa648 --- /dev/null +++ b/mysql-test/t/date_formats.test @@ -0,0 +1,82 @@ +SHOW GLOBAL VARIABLES LIKE "%_format%"; +SHOW SESSION VARIABLES LIKE "%_format%"; + +SET date_format="%d.%m.%Y"; +select CAST("01.01.2001" as DATE) as a; +SET datetime_format="%d.%m.%Y %H.%i.%s"; +select CAST("01.01.2001 05.12.06" as DATETIME) as a; +SET time_format="%H.%i.%s"; +select CAST("05.12.06" as TIME) as a; + +SET datetime_format="%d.%m.%Y %h:%i:%s %p"; +select CAST("01.01.2001 05:12:06AM" as DATETIME) as a; +select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a; + +SET time_format="%h:%i:%s %p"; +select CAST("05:12:06 AM" as TIME) as a; +select CAST("05:12:06.1234PM" as TIME) as a; + +SET time_format="%h.%i.%s %p"; +SET date_format='%d.%m.%y'; +SET datetime_format="%d.%m.%y %h.%i.%s %p"; +select CAST("12-12-06" as DATE) as a; + +select adddate("01.01.97 11.59.59.000001 PM", 10); +select datediff("31.12.97 11.59:59.000001 PM","01.01.98"); +select weekofyear("31.11.97 11:59:59.000001 PM"); +select makedate(1997,1); +select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"); +select maketime(23,11,12); +select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"); + +SET time_format="%H%i%s"; +--error 1105 +SET time_format="%h%i%s"; +--error 1105 +SET date_format='%d.%m.%d'; +--error 1105 +SET datetime_format="%d.%m.%y %h.%i.%s"; + +SET GLOBAL date_format=default; +SHOW GLOBAL VARIABLES LIKE "date_format%"; +SET GLOBAL time_format=default; +SHOW GLOBAL VARIABLES LIKE "time_format%"; +SET GLOBAL datetime_format=default; +SHOW GLOBAL VARIABLES LIKE "datetime_format%"; + +SET date_format=default; +SHOW SESSION VARIABLES LIKE "date_format%"; +SET time_format=default; +SHOW SESSION VARIABLES LIKE "time_format%"; +SET datetime_format=default; +SHOW SESSION VARIABLES LIKE "datetime_format%"; + +SET time_format='%i:%s:%H'; +select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME); + +SET GLOBAL date_format='%Y-%m-%d'; +SET GLOBAL time_format='%H:%i:%s'; +SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s'; +SET date_format='%Y-%m-%d'; +SET time_format='%H:%i:%s'; +SET datetime_format='%Y-%m-%d %H:%i:%s'; + +select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S"); +select str_to_date("15 September 2001", "%d %M %Y"); +select str_to_date("15 Septembeb 2001", "%d %M %Y"); +select str_to_date("15 MAY 2001", "%d %b %Y"); +select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y"); +select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y"); +select str_to_date("Sundai 15 MA", "%W %d %b %Y"); +select str_to_date("Tuesday 52 2001", "%W %V %X"); +select str_to_date("Sunday 01 2001", "%W %V %X"); +select str_to_date("Tuesday 00 2002", "%W %U %Y"); +select str_to_date("Thursday 53 1998", "%W %u %Y"); +select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S"); +select str_to_date("15-01-20", "%d-%m-%Y"); +select str_to_date("15-2001-1", "%d-%Y-%c"); + +select get_format(DATE, 'USA') as a; +select get_format(TIME, 'internal') as a; +select get_format(DATETIME, 'eur') as a; + diff --git a/sql/field.cc b/sql/field.cc index 441dc1ddb60..2065ecc8696 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -279,7 +279,8 @@ bool Field::get_date(TIME *ltime,bool fuzzydate) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || - str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) + str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate,current_thd)<= + WRONG_TIMESTAMP_FULL) return 1; return 0; } @@ -289,7 +290,7 @@ bool Field::get_time(TIME *ltime) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || - str_to_time(res->ptr(),res->length(),ltime)) + str_to_time(res->ptr(),res->length(),ltime,current_thd)) return 1; return 0; } @@ -299,28 +300,29 @@ bool Field::get_time(TIME *ltime) void Field::store_time(TIME *ltime,timestamp_type type) { char buff[25]; + String tmp((char*) buff,sizeof(buff),&my_charset_bin); + DATETIME_FORMAT *tmp_format= 0; + bool is_time_only= 0; + switch (type) { case TIMESTAMP_NONE: + case WRONG_TIMESTAMP_FULL: store("",0,&my_charset_bin); // Probably an error - break; + return; case TIMESTAMP_DATE: - sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); - store(buff,10,&my_charset_bin); + tmp_format= &t_datetime_frm(current_thd, DATE_FORMAT_TYPE).datetime_format; break; case TIMESTAMP_FULL: - sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", - ltime->year,ltime->month,ltime->day, - ltime->hour,ltime->minute,ltime->second); - store(buff,19,&my_charset_bin); + tmp_format=&t_datetime_frm(current_thd,DATETIME_FORMAT_TYPE).datetime_format; break; case TIMESTAMP_TIME: - { - ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d", - ltime->hour,ltime->minute,ltime->second)); - store(buff,(uint) length, &my_charset_bin); + tmp_format= &t_datetime_frm(current_thd, TIME_FORMAT_TYPE).datetime_format; + is_time_only= 1; break; } - } + make_datetime(&tmp, ltime, is_time_only, 0, + tmp_format->format, tmp_format->format_length, 1); + store(tmp.ptr(),tmp.length(),&my_charset_bin); } @@ -2684,7 +2686,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { - long tmp=(long) str_to_timestamp(from,len); + long tmp=(long) str_to_timestamp(from,len,current_thd); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -3018,7 +3020,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) TIME ltime; long tmp; int error= 0; - if (str_to_time(from,len,<ime)) + if (str_to_time(from,len,<ime,current_thd)) { tmp=0L; error= 1; @@ -3127,19 +3129,25 @@ longlong Field_time::val_int(void) String *Field_time::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + TIME ltime; val_buffer->alloc(16); long tmp=(long) sint3korr(ptr); const char *sign=""; + ltime.neg= 0; if (tmp < 0) { tmp= -tmp; - sign= "-"; + ltime.neg= 1; } - long length= my_sprintf((char*) val_buffer->ptr(), - ((char*) val_buffer->ptr(),"%s%02d:%02d:%02d", - sign,(int) (tmp/10000), (int) (tmp/100 % 100), - (int) (tmp % 100))); - val_buffer->length(length); + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (current_thd, TIME_FORMAT_TYPE).datetime_format); + ltime.day= (uint) 0; + ltime.hour= (uint) (tmp/10000); + ltime.minute= (uint) (tmp/100 % 100); + ltime.second= (uint) (tmp % 100); + make_datetime(val_buffer, <ime, 0, 0, + tmp_format->format, + tmp_format->format_length, 1); return val_buffer; } @@ -3305,7 +3313,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) TIME l_time; uint32 tmp; int error= 0; - if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) + if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL) { tmp=0; error= 1; @@ -3415,6 +3423,7 @@ longlong Field_date::val_int(void) String *Field_date::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + TIME ltime; val_buffer->alloc(field_length); val_buffer->length(field_length); int32 tmp; @@ -3424,9 +3433,15 @@ String *Field_date::val_str(String *val_buffer, else #endif longget(tmp,ptr); - sprintf((char*) val_buffer->ptr(),"%04d-%02d-%02d", - (int) ((uint32) tmp/10000L % 10000), (int) ((uint32) tmp/100 % 100), - (int) ((uint32) tmp % 100)); + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (current_thd, DATE_FORMAT_TYPE).datetime_format); + ltime.neg= 0; + ltime.year= (int) ((uint32) tmp/10000L % 10000); + ltime.month= (int) ((uint32) tmp/100 % 100); + ltime.day= (int) ((uint32) tmp % 100); + make_datetime(val_buffer, <ime, 0, 0, + tmp_format->format, + tmp_format->format_length, 1); return val_buffer; } @@ -3485,7 +3500,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) TIME l_time; long tmp; int error= 0; - if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) + if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL) { tmp=0L; error= 1; @@ -3654,7 +3669,7 @@ void Field_newdate::sql_type(String &res) const int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { - longlong tmp=str_to_datetime(from,len,1); + longlong tmp=str_to_datetime(from,len,1,current_thd); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { diff --git a/sql/item.cc b/sql/item.cc index 0f799184559..32926e0f7d5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,7 +46,7 @@ Item::Item(): collation.set(default_charset(), DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; - THD *thd= current_thd; + thd= current_thd; next= thd->free_list; // Put in free list thd->free_list= this; /* @@ -69,7 +69,7 @@ Item::Item(): Used for duplicating lists in processing queries with temporary tables */ -Item::Item(THD *thd, Item &item): +Item::Item(THD *c_thd, Item &item): str_value(item.str_value), name(item.name), max_length(item.max_length), @@ -82,7 +82,8 @@ Item::Item(THD *thd, Item &item): fixed(item.fixed), collation(item.collation) { - next=thd->free_list; // Put in free list + next=c_thd->free_list; // Put in free list + thd= c_thd; thd->free_list= this; } @@ -174,7 +175,8 @@ bool Item::get_date(TIME *ltime,bool fuzzydate) char buff[40]; String tmp(buff,sizeof(buff), &my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) + str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate, thd) <= + WRONG_TIMESTAMP_FULL) { bzero((char*) ltime,sizeof(*ltime)); return 1; @@ -192,7 +194,7 @@ bool Item::get_time(TIME *ltime) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_time(res->ptr(),res->length(),ltime)) + str_to_time(res->ptr(),res->length(),ltime, thd)) { bzero((char*) ltime,sizeof(*ltime)); return 1; @@ -673,30 +675,28 @@ String *Item_param::query_val_str(String* str) } else { - char buff[25]; + DATETIME_FORMAT *tmp_format= 0; + bool is_time_only= 0; switch (ltime.time_type) { case TIMESTAMP_NONE: + case WRONG_TIMESTAMP_FULL: break; case TIMESTAMP_DATE: - sprintf(buff, "%04d-%02d-%02d", - ltime.year,ltime.month,ltime.day); - str->append(buff, 10); + tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; break; case TIMESTAMP_FULL: - sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d", - ltime.year,ltime.month,ltime.day, - ltime.hour,ltime.minute,ltime.second); - str->append(buff, 19); + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; break; case TIMESTAMP_TIME: { - sprintf(buff, "%02d:%02d:%02d", - ltime.hour,ltime.minute,ltime.second); - str->append(buff, 8); + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; + is_time_only= 1; break; - } + } } + make_datetime(str, <ime, is_time_only, 0, + tmp_format->format, tmp_format->format_length, 0); } str->append("'"); } diff --git a/sql/item.h b/sql/item.h index 147c350878e..e45847a91d7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -113,6 +113,14 @@ public: my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ DTCollation collation; + + + /* + thd is current_thd value. Like some other Item's fields it + will be a problem for using one Item in different threads + (as stored procedures may want to do in the future) + */ + THD *thd; // alloc & destruct is done as start of select using sql_alloc Item(); @@ -124,7 +132,7 @@ public: top AND/OR ctructure of WHERE clause to protect it of optimisation changes in prepared statements */ - Item(THD *thd, Item &item); + Item(THD *c_thd, Item &item); virtual ~Item() { name=0; } /*lint -e1509 */ void set_name(const char *str,uint length, CHARSET_INFO *cs); void init_make_field(Send_field *tmp_field,enum enum_field_types type); diff --git a/sql/item_create.cc b/sql/item_create.cc index b1173b9c7b8..fce59d68c1f 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -701,3 +701,8 @@ Item *create_func_maketime(Item* a,Item* b,Item* c) { return new Item_func_maketime(a, b, c); } + +Item *create_func_str_to_date(Item* a,Item* b) +{ + return new Item_func_str_to_date(a, b); +} diff --git a/sql/item_create.h b/sql/item_create.h index c75f4404bad..5d6cbe1d58f 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -149,3 +149,4 @@ Item *create_func_addtime(Item* a,Item* b); Item *create_func_subtime(Item* a,Item* b); Item *create_func_timediff(Item* a,Item* b); Item *create_func_maketime(Item* a,Item* b,Item* c); +Item *create_func_str_to_date(Item* a,Item* b); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 31ce2ad9cdc..4009256ee17 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -57,82 +57,544 @@ static String day_names[] = String("Sunday", &my_charset_latin1) }; -enum date_time_format_types -{ - TIME_ONLY= 0, TIME_MICROSECOND, - DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND -}; - -typedef struct date_time_format +uint check_names(String *arr,int item_count,const char *val_ptr, + const char *val_end, uint *val, bool check_part) { - const char* format_str; - uint length; -}; + for (int i= 0; i < item_count; i++) + { + String *tmp=&arr[i]; + if (!my_strnncoll(&my_charset_latin1, + (const uchar *) val_ptr, 3, + (const uchar *) tmp->ptr(), 3)) + { + if (check_part) + { + *val= i+1; + return 3; + } -static struct date_time_format date_time_formats[]= + int part_len= tmp->length() - 3; + int val_len= val_end - val_ptr - 3; + if (val_len < part_len) + return 0; + val_ptr+=3; + if (!my_strnncoll(&my_charset_latin1, + (const uchar *) val_ptr, part_len, + (const uchar *) tmp->ptr() + 3, part_len)) + { + *val= i+1; + return tmp->length(); + } + return 0; + } + } + return 0; +} + +uint check_val_is_digit(const char *ptr, uint val_len, uint digit_count) { - {"%s%02d:%02d:%02d", 10}, - {"%s%02d:%02d:%02d.%06d", 17}, - {"%04d-%02d-%02d", 10}, - {"%04d-%02d-%02d %02d:%02d:%02d", 19}, - {"%04d-%02d-%02d %02d:%02d:%02d.%06d", 26} -}; + uint i; + uint verify_count= (val_len < digit_count ? val_len : digit_count); + uint digit_found= 0; + for (i= 0; i < verify_count; i++) + { + if (!my_isdigit(&my_charset_latin1, *(ptr+i))) + break; + digit_found++; + } + return digit_found; +} /* - OPTIMIZATION TODO: - - Replace the switch with a function that should be called for each - date type. - - Remove sprintf and opencode the conversion, like we do in - Field_datetime. + Extract datetime value to TIME struct from string value + according to format string. */ - -String *make_datetime(String *str, TIME *ltime, - enum date_time_format_types format) +bool extract_datetime(const char *str_val, uint str_val_len, + const char *str_format, uint str_format_len, + TIME *l_time) { - char *buff; + char intbuff[15]; + int weekday= 0, yearday= 0, daypart= 0, len; + int val_len= 0; + int week_number= -1; + ulong length; CHARSET_INFO *cs= &my_charset_bin; - uint length= date_time_formats[format].length + 32; - const char* format_str= date_time_formats[format].format_str; + int err= 0; + bool usa_time= 0; + bool sunday_first= 0; + const char *rT_format= "%H:%i:%s"; + uint part_len= 0; + const char *val_ptr=str_val; + const char *val_end= str_val + str_val_len; + const char *ptr=str_format; + const char *end=ptr+ str_format_len; - if (str->alloc(length)) - return 0; - - buff= (char*) str->ptr(); - switch (format) { - case TIME_ONLY: - length= cs->cset->snprintf(cs, buff, length, format_str, ltime->neg ? "-" : "", - ltime->hour, ltime->minute, ltime->second); - break; - case TIME_MICROSECOND: - length= cs->cset->snprintf(cs, buff, length, format_str, ltime->neg ? "-" : "", - ltime->hour, ltime->minute, ltime->second, - ltime->second_part); - break; - case DATE_ONLY: - length= cs->cset->snprintf(cs, buff, length, format_str, - ltime->year, ltime->month, ltime->day); - break; - case DATE_TIME: - length= cs->cset->snprintf(cs, buff, length, format_str, - ltime->year, ltime->month, ltime->day, - ltime->hour, ltime->minute, ltime->second); - break; - case DATE_TIME_MICROSECOND: - length= cs->cset->snprintf(cs, buff, length, format_str, - ltime->year, ltime->month, ltime->day, - ltime->hour, ltime->minute, ltime->second, - ltime->second_part); - break; - default: - return 0; + DBUG_ENTER("extract_datetime"); + for (; ptr != end && val_ptr != val_end; ptr++) + { + if (*ptr == '%' && ptr+1 != end) + { + val_len= val_end - val_ptr; + char *val_end1= (char *) val_end; + switch (*++ptr) { + case 'h': + case 'I': + case 'H': + l_time->hour= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + usa_time= (*ptr == 'I' || *ptr == 'h'); + val_ptr+=2; + break; + case 'k': + case 'l': + l_time->hour= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err) + return 1; + usa_time= (*ptr == 'l'); + val_ptr= val_end1; + break; + case 'e': + l_time->day= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err) + return 1; + val_ptr= val_end1; + break; + case 'c': + l_time->month= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err) + return 1; + val_ptr= val_end1; + break; + case 'Y': + l_time->year= my_strntoll(cs, val_ptr, + 4, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 4)) + return 1; + val_ptr+=4; + break; + case 'y': + l_time->year= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); + val_ptr+=2; + break; + case 'm': + l_time->month= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + val_ptr+=2; + break; + case 'd': + l_time->day= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + val_ptr+=2; + break; + case 'D': + l_time->day= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_len < val_end1 - val_ptr + 2)) + return 1; + val_ptr= val_end1 + 2; + break; + case 'i': + l_time->minute=my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + val_ptr+=2; + break; + case 's': + case 'S': + l_time->second= my_strntoll(cs, val_ptr, + 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + val_ptr+=2; + break; + case 'M': + if (val_len < 3 || + !(part_len= check_names(month_names, 12 , val_ptr, + val_end, &l_time->month, 0))) + return 1; + val_ptr+= part_len; + break; + case 'b': + if (val_len < 3 || + !(part_len= check_names(month_names, 12 , val_ptr, + val_end,(uint *) &l_time->month, 1))) + return 1; + val_ptr+= part_len; + break; + case 'W': + if (val_len < 3 || + !(part_len= check_names(day_names, 7 , val_ptr, + val_end,(uint *) &weekday, 0))) + return 1; + val_ptr+= part_len; + break; + case 'a': + if (val_len < 3 || + !(part_len= check_names(day_names, 7 , val_ptr, + val_end,(uint *) &weekday, 1))) + return 1; + val_ptr+= part_len; + break; + case 'w': + weekday= my_strntoll(cs, val_ptr, 1, 10, &val_end1, &err); + if (err) + return 1; + val_ptr++; + break; + case 'j': + yearday= my_strntoll(cs, val_ptr, 3, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 3)) + return 1; + val_ptr+=3; + break; + case 'f': + l_time->second_part= my_strntoll(cs, val_ptr, 3, 10, &val_end1, &err); + if (err) + return 1; + val_ptr= val_end1; + break; + case 'p': + if (val_len < 2) + return 1; + if (!my_strnncoll(&my_charset_latin1, + (const uchar *) val_ptr, 2, + (const uchar *) "PM", 2)) + { + daypart= 12; + val_ptr+= 2; + } + break; + case 'U': + week_number= my_strntoll(cs, val_ptr, 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + sunday_first= 1; + val_ptr+=2; + break; + case 'u': + week_number= my_strntoll(cs, val_ptr, 2, 10, &val_end1, &err); + if (err || (val_end1 - val_ptr != 2)) + return 1; + sunday_first=0; + val_ptr+=2; + break; + case 'r': + case 'T': + usa_time= (*ptr == 'r'); + if (extract_datetime(val_ptr, val_end-val_ptr, + rT_format, strlen(rT_format), + l_time)) + return 1; + val_ptr+=8; + break; + default: + if (*val_ptr != *ptr) + return 1; + val_ptr++; + } + } + else + { + if (*val_ptr != *ptr) + return 1; + val_ptr++; + } + } + if (usa_time) + { + if (l_time->hour > 12 || l_time->hour < 1) + return 1; + l_time->hour= l_time->hour%12+daypart; } - str->length(length); - str->set_charset(cs); + if (yearday > 0) + { + uint days= calc_daynr(l_time->year,1,1) + yearday - 1; + if (days > 0 || days < MAX_DAY_NUMBER) + { + get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); + } + } + + if (week_number >= 0 && weekday) + { + int days= calc_daynr(l_time->year,1,1); + uint weekday_b; + + if (weekday > 7 || weekday < 0) + return 1; + if (sunday_first) + weekday = weekday%7; + + if (week_number == 53) + { + days+= (week_number - 1)*7; + weekday_b= calc_weekday(days, sunday_first); + weekday = weekday - weekday_b - !sunday_first; + days+= weekday; + } + else if (week_number == 0) + { + weekday_b= calc_weekday(days, sunday_first); + weekday = weekday - weekday_b - !sunday_first; + days+= weekday; + } + else + { + days+= (week_number - !sunday_first)*7; + weekday_b= calc_weekday(days, sunday_first); + weekday =weekday - weekday_b - !sunday_first; + days+= weekday; + } + if (days > 0 || days < MAX_DAY_NUMBER) + { + get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); + } + } + + if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || + l_time->minute > 59 || l_time->second > 59) + return 1; + + DBUG_RETURN(0); +} + + + +/* + Print datetime string from TIME struct + according to format string. +*/ + + +String *make_datetime(String *str, TIME *l_time, + const bool is_time_only, + const bool add_second_frac, + const char *ptr, uint format_length, + bool set_len_to_zero) +{ + char intbuff[15]; + uint days_i; + uint hours_i; + uint weekday; + ulong length; + if (set_len_to_zero) + str->length(0); + if (l_time->neg) + str->append("-", 1); + const char *end=ptr+format_length; + for (; ptr != end ; ptr++) + { + if (*ptr != '%' || ptr+1 == end) + str->append(*ptr); + else + { + switch (*++ptr) { + case 'M': + if (!l_time->month) + return 0; + str->append(month_names[l_time->month-1]); + break; + case 'b': + if (!l_time->month) + return 0; + str->append(month_names[l_time->month-1].ptr(),3); + break; + case 'W': + if (is_time_only) + return 0; + weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),0); + str->append(day_names[weekday]); + break; + case 'a': + if (is_time_only) + return 0; + weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),0); + str->append(day_names[weekday].ptr(),3); + break; + case 'D': + if (is_time_only) + return 0; + length= int10_to_str(l_time->day, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 1, '0'); + if (l_time->day >= 10 && l_time->day <= 19) + str->append("th"); + else + { + switch (l_time->day %10) { + case 1: + str->append("st",2); + break; + case 2: + str->append("nd",2); + break; + case 3: + str->append("rd",2); + break; + default: + str->append("th",2); + break; + } + } + break; + case 'Y': + length= int10_to_str(l_time->year, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 4, '0'); + break; + case 'y': + length= int10_to_str(l_time->year%100, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'm': + length= int10_to_str(l_time->month, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'c': + length= int10_to_str(l_time->month, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 1, '0'); + break; + case 'd': + length= int10_to_str(l_time->day, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'e': + length= int10_to_str(l_time->day, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 1, '0'); + break; + case 'f': + length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 6, '0'); + break; + case 'H': + length= int10_to_str(l_time->hour, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'h': + case 'I': + days_i= l_time->hour/24; + hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i; + length= int10_to_str(hours_i, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'i': /* minutes */ + length= int10_to_str(l_time->minute, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + break; + case 'j': + if (is_time_only) + return 0; + length= int10_to_str(calc_daynr(l_time->year,l_time->month,l_time->day) - + calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 3, '0'); + break; + case 'k': + length= int10_to_str(l_time->hour, intbuff, 10) - intbuff; + 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; + length= int10_to_str(hours_i, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 1, '0'); + break; + case 'p': + hours_i= l_time->hour%24; + str->append(hours_i < 12 ? "AM" : "PM",2); + break; + case 'r': + length= my_sprintf(intbuff, + (intbuff, + (l_time->hour < 12) ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", + (l_time->hour+11)%12+1, + l_time->minute, + l_time->second)); + str->append(intbuff, length); + break; + case 'S': + case 's': + length= int10_to_str(l_time->second, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + if (add_second_frac) + { + str->append(".", 1); + length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 6, '0'); + } + break; + case 'T': + length= my_sprintf(intbuff, + (intbuff, + "%02d:%02d:%02d", + l_time->hour, + l_time->minute, + l_time->second)); + str->append(intbuff, length); + break; + case 'U': + case 'u': + { + uint year; + if (is_time_only) + return 0; + length= int10_to_str(calc_week(l_time, 0, (*ptr) == 'U', &year), + intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + } + break; + case 'v': + case 'V': + { + uint year; + if (is_time_only) + return 0; + length= int10_to_str(calc_week(l_time, 1, (*ptr) == 'V', &year), + intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 2, '0'); + } + break; + case 'x': + case 'X': + { + uint year; + if (is_time_only) + return 0; + (void) calc_week(l_time, 1, (*ptr) == 'X', &year); + length= int10_to_str(year, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 4, '0'); + } + break; + case 'w': + if (is_time_only) + return 0; + weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,l_time->day),1); + length= int10_to_str(weekday, intbuff, 10) - intbuff; + str->append_with_prefill(intbuff, length, 1, '0'); + break; + default: + str->append(*ptr); + break; + } + } + } return str; } + /* ** Get a array of positive numbers from a string object. ** Each number is separated by 1 non digit character @@ -346,7 +808,7 @@ longlong Item_func_year::val_int() longlong Item_func_unix_timestamp::val_int() { if (arg_count == 0) - return (longlong) current_thd->query_start(); + return (longlong) thd->query_start(); if (args[0]->type() == FIELD_ITEM) { // Optimize timestamp field Field *field=((Item_field*) args[0])->field; @@ -358,7 +820,7 @@ longlong Item_func_unix_timestamp::val_int() { return 0; /* purecov: inspected */ } - return (longlong) str_to_timestamp(str->ptr(),str->length()); + return (longlong) str_to_timestamp(str->ptr(),str->length(), thd); } @@ -522,22 +984,26 @@ static bool get_interval_value(Item *args,interval_type int_type, String *Item_date::val_str(String *str) { + DATETIME_FORMAT *tmp_format; + TIME ltime; ulong value=(ulong) val_int(); if (null_value) - return (String*) 0; - if (!value) // zero daynr - { - str->copy("0000-00-00",10,&my_charset_latin1,default_charset()); + goto null_date; + + ltime.year= (value/10000L) % 10000; + ltime.month= (value/100)%100; + ltime.day= (value%100); + ltime.neg=0; + ltime.time_type=TIMESTAMP_DATE; + + tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; + if (make_datetime(str, <ime, 0, 0, + tmp_format->format, tmp_format->format_length, 1)) return str; - } - - char tmpbuff[11]; - sprintf(tmpbuff,"%04d-%02d-%02d", - (int) (value/10000L) % 10000, - (int) (value/100)%100, - (int) (value%100)); - str->copy(tmpbuff,10,&my_charset_latin1,default_charset()); - return str; + + null_value= 1; +null_date: + return 0; } @@ -577,7 +1043,7 @@ void Item_func_curdate::fix_length_and_dec() decimals=0; max_length=10*default_charset()->mbmaxlen; - store_now_in_tm(current_thd->query_start(),&start); + store_now_in_tm(thd->query_start(),&start); value=(longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+ ((uint) start.tm_mon+1)*100+ @@ -632,22 +1098,27 @@ String *Item_func_curtime::val_str(String *str) void Item_func_curtime::fix_length_and_dec() { struct tm start; - CHARSET_INFO *cs= default_charset(); + DATETIME_FORMAT *tmp_format; + String tmp((char*) buff,sizeof(buff),default_charset()); + TIME ltime; decimals=0; - max_length=8*cs->mbmaxlen; - collation.set(cs); - - store_now_in_tm(current_thd->query_start(),&start); - + store_now_in_tm(thd->query_start(),&start); value=(longlong) ((ulong) ((uint) start.tm_hour)*10000L+ (ulong) (((uint) start.tm_min)*100L+ (uint) start.tm_sec)); - - buff_length=cs->cset->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d", - (int) start.tm_hour, - (int) start.tm_min, - (int) start.tm_sec); + ltime.day= 0; + ltime.hour= start.tm_hour; + ltime.minute= start.tm_min; + ltime.second= start.tm_sec; + ltime.second_part= 0; + ltime.neg= 0; + ltime.time_type= TIMESTAMP_TIME; + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; + make_datetime(&tmp, <ime, 0, 0, + tmp_format->format, tmp_format->format_length, 1); + buff_length= tmp.length(); + max_length= buff_length; } @@ -681,14 +1152,11 @@ String *Item_func_now::val_str(String *str) void Item_func_now::fix_length_and_dec() { struct tm start; - CHARSET_INFO *cs= &my_charset_bin; + DATETIME_FORMAT *tmp_format; + String tmp((char*) buff,sizeof(buff),&my_charset_bin); decimals=0; - max_length=19*cs->mbmaxlen; - collation.set(cs); - - store_now_in_tm(current_thd->query_start(),&start); - + store_now_in_tm(thd->query_start(),&start); value=((longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+ (((uint) start.tm_mon+1)*100+ (uint) start.tm_mday))*(longlong) 1000000L+ @@ -696,14 +1164,6 @@ void Item_func_now::fix_length_and_dec() (ulong) (((uint) start.tm_min)*100L+ (uint) start.tm_sec))); - buff_length= (uint) cs->cset->snprintf(cs,buff, sizeof(buff), - "%04d-%02d-%02d %02d:%02d:%02d", - ((int) (start.tm_year+1900)) % 10000, - (int) start.tm_mon+1, - (int) start.tm_mday, - (int) start.tm_hour, - (int) start.tm_min, - (int) start.tm_sec); /* For getdate */ ltime.year= start.tm_year+1900; ltime.month= start.tm_mon+1; @@ -711,9 +1171,15 @@ void Item_func_now::fix_length_and_dec() ltime.hour= start.tm_hour; ltime.minute= start.tm_min; ltime.second= start.tm_sec; - ltime.second_part=0; - ltime.neg=0; - ltime.time_type=TIMESTAMP_FULL; + ltime.second_part= 0; + ltime.neg= 0; + ltime.time_type= TIMESTAMP_FULL; + + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; + make_datetime(&tmp, <ime, 0, 0, + tmp_format->format, tmp_format->format_length, 1); + buff_length= tmp.length(); + max_length= buff_length; } bool Item_func_now::get_date(TIME *res, @@ -754,22 +1220,36 @@ void Item_func_now_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_sec_to_time::val_str(String *str) { - char buff[23*2]; - const char *sign=""; longlong seconds=(longlong) args[0]->val_int(); - ulong length; + uint sec; + + DATETIME_FORMAT *tmp_format; + TIME ltime; + if ((null_value=args[0]->null_value)) - return (String*) 0; + goto null_date; + + ltime.neg= 0; if (seconds < 0) { seconds= -seconds; - sign= "-"; + ltime.neg= 1; } - uint sec= (uint) ((ulonglong) seconds % 3600); - length= my_sprintf(buff,(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600), - sec/60, sec % 60)); - str->copy(buff, length, &my_charset_latin1, default_charset()); - return str; + + sec= (uint) ((ulonglong) seconds % 3600); + ltime.day= 0; + ltime.hour= seconds/3600; + ltime.minute= sec/60; + ltime.second= sec % 60; + + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; + if (make_datetime(str, <ime, 0, 0, + tmp_format->format, tmp_format->format_length, 1)) + return str; + + null_value= 1; +null_date: + return (String*) 0; } @@ -879,9 +1359,7 @@ String *Item_func_date_format::val_str(String *str) { String *format; TIME l_time; - char intbuff[15]; uint size,weekday; - ulong length; if (!date_or_time) { @@ -892,24 +1370,17 @@ String *Item_func_date_format::val_str(String *str) { String *res; if (!(res=args[0]->val_str(str))) - { - null_value=1; - return 0; - } - if (str_to_time(res->ptr(),res->length(),&l_time)) - { - null_value=1; - return 0; - } + goto null_date; + + if (str_to_time(res->ptr(),res->length(),&l_time, thd)) + goto null_date; + l_time.year=l_time.month=l_time.day=0; null_value=0; } if (!(format = args[1]->val_str(str)) || !format->length()) - { - null_value=1; - return 0; - } + goto null_date; if (fixed_length) size=max_length; @@ -918,237 +1389,53 @@ String *Item_func_date_format::val_str(String *str) if (format == str) str= &value; // Save result here if (str->alloc(size)) - { - null_value=1; - return 0; - } - str->length(0); + goto null_date; + /* Create the result string */ - const char *ptr=format->ptr(); - const char *end=ptr+format->length(); - for (; ptr != end ; ptr++) - { - if (*ptr != '%' || ptr+1 == end) - str->append(*ptr); - else - { - switch (*++ptr) { - case 'M': - if (!l_time.month) - { - null_value=1; - return 0; - } - str->append(month_names[l_time.month-1]); - break; - case 'b': - if (!l_time.month) - { - null_value=1; - return 0; - } - str->append(month_names[l_time.month-1].ptr(),3); - break; - case 'W': - if (date_or_time) - { - null_value=1; - return 0; - } - weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0); - str->append(day_names[weekday]); - break; - case 'a': - if (date_or_time) - { - null_value=1; - return 0; - } - weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0); - str->append(day_names[weekday].ptr(),3); - break; - case 'D': - if (date_or_time) - { - null_value=1; - return 0; - } - length= int10_to_str(l_time.day, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); - if (l_time.day >= 10 && l_time.day <= 19) - str->append("th"); - else - { - switch (l_time.day %10) { - case 1: - str->append("st",2); - break; - case 2: - str->append("nd",2); - break; - case 3: - str->append("rd",2); - break; - default: - str->append("th",2); - break; - } - } - break; - case 'Y': - length= int10_to_str(l_time.year, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 4, '0'); - break; - case 'y': - length= int10_to_str(l_time.year%100, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'm': - length= int10_to_str(l_time.month, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'c': - length= int10_to_str(l_time.month, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); - break; - case 'd': - length= int10_to_str(l_time.day, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'e': - length= int10_to_str(l_time.day, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); - break; - case 'f': - length= int10_to_str(l_time.second_part, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 6, '0'); - break; - case 'H': - length= int10_to_str(l_time.hour, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'h': - case 'I': - length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'i': /* minutes */ - length= int10_to_str(l_time.minute, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'j': - if (date_or_time) - { - null_value=1; - return 0; - } - length= int10_to_str(calc_daynr(l_time.year,l_time.month,l_time.day) - - calc_daynr(l_time.year,1,1) + 1, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 3, '0'); - break; - case 'k': - length= int10_to_str(l_time.hour, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); - break; - case 'l': - length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); - break; - case 'p': - str->append(l_time.hour < 12 ? "AM" : "PM",2); - break; - case 'r': - length= my_sprintf(intbuff, - (intbuff, - (l_time.hour < 12) ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", - (l_time.hour+11)%12+1, - l_time.minute, - l_time.second)); - str->append(intbuff, length); - break; - case 'S': - case 's': - length= int10_to_str(l_time.second, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - break; - case 'T': - length= my_sprintf(intbuff, - (intbuff, - "%02d:%02d:%02d", - l_time.hour, - l_time.minute, - l_time.second)); - str->append(intbuff, length); - break; - case 'U': - case 'u': - { - uint year; - length= int10_to_str(calc_week(&l_time, 0, (*ptr) == 'U', &year), - intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - } - break; - case 'v': - case 'V': - { - uint year; - length= int10_to_str(calc_week(&l_time, 1, (*ptr) == 'V', &year), - intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 2, '0'); - } - break; - case 'x': - case 'X': - { - uint year; - (void) calc_week(&l_time, 1, (*ptr) == 'X', &year); - length= int10_to_str(year, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 4, '0'); - } - break; - case 'w': - weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1); - length= int10_to_str(weekday, intbuff, 10) - intbuff; - str->append_with_prefill(intbuff, length, 1, '0'); + if (make_datetime(str, &l_time, 0, 0, + format->ptr(), format->length(), 1)) + return str; - break; - default: - str->append(*ptr); - break; - } - } - } - return str; +null_date: + null_value=1; + return 0; } String *Item_func_from_unixtime::val_str(String *str) { struct tm tm_tmp,*start; + DATETIME_FORMAT *tmp_format; time_t tmp=(time_t) args[0]->val_int(); uint32 l; CHARSET_INFO *cs=default_charset(); + TIME ltime; if ((null_value=args[0]->null_value)) - return 0; + goto null_date; + localtime_r(&tmp,&tm_tmp); start=&tm_tmp; - + + ltime.year= start->tm_year+1900; + ltime.month= start->tm_mon+1; + ltime.day= start->tm_mday; + ltime.hour= start->tm_hour; + ltime.minute= start->tm_min; + ltime.second= start->tm_sec; + ltime.second_part= 0; + ltime.neg=0; + l=20*cs->mbmaxlen+32; - if (str->alloc(l)) - return str; /* purecov: inspected */ - l=cs->cset->snprintf(cs,(char*) str->ptr(),l,"%04d-%02d-%02d %02d:%02d:%02d", - (int) start->tm_year+1900, - (int) start->tm_mon+1, - (int) start->tm_mday, - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); - str->length(l); - str->set_charset(cs); - return str; + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; + if (str->alloc(l) && make_datetime(str, <ime, 1, 0, + tmp_format->format, + tmp_format->format_length, 1)) + return str; + null_value= 1; +null_date: + return 0; } @@ -1229,7 +1516,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) { long period,sign; INTERVAL interval; - + ltime->neg= 0; if (args[0]->get_date(ltime,0) || get_interval_value(args[1],int_type,&value,&interval)) goto null_date; @@ -1329,19 +1616,17 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) String *Item_date_add_interval::val_str(String *str) { TIME ltime; - enum date_time_format_types format; + DATETIME_FORMAT *tmp_format; if (Item_date_add_interval::get_date(<ime,0)) return 0; if (ltime.time_type == TIMESTAMP_DATE) - format= DATE_ONLY; - else if (ltime.second_part) - format= DATE_TIME_MICROSECOND; - else - format= DATE_TIME; - - if (make_datetime(str, <ime, format)) + tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format; + else + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; + if (make_datetime(str, <ime, 1, ltime.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; null_value=1; @@ -1400,7 +1685,7 @@ longlong Item_extract::val_int() else { String *res= args[0]->val_str(&value); - if (!res || str_to_time(res->ptr(),res->length(),<ime)) + if (!res || str_to_time(res->ptr(),res->length(),<ime, thd)) { null_value=1; return 0; @@ -1408,7 +1693,6 @@ longlong Item_extract::val_int() neg= ltime.neg ? -1 : 1; null_value=0; } - switch (int_type) { case INTERVAL_YEAR: return ltime.year; case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month; @@ -1530,10 +1814,12 @@ void Item_char_typecast::fix_length_and_dec() String *Item_datetime_typecast::val_str(String *str) { TIME ltime; + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (thd, DATETIME_FORMAT_TYPE).datetime_format); if (!get_arg0_date(<ime,1) && - make_datetime(str, <ime, ltime.second_part ? - DATE_TIME_MICROSECOND : DATE_TIME)) + make_datetime(str, <ime, 1, ltime.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; null_date: @@ -1553,9 +1839,12 @@ bool Item_time_typecast::get_time(TIME *ltime) String *Item_time_typecast::val_str(String *str) { TIME ltime; + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (thd, TIME_FORMAT_TYPE).datetime_format); if (!get_arg0_time(<ime) && - make_datetime(str, <ime, ltime.second_part ? TIME_MICROSECOND : TIME_ONLY)) + make_datetime(str, <ime, 0, ltime.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; null_value=1; @@ -1574,9 +1863,12 @@ bool Item_date_typecast::get_date(TIME *ltime, bool fuzzy_date) String *Item_date_typecast::val_str(String *str) { TIME ltime; + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (thd, DATE_FORMAT_TYPE).datetime_format); if (!get_arg0_date(<ime,1) && - make_datetime(str, <ime, DATE_ONLY)) + make_datetime(str, <ime, 1, 0, + tmp_format->format, tmp_format->format_length, 1)) return str; null_date: @@ -1605,7 +1897,11 @@ String *Item_func_makedate::val_str(String *str) { null_value=0; get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day); - if (make_datetime(str, &l_time, DATE_ONLY)) + + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (thd, DATE_FORMAT_TYPE).datetime_format); + if (make_datetime(str, &l_time, 1, 0, + tmp_format->format, tmp_format->format_length, 1)) return str; } @@ -1656,6 +1952,7 @@ String *Item_func_add_time::val_str(String *str) bool is_time= 0; long microseconds, seconds, days= 0; int l_sign= sign; + DATETIME_FORMAT *tmp_format; null_value=0; l_time3.neg= 0; @@ -1720,19 +2017,21 @@ String *Item_func_add_time::val_str(String *str) calc_time_from_sec(&l_time3, seconds, microseconds); if (!is_time) { + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); if (l_time3.day && - make_datetime(str, &l_time3, - l_time1.second_part || l_time2.second_part ? - DATE_TIME_MICROSECOND : DATE_TIME)) + make_datetime(str, &l_time3, 1, + l_time1.second_part || l_time2.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; goto null_date; } - + + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; l_time3.hour+= days*24; - if (make_datetime(str, &l_time3, - l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY)) + if (make_datetime(str, &l_time3, 0, + l_time1.second_part || l_time2.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; null_date: @@ -1755,6 +2054,7 @@ String *Item_func_timediff::val_str(String *str) long days; int l_sign= 1; TIME l_time1 ,l_time2, l_time3; + DATETIME_FORMAT *tmp_format; null_value= 0; if (args[0]->get_time(&l_time1) || @@ -1800,9 +2100,11 @@ String *Item_func_timediff::val_str(String *str) l_time3.neg= l_time3.neg ? 0 : 1; calc_time_from_sec(&l_time3, seconds, microseconds); - if (make_datetime(str, &l_time3, - l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY)) + + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; + if (make_datetime(str, &l_time3, 0, + l_time1.second_part || l_time2.second_part, + tmp_format->format, tmp_format->format_length, 1)) return str; null_date: @@ -1819,6 +2121,7 @@ null_date: String *Item_func_maketime::val_str(String *str) { TIME ltime; + DATETIME_FORMAT *tmp_format; long hour= args[0]->val_int(); long minute= args[1]->val_int(); @@ -1840,7 +2143,9 @@ String *Item_func_maketime::val_str(String *str) ltime.hour= (ulong)hour; ltime.minute= (ulong)minute; ltime.second= (ulong)second; - if (make_datetime(str, <ime, TIME_ONLY)) + tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format; + if (make_datetime(str, <ime, 0, 0, + tmp_format->format, tmp_format->format_length, 1)) return str; null_date: @@ -1860,3 +2165,79 @@ longlong Item_func_microsecond::val_int() return ltime.second_part; return 0; } + +/* + Array of MySQL date/time/datetime formats + Firts element is date format + Second element is time format + Third element is datetime format + Fourth is format name. +*/ + +const char *datetime_formats[4][5]= +{ + {"%m.%d.%Y", "%Y-%m-%d", "%Y-%m-%d", "%d.%m.%Y", "%Y%m%d"}, + {"%h:%i:%s %p", "%H:%i:%s", "%H:%i:%s", "%H.%i.%S", "%H%i%s"}, + {"%Y-%m-%d-%H.%i.%s", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d %H:%i:%s", "%Y-%m-%d-%H.%i.%s", "%Y%m%d%H%i%s"}, + {"USA", "JIS", "ISO", "EUR", "INTERNAL"} +}; + + +/* + Return format string according format name. + If name is unknown, result is ISO format string +*/ + +String *Item_func_get_format::val_str(String *str) +{ + String *val=args[0]->val_str(str); + const char *format_str= datetime_formats[tm_format][ISO_FORMAT]; + + if (!args[0]->null_value) + { + const char *val_ptr= val->ptr(); + uint val_len= val->length(); + for (int i= 0; i < 5; i++) + { + const char *name_format_str= datetime_formats[3][i]; + uint format_str_len= strlen(name_format_str); + if ( val_len == format_str_len && + !my_strnncoll(&my_charset_latin1, + (const uchar *) val_ptr, val_len, + (const uchar *) name_format_str, format_str_len)) + { + format_str= datetime_formats[tm_format][i]; + break; + } + } + } + + null_value= 0; + str->length(0); + str->append(format_str); + return str; +} + + +String *Item_func_str_to_date::val_str(String *str) +{ + TIME ltime; + bzero((char*) <ime, sizeof(ltime)); + DATETIME_FORMAT *tmp_format; + String *val=args[0]->val_str(str); + String *format=args[1]->val_str(str); + if (args[0]->null_value || args[1]->null_value || + extract_datetime(val->ptr(), val->length(), + format->ptr(), val->length(), + <ime)) + goto null_date; + + tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format; + if (make_datetime(str, <ime, 0, 0, tmp_format->format, + tmp_format->format_length, 1)) + return str; + +null_date: + null_value=1; + return 0; +} diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 6dcf7d00ce1..b7bf294b83d 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -763,3 +763,46 @@ public: maybe_null=1; } }; + + +enum datetime_format +{ + USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT +}; + + +enum datetime_format_types +{ + DATE_FORMAT_TYPE= 0, TIME_FORMAT_TYPE, DATETIME_FORMAT_TYPE +}; + + +class Item_func_get_format :public Item_str_func +{ + const datetime_format_types tm_format; +public: + Item_func_get_format(datetime_format_types type_arg1, Item *a) + :Item_str_func(a), tm_format(type_arg1) {} + String *val_str(String *str); + const char *func_name() const { return "get_format"; } + void fix_length_and_dec() + { + decimals=0; + max_length=17*MY_CHARSET_BIN_MB_MAXLEN; + } +}; + + +class Item_func_str_to_date :public Item_str_func +{ +public: + Item_func_str_to_date(Item *a, Item *b) + :Item_str_func(a, b) {} + String *val_str(String *str); + const char *func_name() const { return "str_to_date"; } + void fix_length_and_dec() + { + decimals=0; + max_length=29*MY_CHARSET_BIN_MB_MAXLEN; + } +}; diff --git a/sql/lex.h b/sql/lex.h index aa6d96d4029..6a7ce37ba08 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -176,6 +176,7 @@ static SYMBOL symbols[] = { { "FUNCTION", SYM(UDF_SYM),0,0}, { "GEOMETRY", SYM(GEOMETRY_SYM),0,0}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0}, + { "GET_FORMAT", SYM(GET_FORMAT),0,0}, { "GLOBAL", SYM(GLOBAL_SYM),0,0}, { "GRANT", SYM(GRANT),0,0}, { "GRANTS", SYM(GRANTS),0,0}, @@ -634,6 +635,7 @@ static SYMBOL sql_functions[] = { { "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)}, { "STD", SYM(STD_SYM),0,0}, { "STDDEV", SYM(STD_SYM),0,0}, + { "STR_TO_DATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)}, { "STRCMP", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, { "SUBSTR", SYM(SUBSTRING),0,0}, { "SUBSTRING", SYM(SUBSTRING),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c8583c12470..b152c71cca6 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -783,7 +783,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_system_variables; -extern rw_lock_t LOCK_grant; +extern rw_lock_t LOCK_grant; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; extern I_List threads; @@ -800,6 +800,13 @@ extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct rand_struct sql_rand; +#define g_datetime_frm(a) (global_system_variables.datetime_formats[(a)]) +#define t_datetime_frm(a, b) ((a)->variables.datetime_formats[(b)]) + +extern const char *datetime_formats[4][5]; +extern const char *opt_datetime_format_names[3]; +extern const char *opt_datetime_formats[3]; + /* optional things, have_* variables */ extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; @@ -863,14 +870,24 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); void init_time(void); long my_gmt_sec(TIME *, long *current_timezone); -time_t str_to_timestamp(const char *str,uint length); -bool str_to_time(const char *str,uint length,TIME *l_time); -longlong str_to_datetime(const char *str,uint length,bool fuzzy_date); +time_t str_to_timestamp(const char *str,uint length, THD *thd); +bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd); +longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd); timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time, - bool fuzzy_date); + bool fuzzy_date, THD *thd); void localtime_to_TIME(TIME *to, struct tm *from); void calc_time_from_sec(TIME *to, long seconds, long microseconds); +extern DATETIME_FORMAT *make_format(DATETIME_FORMAT *datetime_format, + datetime_format_types format_type, + const char *format_str, + uint format_length, bool is_alloc); +extern String *make_datetime(String *str, TIME *l_time, + const bool is_time_only, + const bool add_second_frac, + const char *ptr, uint format_length, + bool set_len_to_zero); + int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); extern "C" void unireg_abort(int exit_code); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 80096e5d5e6..33938290c1b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -310,6 +310,12 @@ char* log_error_file_ptr= log_error_file; char mysql_real_data_home[FN_REFLEN], language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; + +const char *opt_datetime_formats[3]; +const char *opt_datetime_format_names[3]= {"date_format", + "time_format", + "datetime_format"}; + char *language_ptr, *default_collation_name, *default_character_set_name; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; @@ -893,6 +899,9 @@ void clean_up(bool print_message) #ifdef USE_RAID end_raid(); #endif + g_datetime_frm(DATE_FORMAT_TYPE).clean(); + g_datetime_frm(TIME_FORMAT_TYPE).clean(); + g_datetime_frm(DATETIME_FORMAT_TYPE).clean(); if (defaults_argv) free_defaults(defaults_argv); free_tmpdir(&mysql_tmpdir_list); @@ -1976,6 +1985,36 @@ bool open_log(MYSQL_LOG *log, const char *hostname, } +int init_global_datetime_format(datetime_format_types format_type, bool is_alloc) +{ + const char *format_str= opt_datetime_formats[format_type]; + uint format_length= 0; + DATETIME_FORMAT *tmp_format= &g_datetime_frm(format_type).datetime_format; + + if (format_str) + { + format_str= opt_datetime_formats[format_type]; + format_length= strlen(format_str); + } + else + { + format_str= datetime_formats[format_type][ISO_FORMAT]; + format_length= strlen(datetime_formats[format_type][ISO_FORMAT]); + opt_datetime_formats[format_type]= format_str; + } + if (make_format(tmp_format, format_type, format_str, + format_length, is_alloc)) + { + g_datetime_frm(format_type).name= opt_datetime_format_names[format_type]; + g_datetime_frm(format_type).name_length= + strlen(opt_datetime_format_names[format_type]); + g_datetime_frm(format_type).format_type= format_type; + return 0; + } + return 1; +} + + static int init_common_variables(const char *conf_file_name, int argc, char **argv, const char **groups) { @@ -2089,6 +2128,11 @@ static int init_common_variables(const char *conf_file_name, int argc, global_system_variables.character_set_client= default_charset_info; global_system_variables.collation_connection= default_charset_info; + if (init_global_datetime_format(DATE_FORMAT_TYPE, 1) || + init_global_datetime_format(TIME_FORMAT_TYPE, 1) || + init_global_datetime_format(DATETIME_FORMAT_TYPE, 1)) + return 1; + if (use_temp_pool && bitmap_init(&temp_pool,1024,1)) return 1; return 0; @@ -3533,7 +3577,10 @@ enum options OPT_DEFAULT_WEEK_FORMAT, OPT_GROUP_CONCAT_MAX_LEN, OPT_DEFAULT_COLLATION, - OPT_SECURE_AUTH + OPT_SECURE_AUTH, + OPT_DATE_FORMAT, + OPT_TIME_FORMAT, + OPT_DATETIME_FORMAT }; @@ -4444,6 +4491,21 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.default_week_format, (gptr*) &max_system_variables.default_week_format, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0}, + { "date-format", OPT_DATE_FORMAT, + "The DATE format.", + (gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE], + (gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "datetime-format", OPT_DATETIME_FORMAT, + "The DATETIME/TIMESTAMP format.", + (gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE], + (gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "time-format", OPT_TIME_FORMAT, + "The TIME format.", + (gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE], + (gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -4821,6 +4883,10 @@ static void mysql_init_variables(void) max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; global_system_variables.old_passwords= 0; + init_global_datetime_format(DATE_FORMAT_TYPE, 0); + init_global_datetime_format(TIME_FORMAT_TYPE, 0); + init_global_datetime_format(DATETIME_FORMAT_TYPE, 0); + /* Variables that depends on compile options */ #ifndef DBUG_OFF default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", diff --git a/sql/protocol.cc b/sql/protocol.cc index d1eb3460fc8..c2d9ccec63a 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -831,17 +831,12 @@ bool Protocol_simple::store(TIME *tm) field_pos++; #endif char buff[40]; - uint length; - length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d", - (int) tm->year, - (int) tm->month, - (int) tm->day, - (int) tm->hour, - (int) tm->minute, - (int) tm->second)); - if (tm->second_part) - length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part)); - return net_store_data((char*) buff, length); + String tmp((char*) buff,sizeof(buff),&my_charset_bin); + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (current_thd, DATETIME_FORMAT_TYPE).datetime_format); + make_datetime(&tmp, tm, 1, tm->second_part, + tmp_format->format, tmp_format->format_length, 1); + return net_store_data((char*) tmp.ptr(), tmp.length()); } @@ -853,12 +848,12 @@ bool Protocol_simple::store_date(TIME *tm) field_pos++; #endif char buff[40]; - uint length; - length= my_sprintf(buff,(buff, "%04d-%02d-%02d", - (int) tm->year, - (int) tm->month, - (int) tm->day)); - return net_store_data((char*) buff, length); + String tmp((char*) buff,sizeof(buff),&my_charset_bin); + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (current_thd, DATE_FORMAT_TYPE).datetime_format); + make_datetime(&tmp, tm, 1, 0, + tmp_format->format, tmp_format->format_length, 1); + return net_store_data((char*) tmp.ptr(), tmp.length()); } @@ -876,16 +871,14 @@ bool Protocol_simple::store_time(TIME *tm) field_pos++; #endif char buff[40]; - uint length; + String tmp((char*) buff,sizeof(buff),&my_charset_bin); + DATETIME_FORMAT *tmp_format= (&t_datetime_frm + (current_thd, TIME_FORMAT_TYPE).datetime_format); uint day= (tm->year || tm->month) ? 0 : tm->day; - length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", - tm->neg ? "-" : "", - (long) day*24L+(long) tm->hour, - (int) tm->minute, - (int) tm->second)); - if (tm->second_part) - length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part)); - return net_store_data((char*) buff, length); + tm->hour= (long) day*24L+(long) tm->hour; + make_datetime(&tmp, tm, 0, tm->second_part, + tmp_format->format, tmp_format->format_length, 1); + return net_store_data((char*) tmp.ptr(), tmp.length()); } diff --git a/sql/set_var.cc b/sql/set_var.cc index d07bcd52559..10f40271906 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -383,6 +383,9 @@ sys_var *sys_variables[]= &sys_collation_connection, &sys_concurrent_insert, &sys_connect_timeout, + &g_datetime_frm(DATE_FORMAT_TYPE), + &g_datetime_frm(DATETIME_FORMAT_TYPE), + &g_datetime_frm(TIME_FORMAT_TYPE), &sys_default_week_format, &sys_delay_key_write, &sys_delayed_insert_limit, @@ -512,6 +515,8 @@ struct show_var_st init_vars[]= { {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {"datadir", mysql_real_data_home, SHOW_CHAR}, + {"date_format", (char*) &g_datetime_frm(DATE_FORMAT_TYPE), SHOW_SYS}, + {"datetime_format", (char*) &g_datetime_frm(DATETIME_FORMAT_TYPE), SHOW_SYS}, {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, @@ -661,6 +666,7 @@ struct show_var_st init_vars[]= { #endif {"thread_stack", (char*) &thread_stack, SHOW_LONG}, {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS}, + {"time_format", (char*) &g_datetime_frm(TIME_FORMAT_TYPE), SHOW_SYS}, #ifdef HAVE_TZNAME {"timezone", time_zone, SHOW_CHAR}, #endif @@ -671,9 +677,75 @@ struct show_var_st init_vars[]= { {NullS, NullS, SHOW_LONG} }; + /* Functions to check and update variables */ +char *update_datetime_format(THD *thd, enum enum_var_type type, + enum datetime_format_types format_type, + DATETIME_FORMAT *tmp_format) +{ + char *old_value; + if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + old_value= g_datetime_frm(format_type).datetime_format.format; + g_datetime_frm(format_type).datetime_format= *tmp_format; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + { + old_value= t_datetime_frm(thd,format_type).datetime_format.format; + t_datetime_frm(thd, format_type).datetime_format= *tmp_format; + } + return old_value; +} + + +bool sys_var_datetime_format::update(THD *thd, set_var *var) +{ + DATETIME_FORMAT tmp_format; + char *old_value; + uint new_length; + + if ((new_length= var->value->str_value.length())) + { + if (!make_format(&tmp_format, format_type, + var->value->str_value.ptr(), + new_length, 1)) + return 1; + } + + old_value= update_datetime_format(thd, var->type, format_type, &tmp_format); + my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); + return 0; +} + +byte *sys_var_datetime_format::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + if (type == OPT_GLOBAL) + return (byte*) g_datetime_frm(format_type).datetime_format.format; + return (byte*) t_datetime_frm(thd, format_type).datetime_format.format; +} + +void sys_var_datetime_format::set_default(THD *thd, enum_var_type type) +{ + DATETIME_FORMAT tmp_format; + char *old_value; + uint new_length; + + if ((new_length= strlen(opt_datetime_formats[format_type]))) + { + if (!make_format(&tmp_format, format_type, + opt_datetime_formats[format_type], + new_length, 1)) + return; + } + + old_value= update_datetime_format(thd, type, format_type, &tmp_format); + my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); +} /* The following 3 functions need to be changed in 4.1 when we allow diff --git a/sql/set_var.h b/sql/set_var.h index 9c9ad071967..4bff1e31193 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -49,6 +49,8 @@ public: const char *name; sys_after_update_func after_update; + sys_var() + {} sys_var(const char *name_arg) :name(name_arg),after_update(0) {} sys_var(const char *name_arg,sys_after_update_func func) @@ -188,6 +190,9 @@ public: class sys_var_thd :public sys_var { public: + sys_var_thd() + :sys_var() + {} sys_var_thd(const char *name_arg) :sys_var(name_arg) {} @@ -538,6 +543,51 @@ public: }; +class sys_var_datetime_format :public sys_var_thd +{ +public: + enum datetime_format_types format_type; + DATETIME_FORMAT datetime_format; + sys_var_datetime_format(): sys_var_thd() + {} + + void clean() + { + my_free(datetime_format.format, MYF(MY_ALLOW_ZERO_PTR)); + datetime_format.format=0; + } + + /* + It's for copying of global_system_variables structure + in THD constructor. + */ + inline sys_var_datetime_format& operator= (sys_var_datetime_format& s) + { + if (&s != this) + { + name= s.name; name_length= s.name_length; + datetime_format= s.datetime_format; + datetime_format.format= (my_strdup_with_length + (s.datetime_format.format, + s.datetime_format. + format_length, MYF(0))); + format_type= s.format_type; + } + return *this; + } + + SHOW_TYPE type() { return SHOW_CHAR; } + bool check_update_type(Item_result type) + { + return type != STRING_RESULT; /* Only accept strings */ + } + bool check_default(enum_var_type type) { return 0; } + bool update(THD *thd, set_var *var); + byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + void set_default(THD *thd, enum_var_type type); +}; + + /* Variable that you can only read from */ class sys_var_readonly: public sys_var diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ba1952e533e..19ce115f379 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -274,6 +274,9 @@ void THD::cleanup(void) close_thread_tables(this); } close_temporary_tables(this); + variables.datetime_formats[DATE_FORMAT_TYPE].clean(); + variables.datetime_formats[TIME_FORMAT_TYPE].clean(); + variables.datetime_formats[DATETIME_FORMAT_TYPE].clean(); delete_dynamic(&user_var_events); hash_free(&user_vars); if (global_read_lock) diff --git a/sql/sql_class.h b/sql/sql_class.h index a49162bb4ef..b86dea480c5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -406,6 +406,7 @@ struct system_variables CHARSET_INFO *character_set_client; CHARSET_INFO *character_set_results; CHARSET_INFO *collation_connection; + sys_var_datetime_format datetime_formats[3]; }; void free_tmp_table(THD *thd, TABLE *entry); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b84a21b1440..4c659c2a61d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -79,6 +79,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) CHARSET_INFO *charset; thr_lock_type lock_type; interval_type interval; + datetime_format_types datetime_format_type; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; } @@ -477,6 +478,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token GEOMETRYCOLLECTION %token GROUP_CONCAT_SYM %token GROUP_UNIQUE_USERS +%token GET_FORMAT %token HOUR_MICROSECOND_SYM %token HOUR_MINUTE_SYM %token HOUR_SECOND_SYM @@ -639,6 +641,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC UDA_CHAR_SUM UDA_FLOAT_SUM UDA_INT_SUM +%type datetime_format_type; %type interval %type table_types @@ -2529,6 +2532,8 @@ simple_expr: { $$= new Item_func_spatial_collection(* $3, Geometry::wkbGeometryCollection, Geometry::wkbPoint); } + | GET_FORMAT '(' datetime_format_type ',' expr ')' + { $$= new Item_func_get_format($3, $5); } | HOUR_SYM '(' expr ')' { $$= new Item_func_hour($3); } | IF '(' expr ',' expr ',' expr ')' @@ -3133,6 +3138,11 @@ interval: | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } | YEAR_SYM { $$=INTERVAL_YEAR; }; +datetime_format_type: + DATE_SYM {$$=DATE_FORMAT_TYPE;} + | TIME_SYM {$$=TIME_FORMAT_TYPE;} + | DATETIME {$$=DATETIME_FORMAT_TYPE;}; + table_alias: /* empty */ | AS @@ -4479,6 +4489,7 @@ keyword: | FLUSH_SYM {} | GEOMETRY_SYM {} | GEOMETRYCOLLECTION {} + | GET_FORMAT {} | GRANTS {} | GLOBAL_SYM {} | HANDLER_SYM {} diff --git a/sql/structs.h b/sql/structs.h index 05ebdba7a37..d9be230c049 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -24,6 +24,11 @@ typedef struct st_date_format { /* How to print date */ uint pos[6]; /* Positions to YY.MM.DD HH:MM:SS */ } DATE_FORMAT; +typedef struct st_datetime_format { + byte dt_pos[8]; + char *format; + uint format_length; +} DATETIME_FORMAT; typedef struct st_keyfile_info { /* used with ha_info() */ byte ref[MAX_REFLENGTH]; /* Pointer to current row */ @@ -110,8 +115,8 @@ typedef struct st_read_record { /* Parameter to read_record */ bool print_error, ignore_not_found_rows; } READ_RECORD; -enum timestamp_type { TIMESTAMP_NONE, TIMESTAMP_DATE, TIMESTAMP_FULL, - TIMESTAMP_TIME }; +enum timestamp_type { TIMESTAMP_NONE, WRONG_TIMESTAMP_FULL, TIMESTAMP_DATE, TIMESTAMP_FULL, + TIMESTAMP_TIME}; typedef struct st_time { uint year,month,day,hour,minute,second; diff --git a/sql/time.cc b/sql/time.cc index 70ae8dcd8ed..f2e41afa560 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -27,6 +27,10 @@ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037 /* Init some variabels needed when using my_local_time */ /* Currently only my_time_zone is inited */ +bool parse_datetime_formats(datetime_format_types format_type, + const char *format_str, uint format_length, + byte *dt_pos); + static long my_time_zone=0; void init_time(void) @@ -316,10 +320,12 @@ ulong convert_month_to_period(ulong month) */ timestamp_type -str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) +str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date,THD *thd) { - uint field_length,year_length,digits,i,number_of_fields,date[7]; + uint field_length= 0, year_length= 0, digits, i, number_of_fields; + uint date[7], date_len[7]; uint not_zero_date; + bool is_internal_format= 0; const char *pos; const char *end=str+length; bool found_delimitier= 0; @@ -336,24 +342,32 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) */ for (pos=str; pos != end && my_isdigit(&my_charset_latin1,*pos) ; pos++) ; + /* Check for internal format */ digits= (uint) (pos-str); - year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; - field_length=year_length-1; + + if (pos == end || digits>=12) + { + is_internal_format= 1; + year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; + field_length=year_length-1; + date_len[0]= year_length; + } not_zero_date= 0; for (i=0 ; i < 6 && str != end && my_isdigit(&my_charset_latin1,*str) ; i++) { + if (!is_internal_format) + date_len[i]= 1; uint tmp_value=(uint) (uchar) (*str++ - '0'); - while (str != end && my_isdigit(&my_charset_latin1,str[0]) && - field_length--) + while (str != end && my_isdigit(&my_charset_latin1,str[0]) + && (is_internal_format && field_length-- || !is_internal_format) ) { tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); str++; + if (!is_internal_format) + date_len[i]+= 1; } - if (found_delimitier && (int) field_length < 0) - { - /* The number can't match any valid date or datetime string */ + if (i == 2 && *str == '.') DBUG_RETURN(TIMESTAMP_NONE); - } date[i]=tmp_value; not_zero_date|= tmp_value; if (i == 2 && str != end && *str == 'T') @@ -371,7 +385,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) found_delimitier=1; // Should be a 'normal' date } } - field_length=1; // Rest fields can only be 2 + if (is_internal_format) + field_length=1; // Rest fields can only be 2 } /* Handle second fractions */ if (i == 6 && (uint) (end-str) >= 2 && *str == '.' && @@ -389,14 +404,69 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) else date[6]=0; - if (year_length == 2 && i >=2 && (date[1] || date[2])) - date[0]+= (date[0] < YY_PART_YEAR ? 2000 : 1900); + while (str != end && (my_ispunct(&my_charset_latin1,*str) || + my_isspace(&my_charset_latin1,*str))) + str++; + + uint add_hours= 0; + if (!my_strnncoll(&my_charset_latin1, + (const uchar *)str, 2, + (const uchar *)"PM", 2)) + add_hours= 12; + number_of_fields=i; while (i < 6) date[i++]=0; - if (number_of_fields < 3 || date[1] > 12 || - date[2] > 31 || date[3] > 23 || date[4] > 59 || date[5] > 59 || - (!fuzzy_date && (date[1] == 0 || date[2] == 0))) + + if (!is_internal_format) + { + byte *frm_pos; + + if (number_of_fields <= 3) + { + frm_pos= t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format.dt_pos; + l_time->hour= 0; + l_time->minute= 0; + l_time->second= 0; + } + else + { + frm_pos= t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format.dt_pos; + l_time->hour= date[(int) frm_pos[3]]; + l_time->minute=date[(int) frm_pos[4]]; + l_time->second=date[(int) frm_pos[5]]; + if (frm_pos[6] == 1) + { + if (l_time->hour > 12) + DBUG_RETURN(WRONG_TIMESTAMP_FULL); + l_time->hour= l_time->hour%12 + add_hours; + } + } + + l_time->year= date[(int) frm_pos[0]]; + l_time->month= date[(int) frm_pos[1]]; + l_time->day= date[(int) frm_pos[2]]; + year_length= date_len[(int) frm_pos[0]]; + } + else + { + l_time->year= date[0]; + l_time->month= date[1]; + l_time->day= date[2]; + l_time->hour= date[3]; + l_time->minute=date[4]; + l_time->second=date[5]; + } + l_time->second_part=date[6]; + l_time->neg= 0; + if (year_length == 2 && i >=2 && (l_time->month || l_time->day)) + l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); + + + if (number_of_fields < 3 || l_time->month > 12 || + l_time->day > 31 || l_time->hour > 23 || + l_time->minute > 59 || l_time->second > 59 || + (!fuzzy_date && (l_time->month == 0 || l_time->day == 0))) { /* Only give warning for a zero date if there is some garbage after */ if (!not_zero_date) // If zero date @@ -411,53 +481,46 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) } } if (not_zero_date) - current_thd->cuted_fields++; - DBUG_RETURN(TIMESTAMP_NONE); + thd->cuted_fields++; + DBUG_RETURN(WRONG_TIMESTAMP_FULL); } - if (str != end && current_thd->count_cuted_fields) + if (str != end && thd->count_cuted_fields) { for (; str != end ; str++) { if (!my_isspace(&my_charset_latin1,*str)) { - current_thd->cuted_fields++; + thd->cuted_fields++; break; } } } - l_time->year= date[0]; - l_time->month= date[1]; - l_time->day= date[2]; - l_time->hour= date[3]; - l_time->minute=date[4]; - l_time->second=date[5]; - l_time->second_part=date[6]; - l_time->neg= 0; + DBUG_RETURN(l_time->time_type= (number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_FULL)); } -time_t str_to_timestamp(const char *str,uint length) +time_t str_to_timestamp(const char *str,uint length, THD *thd) { TIME l_time; long not_used; - if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE) + if (str_to_TIME(str,length,&l_time,0,thd) <= WRONG_TIMESTAMP_FULL) return(0); if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) { - current_thd->cuted_fields++; + thd->cuted_fields++; return(0); } return(my_gmt_sec(&l_time, ¬_used)); } -longlong str_to_datetime(const char *str,uint length,bool fuzzy_date) +longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd) { TIME l_time; - if (str_to_TIME(str,length,&l_time,fuzzy_date) == TIMESTAMP_NONE) + if (str_to_TIME(str,length,&l_time,fuzzy_date,thd) <= WRONG_TIMESTAMP_FULL) return(0); return (longlong) (l_time.year*LL(10000000000) + l_time.month*LL(100000000)+ @@ -484,12 +547,13 @@ longlong str_to_datetime(const char *str,uint length,bool fuzzy_date) 1 error */ -bool str_to_time(const char *str,uint length,TIME *l_time) +bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd) { long date[5],value; const char *end=str+length; bool found_days,found_hours; uint state; + byte *frm_pos= t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format.dt_pos; l_time->neg=0; for (; str != end && @@ -507,8 +571,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time) /* Check first if this is a full TIMESTAMP */ if (length >= 12) { // Probably full timestamp - if (str_to_TIME(str,length,l_time,1) == TIMESTAMP_FULL) - return 0; // Was an ok timestamp + enum timestamp_type tres= str_to_TIME(str,length,l_time,1,thd); + if (tres == TIMESTAMP_FULL) + return 0; + else if (tres == WRONG_TIMESTAMP_FULL) + return 1; } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ @@ -533,7 +600,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time) found_days=1; str++; // Skip space; } - else if ((end-str) > 1 && *str == ':' && + else if ((end-str) > 1 && *str == frm_pos[7] && my_isdigit(&my_charset_latin1,str[1])) { date[0]=0; // Assume we found hours @@ -559,8 +626,8 @@ bool str_to_time(const char *str,uint length,TIME *l_time) for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) value=value*10L + (long) (*str - '0'); date[state++]=value; - if (state == 4 || (end-str) < 2 || *str != ':' || - !my_isdigit(&my_charset_latin1,str[1])) + if (state == 4 || (end-str) < 2 || *str != frm_pos[7] || + !my_isdigit(&my_charset_latin1,str[1])) break; str++; // Skip ':' } @@ -577,7 +644,6 @@ bool str_to_time(const char *str,uint length,TIME *l_time) else bzero((char*) (date+state), sizeof(long)*(4-state)); } - fractional: /* Get fractional second part */ if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1])) @@ -593,6 +659,20 @@ bool str_to_time(const char *str,uint length,TIME *l_time) else date[4]=0; + while (str != end && !my_isalpha(&my_charset_latin1,*str)) + str++; + + if ( (end-str)>= 2 && + !my_strnncoll(&my_charset_latin1, + (const uchar *)str, 2, + (const uchar *)"PM", 2) && + frm_pos[6] == 1) + { + uint days_i= date[1]/24; + uint hours_i= date[1]%24; + date[1]= hours_i%12 + 12 + 24*days_i; + } + /* Some simple checks */ if (date[2] >= 60 || date[3] >= 60) { @@ -601,9 +681,9 @@ bool str_to_time(const char *str,uint length,TIME *l_time) } l_time->month=0; l_time->day=date[0]; - l_time->hour=date[1]; - l_time->minute=date[2]; - l_time->second=date[3]; + l_time->hour=date[frm_pos[3] + 1]; + l_time->minute=date[frm_pos[4] + 1]; + l_time->second=date[frm_pos[5] + 1]; l_time->second_part=date[4]; l_time->time_type= TIMESTAMP_TIME; @@ -648,3 +728,165 @@ void calc_time_from_sec(TIME *to, long seconds, long microseconds) to->second= t_seconds%60L; to->second_part= microseconds; } + + +DATETIME_FORMAT *make_format(DATETIME_FORMAT *datetime_format, + datetime_format_types format_type, + const char *format_str, + uint format_length, bool is_alloc) +{ + if (format_length && + !parse_datetime_formats(format_type, format_str, + format_length, + datetime_format->dt_pos)) + { + if (is_alloc) + { + if (!(datetime_format->format= my_strdup_with_length(format_str, + format_length, + MYF(0)))) + return 0; + } + else + datetime_format->format= (char *) format_str; + datetime_format->format_length= format_length; + return datetime_format; + } + return 0; +} + + +bool parse_datetime_formats(datetime_format_types format_type, + const char *format_str, uint format_length, + byte *dt_pos) +{ + uint pos= 0; + dt_pos[0]= dt_pos[1]= dt_pos[2]= dt_pos[3]= + dt_pos[4]= dt_pos[5]= dt_pos[6]= dt_pos[7]= -1; + + const char *ptr=format_str; + const char *end=ptr+format_length; + bool need_p= 0; + + for (; ptr != end; ptr++) + { + if (*ptr == '%' && ptr+1 != end) + { + switch (*++ptr) { + case 'y': + case 'Y': + if (dt_pos[0] > -1) + return 1; + dt_pos[0]= pos; + break; + case 'c': + case 'm': + if (dt_pos[1] > -1) + return 1; + dt_pos[1]= pos; + break; + case 'd': + case 'e': + if (dt_pos[2] > -1) + return 1; + dt_pos[2]= pos; + break; + case 'H': + case 'k': + case 'h': + case 'I': + case 'l': + if (dt_pos[3] > -1) + return 1; + dt_pos[3]= pos; + need_p= (*ptr == 'h' || *ptr == 'l' || *ptr == 'I'); + break; + case 'i': + if (dt_pos[4] > -1) + return 1; + dt_pos[4]= pos; + break; + case 's': + case 'S': + if (dt_pos[5] > -1) + return 1; + dt_pos[5]= pos; + break; + case 'p': + if (dt_pos[6] > -1) + return 1; + /* %p should be last in format string */ + if (format_type == DATE_FORMAT_TYPE || + (pos != 6 && format_type == DATETIME_FORMAT_TYPE) || + (pos != 3 && format_type == TIME_FORMAT_TYPE)) + return 1; + dt_pos[6]= 1; + break; + default: + return 1; + } + if (dt_pos[6] == -1) + pos++; + } + } + + if (pos > 5 && format_type == DATETIME_FORMAT_TYPE && + (dt_pos[0] + dt_pos[1] + dt_pos[2] + + dt_pos[3] + dt_pos[4] + dt_pos[5] != 15) || + pos > 2 && format_type == DATE_FORMAT_TYPE && + (dt_pos[0] + dt_pos[1] + dt_pos[2] != 3) || + pos > 2 && format_type == TIME_FORMAT_TYPE && + (dt_pos[3] + dt_pos[4] + dt_pos[5] != 3) || + (need_p && dt_pos[6] != 1)) + return 1; + + /* + Check for valid separators between date/time parst + */ + uint tmp_len= format_length; + if (dt_pos[6] == 1) + { + end= end - 2; + if (my_ispunct(&my_charset_latin1, *end) || my_isspace(&my_charset_latin1, *end)) + end--; + tmp_len= end - format_str; + } + switch (format_type) { + case DATE_FORMAT_TYPE: + case TIME_FORMAT_TYPE: + if ((tmp_len == 6 && + !my_strnncoll(&my_charset_bin, + (const uchar *) format_str, 6, + (const uchar *) datetime_formats + [format_type][INTERNAL_FORMAT], 6)) || + tmp_len == 8 && + my_ispunct(&my_charset_latin1, *(format_str+2)) && + my_ispunct(&my_charset_latin1, *(format_str+5))) + { + if (format_type == TIME_FORMAT_TYPE && tmp_len == 8) + { + if (*(format_str+2) != *(format_str+5)) + return 1; + dt_pos[7]= *(format_str+2); + } + return 0; + } + break; + case DATETIME_FORMAT_TYPE: + if ((tmp_len == 12 && + !my_strnncoll(&my_charset_bin, + (const uchar *) format_str, 12, + (const uchar *) datetime_formats + [DATETIME_FORMAT_TYPE][INTERNAL_FORMAT], 12)) || + tmp_len == 17 && + my_ispunct(&my_charset_latin1, *(format_str+2)) && + my_ispunct(&my_charset_latin1, *(format_str+5)) && + my_ispunct(&my_charset_latin1, *(format_str+11)) && + my_ispunct(&my_charset_latin1, *(format_str+14)) && + (my_ispunct(&my_charset_latin1, *(format_str+8)) || + my_isspace(&my_charset_latin1, *(format_str+8)))) + return 0; + break; + } + return 1; +} From 30743b966563bfd3a543f1df428de5a75a1d5ee5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Oct 2003 18:52:45 +0500 Subject: [PATCH 48/50] Fix for: http://bugs.mysql.com/bug.php?id=1022 Description: When a table contains a 'float' field, and one of the functions MAX, MIN, or AVG is used on that field, the system crashes. --- sql/item.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/item.cc b/sql/item.cc index 4de4951cb51..127c0a36da4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1296,6 +1296,14 @@ bool Item::send(Protocol *protocol, String *buffer) result= protocol->store_longlong(nr, unsigned_flag); break; } + case MYSQL_TYPE_FLOAT: + { + float nr; + nr= val(); + if (!null_value) + result= protocol->store(nr, decimals, buffer); + break; + } case MYSQL_TYPE_DOUBLE: { double nr; From 5d4ae9871199475813fe81b1e326739d51a90136 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Oct 2003 19:13:45 +0500 Subject: [PATCH 49/50] Test for bug #1022 Description: When a table contains a 'float' field, and one of the functions MAX, MIN, or AVG is used on that field, the system crashes. --- mysql-test/r/type_float.result | 6 ++++++ mysql-test/t/type_float.test | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 987fa9d5685..2a461942853 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -70,6 +70,12 @@ select min(a) from t1; min(a) -0.010 drop table t1; +create table t1 (a float); +insert into t1 values (1); +select max(a),min(a),avg(a) from t1; +max(a) min(a) avg(a) +1 1 1 +drop table t1; create table t1 (f float, f2 float(24), f3 float(6,2), d double, d2 float(53), d3 double(10,3), de decimal, de2 decimal(6), de3 decimal(5,2), n numeric, n2 numeric(8), n3 numeric(5,6)); show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index f6281ca6c21..caccf31b32a 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -31,6 +31,15 @@ select a from t1 order by a; select min(a) from t1; drop table t1; +# Bug #1022: When a table contains a 'float' field, +# and one of the functions MAX, MIN, or AVG is used on that field, +# the system crashes. + +create table t1 (a float); +insert into t1 values (1); +select max(a),min(a),avg(a) from t1; +drop table t1; + # # FLOAT/DOUBLE/DECIMAL handling # From 8d94e500e025fb5626df12c8183e8ab14c74e624 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Oct 2003 16:05:17 +0500 Subject: [PATCH 50/50] Fix for Windows bug reported throuhg Miguel libmysqld/lib_sql.cc: This code seems to be superfluous sql/derror.cc: in embedded server these functions should return the sign of the error instead of halting the program sql/init.cc: my_abort_hook left unchanged sql/mysql_priv.h: declaration of init_errmessage changed unireg_abort was replaced with DBUG_RETURN for embedded server sql/mysqld.cc: these functions don't work in embedded server thus #ifdef-ed --- libmysqld/lib_sql.cc | 5 ----- sql/derror.cc | 13 +++++++------ sql/init.cc | 2 ++ sql/mysql_priv.h | 6 +++++- sql/mysqld.cc | 15 ++++++++++----- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index c9f98a701ef..d4cb916a89c 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -435,11 +435,6 @@ void STDCALL mysql_server_end() my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR)); copy_arguments_ptr=0; clean_up(0); -#ifdef THREAD - /* Don't call my_thread_end() if the application is using MY_INIT() */ - if (!org_my_init_done) - my_thread_end(); -#endif /* If library called my_init(), free memory allocated by it */ if (!org_my_init_done) my_end(0); diff --git a/sql/derror.cc b/sql/derror.cc index 78efdcc33f3..7f4068c487e 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -20,27 +20,28 @@ #include "mysql_priv.h" #include "mysys_err.h" -static void read_texts(const char *file_name,const char ***point, +static bool read_texts(const char *file_name,const char ***point, uint error_messages); static void init_myfunc_errs(void); /* Read messages from errorfile */ -void init_errmessage(void) +bool init_errmessage(void) { DBUG_ENTER("init_errmessage"); - read_texts(ERRMSG_FILE,&my_errmsg[ERRMAPP],ER_ERROR_MESSAGES); + if (read_texts(ERRMSG_FILE,&my_errmsg[ERRMAPP],ER_ERROR_MESSAGES)) + DBUG_RETURN(TRUE); errmesg=my_errmsg[ERRMAPP]; /* Init global variabel */ init_myfunc_errs(); /* Init myfunc messages */ - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } /* Read text from packed textfile in language-directory */ /* If we can't read messagefile then it's panic- we can't continue */ -static void read_texts(const char *file_name,const char ***point, +static bool read_texts(const char *file_name,const char ***point, uint error_messages) { register uint i; @@ -116,7 +117,7 @@ Check that the above file is the right version for this program!", point[i]= *point +uint2korr(head+10+i+i); } VOID(my_close(file,MYF(0))); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); err: switch (funktpos) { diff --git a/sql/init.cc b/sql/init.cc index 50d504068a0..8b15fef4ee3 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -37,7 +37,9 @@ void unireg_init(ulong options) #ifdef USE_MY_ATOF init_my_atof(); /* use our atof */ #endif +#ifndef EMBEDDED_LIBRARY my_abort_hook=unireg_abort; /* Abort with close of databases */ +#endif VOID(strmov(reg_ext,".frm")); for (i=0 ; i < 6 ; i++) // YYMMDDHHMMSS diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6c1f7bfa472..f30702afcc2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -725,7 +725,7 @@ void key_restore(TABLE *form,byte *key,uint index,uint key_length); int key_cmp(TABLE *form,const byte *key,uint index,uint key_length); void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); -void init_errmessage(void); +bool init_errmessage(void); void sql_perror(const char *message); void sql_print_error(const char *format,...) @@ -919,7 +919,11 @@ void calc_time_from_sec(TIME *to, long seconds, long microseconds); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); +#ifndef EMBEDDED_LIBRARY extern "C" void unireg_abort(int exit_code); +#else +#define unireg_abort(exit_code) DBUG_RETURN(exit_code) +#endif void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 812a5b28ff7..d2c04f634f9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -845,6 +845,7 @@ extern "C" sig_handler print_signal_warning(int sig) (Mac OS X) we have to call exit() instead if pthread_exit(). */ +#ifndef EMBEDDED_LIBRARY void unireg_end(void) { clean_up(1); @@ -856,7 +857,6 @@ void unireg_end(void) #endif } - extern "C" void unireg_abort(int exit_code) { DBUG_ENTER("unireg_abort"); @@ -868,7 +868,7 @@ extern "C" void unireg_abort(int exit_code) my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ } - +#endif void clean_up(bool print_message) { @@ -1015,6 +1015,7 @@ static void set_ports() } } +#ifndef EMBEDDED_LIBRARY /* Change to run as another user if started with --user */ static void set_user(const char *user) @@ -1097,7 +1098,6 @@ static void set_root(const char *path) #endif } - static void server_init(void) { struct sockaddr_in IPaddr; @@ -1248,6 +1248,7 @@ static void server_init(void) DBUG_VOID_RETURN; } +#endif /*!EMBEDDED_LIBRARY*/ void yyerror(const char *s) { @@ -2081,7 +2082,8 @@ static int init_common_variables(const char *conf_file_name, int argc, open_files_limit= 0; /* Can't set or detect limit */ #endif unireg_init(opt_specialflag); /* Set up extern variabels */ - init_errmessage(); /* Read error messages from file */ + if (init_errmessage()) /* Read error messages from file */ + return 1; init_client_errs(); lex_init(); item_init(); @@ -2188,6 +2190,7 @@ static void init_ssl() static int init_server_components() { + DBUG_ENTER("init_server_components"); table_cache_init(); hostname_cache_init(); query_cache_result_size_limit(query_cache_limit); @@ -2279,7 +2282,7 @@ Now disabling --log-slave-updates."); init_max_user_conn(); init_update_queries(); - return 0; + DBUG_RETURN(0); } @@ -5537,8 +5540,10 @@ static void get_options(int argc,char **argv) /* Set global MyISAM variables from delay_key_write_options */ fix_delay_key_write((THD*) 0, OPT_GLOBAL); +#ifndef EMBEDDED_LIBRARY if (mysqld_chroot) set_root(mysqld_chroot); +#endif fix_paths(); /*