From 4536b069238b0aa862bc3aa497b750c945eef736 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Nov 2002 22:57:17 +0100 Subject: [PATCH 01/61] - Moved the init script from /etc/rc.d/init.d to /etc/init.d for better compatibility of the RPMs - added "restart" action to the mysql.server init script support-files/mysql.server.sh: - added "restart" action support-files/mysql.spec.sh: - moved init script from /etc/rc.d/init.d to /etc/init.d (the majority of Linux distributions now support this scheme as proposed by the LSB either directly or via a compatibility symlink) - relaxed the Perl requirements a bit - Use new "restart" init script action instead of starting and stopping separately - Be more flexible in activating the automatic bootup - use insserv (on older SuSE versions) or chkconfig (Red Hat, newer SuSE versions and others) to create the respective symlinks --- support-files/mysql.server.sh | 9 ++++- support-files/mysql.spec.sh | 63 ++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 822e864dd77..a6468997b0f 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -173,9 +173,16 @@ case "$mode" in fi ;; + 'restart') + # Stop the service and regardless of whether it was + # running or not, start it again. + $0 stop + $0 start + ;; + *) # usage - echo "usage: $0 start|stop" + echo "Usage: $0 start|stop|restart" exit 1 ;; esac diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index dcff17dee03..978e04e3268 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -71,7 +71,7 @@ Este pacote cont %package bench Release: %{release} -Requires: %{name}-client MySQL-DBI-perl-bin perl +Requires: %{name}-client perl-DBI perl Summary: MySQL - Benchmarks and test system Group: Applications/Databases Summary(pt_BR): MySQL - Medições de desempenho @@ -269,7 +269,7 @@ RBR=$RPM_BUILD_ROOT MBD=$RPM_BUILD_DIR/mysql-%{mysql_version} # Ensure that needed directories exists -install -d $RBR/etc/{logrotate.d,rc.d/init.d} +install -d $RBR/etc/{logrotate.d,init.d} install -d $RBR/var/lib/mysql/mysql install -d $RBR/usr/share/{sql-bench,mysql-test} install -d $RBR%{_mandir} @@ -290,14 +290,20 @@ install -m644 $MBD/sql/mysqld.sym $RBR/usr/lib/mysql/mysqld.sym # Install logrotate and autostart install -m644 $MBD/support-files/mysql-log-rotate $RBR/etc/logrotate.d/mysql -install -m755 $MBD/support-files/mysql.server $RBR/etc/rc.d/init.d/mysql +install -m755 $MBD/support-files/mysql.server $RBR/etc/init.d/mysql # Create symbolic compatibility link safe_mysqld -> mysqld_safe # (safe_mysqld will be gone in MySQL 4.1) ln -sf ./mysqld_safe $RBR/usr/bin/safe_mysqld %pre -if test -x /etc/rc.d/init.d/mysql +# Shut down a previously installed server first +if test -x /etc/init.d/mysql +then + /etc/init.d/mysql stop > /dev/null 2>&1 + echo "Giving mysqld a couple of seconds to exit nicely" + sleep 5 +elif test -x /etc/rc.d/init.d/mysql then /etc/rc.d/init.d/mysql stop > /dev/null 2>&1 echo "Giving mysqld a couple of seconds to exit nicely" @@ -313,7 +319,15 @@ if test ! -d $mysql_datadir/mysql; then mkdir $mysql_datadir/mysql; fi if test ! -d $mysql_datadir/test; then mkdir $mysql_datadir/test; fi # Make MySQL start/shutdown automatically when the machine does it. -/sbin/chkconfig --add mysql +# use insserv for older SuSE Linux versions +if test -x /sbin/insserv +then + /sbin/insserv /etc/init.d/mysql +# use chkconfig on Red Hat and newer SuSE releases +elif test -x /sbin/chkconfig +then + /sbin/chkconfig --add mysql +fi # Create a MySQL user. Do not report any problems if it already # exists. This is redhat specific and should be handled more portable @@ -334,31 +348,37 @@ chown -R mysql $mysql_datadir chmod -R og-rw $mysql_datadir/mysql # Restart in the same way that mysqld will be started normally. -/etc/rc.d/init.d/mysql start +/etc/init.d/mysql start # Allow safe_mysqld to start mysqld and print a message before we exit sleep 2 %post Max # Restart mysqld, to use the new binary. -# There may be a better way to handle this. -/etc/rc.d/init.d/mysql stop > /dev/null 2>&1 -echo "Giving mysqld a couple of seconds to restart" -sleep 5 -/etc/rc.d/init.d/mysql start -sleep 2 +echo "Restarting mysqld." +/etc/init.d/mysql restart > /dev/null 2>&1 %preun if test $1 = 0 then - if test -x /etc/rc.d/init.d/mysql + # Stop MySQL before uninstalling it + if test -x /etc/init.d/mysql then - /etc/rc.d/init.d/mysql stop > /dev/null + /etc/init.d/mysql stop > /dev/null fi # Remove autostart of mysql - /sbin/chkconfig --del mysql + # for older SuSE Linux versions + if test -x /sbin/insserv + then + /sbin/insserv -r /etc/init.d/mysql + # use chkconfig on Red Hat and newer SuSE releases + elif test -x /sbin/chkconfig + then + /sbin/chkconfig --del mysql + fi fi + # We do not remove the mysql user since it may still own a lot of # database files. @@ -412,7 +432,7 @@ fi %attr(644, root, root) /usr/lib/mysql/mysqld.sym %attr(644, root, root) /etc/logrotate.d/mysql -%attr(755, root, root) /etc/rc.d/init.d/mysql +%attr(755, root, root) /etc/init.d/mysql %attr(755, root, root) /usr/share/mysql/ @@ -482,6 +502,17 @@ fi %changelog +* Wed Nov 27 2002 Lenz Grimmer + +- moved init script from /etc/rc.d/init.d to /etc/init.d (the majority of + Linux distributions now support this scheme as proposed by the LSB either + directly or via a compatibility symlink) +- Use new "restart" init script action instead of starting and stopping + separately +- Be more flexible in activating the automatic bootup - use insserv (on + older SuSE versions) or chkconfig (Red Hat, newer SuSE versions and + others) to create the respective symlinks + * Wed Sep 25 2002 Lenz Grimmer - MySQL-Max now requires MySQL >= 4.0 to avoid version mismatches From cf85a16cf48e20a319e2b26cdd7dc41ea0972528 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2002 01:01:38 +0100 Subject: [PATCH 02/61] better fix for read_rows, same for read_one_row --- libmysql/libmysql.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 3c1353e0088..9db1e1c9ab9 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -939,7 +939,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, else { cur->data[field] = to; - if (to+len > end_to) + if (len > end_to - to) { free_rows(result); net->last_errno=CR_UNKNOWN_ERROR; @@ -980,7 +980,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) { uint field; ulong pkt_len,len; - uchar *pos,*prev_pos; + uchar *pos,*prev_pos, *end_pos; if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error) return -1; @@ -988,6 +988,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) return 1; /* End of data */ prev_pos= 0; /* allowed to write at packet[-1] */ pos=mysql->net.read_pos; + end_pos=pos+pkt_len; for (field=0 ; field < fields ; field++) { if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH) @@ -997,6 +998,12 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) } else { + if (len > end_pos - pos) + { + mysql->net.last_errno=CR_UNKNOWN_ERROR; + strmov(mysql->net.last_error,ER(mysql->net.last_errno)); + return -1; + } row[field] = (char*) pos; pos+=len; *lengths++=len; From 446f877906f7cb7f1a4a65b185ca49d58f832121 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2002 22:03:24 +0200 Subject: [PATCH 03/61] row0mysql.c, dict0dict.c, db0err.h, ha_innobase.cc: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd sql/ha_innobase.cc: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/include/db0err.h: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/dict/dict0dict.c: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd innobase/row/row0mysql.c: Heikki will merge to 4.0: Prevent listing the same column twice in an InnoDB index: that will cause index corruption when that col is UPDATEd --- innobase/dict/dict0dict.c | 21 ++++++++++++++++++++ innobase/include/db0err.h | 2 ++ innobase/row/row0mysql.c | 40 ++++++++++++++++++++++++++++++++------- sql/ha_innobase.cc | 6 +++++- 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 65f40d345d8..eb9610a6e73 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1033,6 +1033,7 @@ dict_index_add_to_cache( ulint n_ord; ibool success; ulint i; + ulint j; ut_ad(index); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1063,6 +1064,26 @@ dict_index_add_to_cache( return(FALSE); } + /* Check that the same column does not appear twice in the index. + InnoDB assumes this in its algorithms, e.g., update of an index + entry */ + + for (i = 0; i < dict_index_get_n_fields(index); i++) { + + for (j = 0; j < i; j++) { + if (dict_index_get_nth_field(index, j)->col + == dict_index_get_nth_field(index, i)->col) { + + fprintf(stderr, +"InnoDB: Error: column %s appears twice in index %s of table %s\n" +"InnoDB: This is not allowed in InnoDB.\n" +"InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n", + dict_index_get_nth_field(index, i)->col->name, + index->name, table->name); + } + } + } + /* Build the cache internal representation of the index, containing also the added system fields */ diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index ddfbd5b7862..df74b06dfc0 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -42,6 +42,8 @@ Created 5/24/1996 Heikki Tuuri #define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint to a table failed */ +#define DB_COL_APPEARS_TWICE_IN_INDEX 40 + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 705ded785fc..325e931b455 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1393,7 +1393,7 @@ int row_create_index_for_mysql( /*=======================*/ /* out: error number or DB_SUCCESS */ - dict_index_t* index, /* in: index defintion */ + dict_index_t* index, /* in: index definition */ trx_t* trx) /* in: transaction handle */ { ind_node_t* node; @@ -1402,11 +1402,14 @@ row_create_index_for_mysql( ulint namelen; ulint keywordlen; ulint err; + ulint i; + ulint j; + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); - trx->op_info = "creating index"; + trx->op_info = (char *) "creating index"; trx_start_if_not_started(trx); @@ -1422,6 +1425,29 @@ row_create_index_for_mysql( return(DB_SUCCESS); } + /* Check that the same column does not appear twice in the index. + InnoDB assumes this in its algorithms, e.g., update of an index + entry */ + + for (i = 0; i < dict_index_get_n_fields(index); i++) { + for (j = 0; j < i; j++) { + if (0 == ut_strcmp( + dict_index_get_nth_field(index, j)->name, + dict_index_get_nth_field(index, i)->name)) { + + fprintf(stderr, +"InnoDB: Error: column %s appears twice in index %s\n" +"InnoDB: This is not allowed in InnoDB.\n", + dict_index_get_nth_field(index, i)->name, + index->name); + + err = DB_COL_APPEARS_TWICE_IN_INDEX; + + goto error_handling; + } + } + } + heap = mem_heap_create(512); trx->dict_operation = TRUE; @@ -1434,11 +1460,13 @@ row_create_index_for_mysql( SESS_COMM_EXECUTE, 0)); que_run_threads(thr); - err = trx->error_state; + err = trx->error_state; + que_graph_free((que_t*) que_node_get_parent(thr)); + +error_handling: if (err != DB_SUCCESS) { /* We have special error handling here */ - ut_a(err == DB_OUT_OF_FILE_SPACE); trx->error_state = DB_SUCCESS; @@ -1448,10 +1476,8 @@ row_create_index_for_mysql( trx->error_state = DB_SUCCESS; } - - que_graph_free((que_t*) que_node_get_parent(thr)); - trx->op_info = ""; + trx->op_info = (char *) ""; return((int) err); } diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 2f79f8d6ba9..489c2fafd9b 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -233,10 +233,14 @@ convert_error_code_to_mysql( return(HA_ERR_ROW_IS_REFERENCED); - } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) { + } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) { return(HA_ERR_CANNOT_ADD_FOREIGN); + } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) { + + return(HA_ERR_WRONG_TABLE_DEF); + } else if (error == (int) DB_OUT_OF_FILE_SPACE) { return(HA_ERR_RECORD_FILE_FULL); From c92d611d5447407820ebf3914a71b3a8ab265774 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2002 22:09:51 +0200 Subject: [PATCH 04/61] row0mysql.c: Heikki will merge to 4.0: cleanup innobase/row/row0mysql.c: Heikki will merge to 4.0: cleanup --- innobase/row/row0mysql.c | 1 - 1 file changed, 1 deletion(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 325e931b455..f0aa413a64c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1405,7 +1405,6 @@ row_create_index_for_mysql( ulint i; ulint j; - ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); From a29ee10048e9bbe0f5251a36981b274ab72b8a25 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Dec 2002 21:38:27 +0100 Subject: [PATCH 05/61] current_user() to return priv_user --- sql/item.h | 4 +++- sql/item_create.cc | 11 ++++++++++- sql/item_create.h | 1 + sql/lex.h | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sql/item.h b/sql/item.h index ad68287a92c..05b906a66a6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -267,6 +267,8 @@ public: } Item_string(const char *name_par,const char *str,uint length) { + if (!length) + length=strlen(str); str_value.set(str,length); max_length=length; name=(char*) name_par; @@ -286,7 +288,7 @@ public: String *const_string() { return &str_value; } inline void append(char *str,uint length) { str_value.append(str,length); } void print(String *str); - unsigned int size_of() { return sizeof(*this);} + unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/item_create.cc b/sql/item_create.cc index c5f53f0d040..1f0bad8eda3 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -291,6 +291,15 @@ Item *create_func_pow(Item* a, Item *b) return new Item_func_pow(a,b); } +Item *create_func_current_user() +{ + THD *thd=current_thd; + Item_string *res=new Item_string("CURRENT_USER()", thd->priv_user, 0); + res->append("@", 1); + res->append((char *)thd->host_or_ip, 0); + return res; +} + Item *create_func_quarter(Item* a) { return new Item_func_quarter(a); @@ -394,7 +403,7 @@ Item *create_func_ucase(Item* a) Item *create_func_version(void) { - return new Item_string(NullS,server_version, (uint) strlen(server_version)); + return new Item_string("VERSION()",server_version, 0); } Item *create_func_weekday(Item* a) diff --git a/sql/item_create.h b/sql/item_create.h index 28fbd61df8f..80ef57e436a 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -68,6 +68,7 @@ Item *create_func_period_add(Item* a, Item *b); Item *create_func_period_diff(Item* a, Item *b); Item *create_func_pi(void); Item *create_func_pow(Item* a, Item *b); +Item *create_func_current_user(void); Item *create_func_quarter(Item* a); Item *create_func_radians(Item *a); Item *create_func_release_lock(Item* a); diff --git a/sql/lex.h b/sql/lex.h index 717e8a355ca..bf0abc323e1 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -398,7 +398,7 @@ static SYMBOL sql_functions[] = { { "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)}, - { "CURRENT_USER", SYM(USER),0,0}, + { "CURRENT_USER", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_current_user)}, { "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)}, { "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, From 7cc9c3c6bf6d39ba057d6573a2d95fc7d987cc8e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Dec 2002 22:49:16 +0200 Subject: [PATCH 06/61] Don't initialize fulltext functions twice in multi-table-update mysql-test/mysql-test-run.sh: Added option --extern (from 4.1) mysql-test/r/multi_update.result: Portability fix mysql-test/t/multi_update.test: Portability fix --- mysql-test/mysql-test-run.sh | 1 + mysql-test/r/multi_update.result | 14 +++++++------- mysql-test/t/multi_update.test | 4 ++-- sql/sql_update.cc | 1 - 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 928beaf0aa4..5c80e7d538a 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -217,6 +217,7 @@ while test $# -gt 0; do --slave-binary=*) SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;; --local) USE_RUNNING_SERVER="" ;; + --extern) USE_RUNNING_SERVER="1" ;; --tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;; --local-master) MASTER_MYPORT=3306; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 7d1f5bd53f6..8cf035343b1 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -182,13 +182,13 @@ insert into t1 values(1,1,NULL); insert into t2 values(1,10,NULL),(2,20,NULL); set timestamp=1038000000; UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n; -select * from t1; -n d t -1 10 20021123002000 -select * from t2; -n d t -1 10 20021127154957 -2 20 20021127154957 +select n,d,unix_timestamp(t) from t1; +n d unix_timestamp(t) +1 10 1038000000 +select n,d,unix_timestamp(t) from t2; +n d unix_timestamp(t) +1 10 1038401397 +2 20 1038401397 UPDATE t1,t2 SET 1=2 WHERE t1.n=t2.n; You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1=2 WHERE t1.n=t2.n' at line 1 drop table t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index b79b0749c82..ff456b710c1 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -183,8 +183,8 @@ insert into t1 values(1,1,NULL); insert into t2 values(1,10,NULL),(2,20,NULL); set timestamp=1038000000; UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n; -select * from t1; -select * from t2; +select n,d,unix_timestamp(t) from t1; +select n,d,unix_timestamp(t) from t2; --error 1064 UPDATE t1,t2 SET 1=2 WHERE t1.n=t2.n; drop table t1,t2; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4eab38bebad..2416a99faa8 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -517,7 +517,6 @@ int multi_update::prepare(List ¬_used_values) for (i=0 ; i < table_count ; i++) set_if_bigger(max_fields, fields_for_table[i]->elements); copy_field= new Copy_field[max_fields]; - init_ftfuncs(thd,1); DBUG_RETURN(thd->fatal_error != 0); } From 6271ea35b83501781cf3ee51a62fd95870b3fb96 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Dec 2002 22:40:20 +0100 Subject: [PATCH 07/61] bulk insert code optimized mysql-test/r/distinct.result: updated mysql-test/r/fulltext.result: updated mysql-test/r/select.result: updated mysql-test/r/show_check.result: updated mysql-test/t/insert.test: updated --- include/my_base.h | 3 --- include/myisam.h | 4 +++ myisam/mi_extra.c | 27 ------------------- myisam/mi_write.c | 47 +++++++++++++++++++++++++++++----- myisam/myisamdef.h | 3 +-- mysql-test/r/distinct.result | 8 +++--- mysql-test/r/fulltext.result | 4 +-- mysql-test/r/select.result | 4 +-- mysql-test/r/show_check.result | 2 +- mysql-test/t/insert.test | 2 ++ sql/ha_myisam.cc | 18 ++++++------- sql/ha_myisammrg.cc | 4 +-- sql/sql_insert.cc | 20 +++++---------- 13 files changed, 73 insertions(+), 73 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index 8ef8301b84d..bcb8c8d6a2f 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -106,9 +106,6 @@ enum ha_extra_function { HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/ HA_EXTRA_NO_IGNORE_DUP_KEY, HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */ - HA_EXTRA_BULK_INSERT_BEGIN, - HA_EXTRA_BULK_INSERT_FLUSH, /* Flush one index */ - HA_EXTRA_BULK_INSERT_END, HA_EXTRA_PREPARE_FOR_DELETE, HA_EXTRA_PREPARE_FOR_UPDATE /* Remove read cache if problems */ }; diff --git a/include/myisam.h b/include/myisam.h index 79d18bf8736..94b5d23bba6 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -433,6 +433,10 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, my_bool force); +int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows); +void mi_flush_bulk_insert(MI_INFO *info, uint inx); +void mi_end_bulk_insert(MI_INFO *info); + #ifdef __cplusplus } #endif diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index d7a3aea516d..8429b22dad4 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -358,33 +358,6 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) case HA_EXTRA_QUICK: info->quick_mode=1; break; - case HA_EXTRA_BULK_INSERT_BEGIN: - error=_mi_init_bulk_insert(info, (extra_arg ? *(ulong*) extra_arg : - myisam_bulk_insert_tree_size)); - break; - case HA_EXTRA_BULK_INSERT_FLUSH: - if (info->bulk_insert) - { - uint index_to_flush= *(uint*) extra_arg; - if (is_tree_inited(&info->bulk_insert[index_to_flush])) - reset_tree(&info->bulk_insert[index_to_flush]); - } - break; - case HA_EXTRA_BULK_INSERT_END: - if (info->bulk_insert) - { - uint i; - for (i=0 ; i < share->base.keys ; i++) - { - if (is_tree_inited(& info->bulk_insert[i])) - { - delete_tree(& info->bulk_insert[i]); - } - } - my_free((void *)info->bulk_insert, MYF(0)); - info->bulk_insert=0; - } - break; case HA_EXTRA_NO_ROWS: if (!share->state.header.uniques) info->opt_flag|= OPT_NO_ROWS; diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 70a1bea26bb..d39bbbf5fc7 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -801,26 +801,27 @@ static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param) } -int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size) +int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows) { MYISAM_SHARE *share=info->s; MI_KEYDEF *key=share->keyinfo; bulk_insert_param *params; - uint i, num_keys; + uint i, num_keys, total_keylength; ulonglong key_map=0; DBUG_ENTER("_mi_init_bulk_insert"); DBUG_PRINT("enter",("cache_size: %lu", cache_size)); - if (info->bulk_insert) + if (info->bulk_insert || (rows && rows < MI_MIN_ROWS_TO_USE_BULK_INSERT)) DBUG_RETURN(0); - for (i=num_keys=0 ; i < share->base.keys ; i++) + for (i=total_keylength=num_keys=0 ; i < share->base.keys ; i++) { if (!(key[i].flag & HA_NOSAME) && share->base.auto_key != i+1 && test(share->state.key_map & ((ulonglong) 1 << i))) { num_keys++; key_map |=((ulonglong) 1 << i); + total_keylength+=key[i].maxlength+TREE_ELEMENT_EXTRA_SIZE; } } @@ -828,6 +829,11 @@ int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size) num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size) DBUG_RETURN(0); + if (rows && rows*total_keylength < cache_size) + cache_size=rows; + else + cache_size/=total_keylength*16; + info->bulk_insert=(TREE *) my_malloc((sizeof(TREE)*share->base.keys+ sizeof(bulk_insert_param)*num_keys),MYF(0)); @@ -836,7 +842,7 @@ int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size) DBUG_RETURN(HA_ERR_OUT_OF_MEM); params=(bulk_insert_param *)(info->bulk_insert+share->base.keys); - for (i=0 ; i < share->base.keys ; i++,key++) + for (i=0 ; i < share->base.keys ; i++) { if (test(key_map & ((ulonglong) 1 << i))) { @@ -844,8 +850,8 @@ int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size) params->keynr=i; /* Only allocate a 16'th of the buffer at a time */ init_tree(&info->bulk_insert[i], - cache_size / num_keys / 16 + 10, - cache_size / num_keys, 0, + cache_size * key[i].maxlength, + cache_size * key[i].maxlength, 0, (qsort_cmp2)keys_compare, 0, (tree_element_free) keys_free, (void *)params++); } @@ -855,3 +861,30 @@ int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size) DBUG_RETURN(0); } + +void mi_flush_bulk_insert(MI_INFO *info, uint inx) +{ + if (info->bulk_insert) + { + if (is_tree_inited(&info->bulk_insert[inx])) + reset_tree(&info->bulk_insert[inx]); + } +} + +void mi_end_bulk_insert(MI_INFO *info) +{ + if (info->bulk_insert) + { + uint i; + for (i=0 ; i < info->s->base.keys ; i++) + { + if (is_tree_inited(& info->bulk_insert[i])) + { + delete_tree(& info->bulk_insert[i]); + } + } + my_free((void *)info->bulk_insert, MYF(0)); + info->bulk_insert=0; + } +} + diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index f0d6f740661..07744e11e5f 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -373,6 +373,7 @@ struct st_myisam_info { #define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ #define MI_MIN_SIZE_BULK_INSERT_TREE 16384 /* this is per key */ +#define MI_MIN_ROWS_TO_USE_BULK_INSERT 100 /* The UNIQUE check is done with a hashed long key */ @@ -658,8 +659,6 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); -int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size); - /* Functions needed by mi_check */ void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...)); diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 020d6c6534f..919478c7265 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3); INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2'); explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; table type possible_keys key key_len ref rows Extra -t3 index a a 5 NULL 6 Using index; Using temporary -t2 index a a 4 NULL 5 Using index; Distinct -t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 Using where; Distinct +t1 ALL PRIMARY NULL NULL NULL 2 Using temporary +t2 ref a a 4 t1.a 1 Using index +t3 ref a a 5 t1.b 1 Using where; Using index SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; a 1 @@ -190,7 +190,7 @@ insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; table type possible_keys key key_len ref rows Extra t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary -t3 ref a a 5 t1.a 10 Using where; Using index; Distinct +t3 ref a a 5 t1.a 1 Using where; Using index; Distinct select distinct t1.a from t1,t3 where t1.a=t3.a; a 1 diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index edf109fcc93..fc1e0788087 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -135,8 +135,8 @@ id 3 show keys from t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t2 1 tig 1 ticket A NULL NULL NULL YES BTREE -t2 1 tix 1 inhalt A NULL 1 NULL YES FULLTEXT +t2 1 tig 1 ticket A 3 NULL NULL YES BTREE +t2 1 tix 1 inhalt A 1 1 NULL YES FULLTEXT show create table t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index a921d75f20a..51cd67ac832 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3239,8 +3239,8 @@ Field Type Null Key Default Extra Privileges show keys from t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE -t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE -t2 1 fld3 1 fld3 A NULL NULL NULL BTREE +t2 0 fld1 1 fld1 A 0 NULL NULL BTREE +t2 1 fld3 1 fld3 A 1199 NULL NULL BTREE drop table t4, t3, t2, t1; DO 1; DO benchmark(100,1+1),1,1; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 2c32d766a38..70548311e26 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -9,7 +9,7 @@ Table Op Msg_type Msg_text test.t1 check status Table is already up to date check table t1 changed; Table Op Msg_type Msg_text -test.t1 check status OK +test.t1 check status Table is already up to date insert into t1 values (5,5,5); check table t1 changed; Table Op Msg_type Msg_text diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 0bca8dc5890..9b06b522028 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -46,6 +46,8 @@ drop table t1; create table t1 (sid char(20), id int(2) NOT NULL auto_increment, key(sid, id)); insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL); select * from t1; +insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL); +select * from t1; drop table t1; # diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 0c472ea6a45..0560afdf068 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -685,11 +685,14 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) /* Only disable old index if the table was empty */ if (file->state->records == 0) mi_disable_non_unique_index(file,rows); - ha_myisam::extra_opt(HA_EXTRA_BULK_INSERT_BEGIN, - current_thd->variables.bulk_insert_buff_size); + else + { + mi_init_bulk_insert(file, + current_thd->variables.bulk_insert_buff_size, rows); table->bulk_insert= 1; } } + } enable_activate_all_index=1; } else @@ -704,7 +707,7 @@ bool ha_myisam::activate_all_index(THD *thd) MYISAM_SHARE* share = file->s; DBUG_ENTER("activate_all_index"); - mi_extra(file, HA_EXTRA_BULK_INSERT_END, 0); + mi_end_bulk_insert(file); table->bulk_insert= 0; if (enable_activate_all_index && share->state.key_map != set_bits(ulonglong, share->base.keys)) @@ -945,13 +948,11 @@ int ha_myisam::extra(enum ha_extra_function operation) } -/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */ +/* To be used with WRITE_CACHE and EXTRA_CACHE */ int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size) { - if ((specialflag & SPECIAL_SAFE_MODE) & - (operation == HA_EXTRA_WRITE_CACHE || - operation == HA_EXTRA_BULK_INSERT_BEGIN)) + if ((specialflag & SPECIAL_SAFE_MODE) & operation == HA_EXTRA_WRITE_CACHE) return 0; return mi_extra(file, operation, (void*) &cache_size); } @@ -1213,8 +1214,7 @@ longlong ha_myisam::get_auto_increment() } if (table->bulk_insert) - mi_extra(file, HA_EXTRA_BULK_INSERT_FLUSH, - (void*) &table->next_number_index); + mi_flush_bulk_insert(file, table->next_number_index); longlong nr; int error; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 07683dca73e..f2c3d1a7747 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -247,9 +247,7 @@ int ha_myisammrg::extra(enum ha_extra_function operation) int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) { - if ((specialflag & SPECIAL_SAFE_MODE) & - (operation == HA_EXTRA_WRITE_CACHE || - operation == HA_EXTRA_BULK_INSERT_BEGIN)) + if ((specialflag & SPECIAL_SAFE_MODE) & operation == HA_EXTRA_WRITE_CACHE) return 0; return myrg_extra(file, operation, (void*) &cache_size); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5ca08aa31b0..4d1b2e59f60 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -105,7 +105,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, int error; bool log_on= ((thd->options & OPTION_UPDATE_LOG) || !(thd->master_access & SUPER_ACL)); - bool transactional_table, log_delayed, bulk_insert=0; + bool transactional_table, log_delayed, bulk_insert; uint value_count; ulong counter = 1; ulonglong id; @@ -187,21 +187,16 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, thd->proc_info="update"; if (duplic == DUP_IGNORE || duplic == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - if ((bulk_insert= (values_list.elements >= MIN_ROWS_TO_USE_BULK_INSERT && - lock_type != TL_WRITE_DELAYED && - !(specialflag & SPECIAL_SAFE_MODE)))) + if ((lock_type != TL_WRITE_DELAYED && !(specialflag & SPECIAL_SAFE_MODE))) { table->file->extra_opt(HA_EXTRA_WRITE_CACHE, min(thd->variables.read_buff_size, table->avg_row_length*values_list.elements)); - if (thd->variables.bulk_insert_buff_size) - table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN, - min(thd->variables.bulk_insert_buff_size, - (table->total_key_length + - table->keys * TREE_ELEMENT_EXTRA_SIZE)* - values_list.elements)); - table->bulk_insert= 1; + table->file->deactivate_non_unique_index(values_list.elements); + bulk_insert=1; } + else + bulk_insert=0; while ((values= its++)) { @@ -278,7 +273,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, error=1; } } - if (table->file->extra(HA_EXTRA_BULK_INSERT_END)) + if (table->file->activate_all_index(thd)) { if (!error) { @@ -286,7 +281,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, error=1; } } - table->bulk_insert= 0; } if (id && values_list.elements != 1) thd->insert_id(id); // For update log From 127d01dd016aeb4b90689219d13b67075e21b8bb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 00:06:05 +0100 Subject: [PATCH 08/61] ANALYZE for MERGE --- include/myisammrg.h | 2 ++ myisammrg/myrg_info.c | 17 ++++++++--------- myisammrg/myrg_open.c | 22 ++++++++++++++++++---- sql/ha_myisammrg.cc | 7 +++++++ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/include/myisammrg.h b/include/myisammrg.h index c3b3b39424b..ea882450eef 100644 --- a/include/myisammrg.h +++ b/include/myisammrg.h @@ -51,6 +51,7 @@ typedef struct st_mymerge_info /* Struct from h_info */ uint reclength; /* Recordlength */ int errkey; /* With key was dupplicated on err */ uint options; /* HA_OPTION_... used */ + ulong *rec_per_key; /* for sql optimizing */ } MYMERGE_INFO; typedef struct st_myrg_table_info @@ -71,6 +72,7 @@ typedef struct st_myrg_info my_bool cache_in_use; LIST open_list; QUEUE by_key; + ulong *rec_per_key_part; /* for sql optimizing */ } MYRG_INFO; diff --git a/myisammrg/myrg_info.c b/myisammrg/myrg_info.c index 14bc228cc1f..ba840ac444b 100644 --- a/myisammrg/myrg_info.c +++ b/myisammrg/myrg_info.c @@ -28,8 +28,6 @@ ulonglong myrg_position(MYRG_INFO *info) ~(ulonglong) 0; } - /* If flag != 0 one only gets pos of last record */ - int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) { MYRG_TABLE *current_table; @@ -55,15 +53,16 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) DBUG_PRINT("info2",("table: %s, offset: %lu", file->table->filename,(ulong) file->file_offset)); } - x->records = info->records; - x->deleted = info->del; - x->data_file_length = info->data_file_length; - x->reclength = info->reclength; - x->options = info->options; + x->records= info->records; + x->deleted= info->del; + x->data_file_length= info->data_file_length; + x->reclength= info->reclength; + x->options= info->options; if (current_table) - x->errkey = current_table->table->errkey; + x->errkey= current_table->table->errkey; else - x->errkey=0; + x->errkey= 0; + x->rec_per_key = info->rec_per_key_part; } DBUG_RETURN(0); } diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 9360f582958..6a3c8dd86d9 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -32,8 +32,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { - int save_errno,i,errpos; - uint files,dir_length,length,options; + int save_errno,i,j,errpos; + uint files,dir_length,length,options, key_parts; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO info,*m_info; @@ -89,13 +89,25 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) } info.reclength=isam->s->base.reclength; } + key_parts=(isam ? isam->s->base.key_parts : 0); if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+ - files*sizeof(MYRG_TABLE), + files*sizeof(MYRG_TABLE)+ + sizeof(long)*key_parts, MYF(MY_WME)))) goto err; *m_info=info; - m_info->open_tables=(files) ? (MYRG_TABLE *) (m_info+1) : 0; m_info->tables=files; + if (files) + { + m_info->open_tables=(MYRG_TABLE *) (m_info+1); + m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files); + bzero((char*) m_info->rec_per_key_part,sizeof(long)*key_parts); + } + else + { + m_info->open_tables=0; + m_info->rec_per_key_part=0; + } errpos=2; options= (uint) ~0; @@ -107,6 +119,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->records+=isam->state->records; m_info->del+=isam->state->del; m_info->data_file_length+=isam->state->data_file_length; + for (j=0; j < key_parts; j++) + m_info->rec_per_key_part[j]+=isam->s->state.rec_per_key_part[j] / files; if (i) isam=(MI_INFO*) (isam->open_list.next->data); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index f2c3d1a7747..efebeb8b46d 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -229,6 +229,13 @@ void ha_myisammrg::info(uint flag) #else ref_length=4; // Can't be > than my_off_t #endif + if (flag & HA_STATUS_CONST) + { + if (table->key_parts) + memcpy((char*) table->key_info[0].rec_per_key, + (char*) info.rec_per_key, + sizeof(table->key_info[0].rec_per_key)*table->key_parts); + } } From 181537e9248196e94323c138f7fc7c503d2c8c41 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 00:07:25 +0100 Subject: [PATCH 09/61] incorrect bugfix removed. EQ+BETWEEN still cannot be optimized :( --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c4bc10a8b2a..1e70064b4a1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1267,7 +1267,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, select->quick=0; if (records != HA_POS_ERROR) { - s->records=s->found_records=records; + s->found_records=records; s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); } } From 37a02e4ce45ec6947f0aac5c3bdbce7be46beeac Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 04:17:31 -0400 Subject: [PATCH 10/61] Update Windows binaries prefix according MySQL Pro release package sql/mysqld.cc: With the introduction of Pro release version the InnoDB table engine was added for all binaries and not more define only the max package --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6aa41f9f800..0895013c37e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -184,12 +184,12 @@ static char **opt_argv; #ifdef __WIN__ #undef MYSQL_SERVER_SUFFIX #ifdef __NT__ -#if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) +#if defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max-nt" #else #define MYSQL_SERVER_SUFFIX "-nt" #endif /* ...DB */ -#elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) +#elif defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max" #else #define MYSQL_SERVER_SUFFIX "" From 10bde0b61cbbc84f0ee4a1b6412c357f25db61e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 14:25:23 +0100 Subject: [PATCH 11/61] - make sure to replace HOSTNAME in mysql.server when packing up the binary distribution (this will still be broken for 3.23.54) - make sure that mysql.server in the binary distribution is executable, too --- scripts/make_binary_distribution.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index bde77713d63..d8d34229b70 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -120,11 +120,11 @@ $CP scripts/* $BASE/bin rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh $BASE/bin/mysql_install_db $BASE/bin/make_binary_distribution $BASE/bin/setsomevars $BASE/support-files/Makefile* $BASE/support-files/*.sh $BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db -$BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server +$BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server $BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/safe_mysqld mv $BASE/support-files/binary-configure $BASE/configure -chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-* $BASE/configure +chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-* $BASE/support-files/mysql.server $BASE/configure $CP -r sql-bench/* $BASE/sql-bench rm -f $BASE/sql-bench/*.sh $BASE/sql-bench/Makefile* $BASE/lib/*.la From 89991c65f3327f33f11b81c23914dfad57c4002d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 18:40:38 +0500 Subject: [PATCH 12/61] merge Ranger's patches to crash-me, add new tests ( DEFAULT VALUES ) to crash-me sql-bench/crash-me.sh: new tests: - INSERT with DEFAULT: - INSERT with empty value list: - Insert DEFAULT VALUES; ------- -checking of reserved keywords (by courtesy of Ranger) -------- - added "--suffix" option - added description of "--config-file" to help section - fixed test for DIFFERENCE() - fixed small bug in safe_query_result (was s/,/,/ should s/,/./) (by courtesy of Ranger) sql-bench/server-cfg.sh: remove "KERNEL" and add "SAPDB" to sapdb version BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql-bench/crash-me.sh | 267 ++++++++++++++++++++++++++++++++++++++- sql-bench/server-cfg.sh | 3 +- 3 files changed, 266 insertions(+), 5 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index f4174cc2fbf..5c9df32641b 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -86,6 +86,7 @@ tonu@x153.internalnet tonu@x3.internalnet venu@work.mysql.com vva@genie.(none) +walrus@kishkin.ru walrus@mysql.com worm@altair.is.lan zak@balfor.local diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index 6c3ee9bd0dc..d18070d30b7 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -55,6 +55,7 @@ $opt_check_server=0; # Check if server is alive before each query $opt_sleep=10; # time to sleep while starting the db server $limit_changed=0; # For configure file $reconnect_count=0; +$opt_suffix=""; $opt_comment=$opt_config_file=$opt_log_queries_to_file=""; $limits{'crash_me_safe'}='yes'; $prompts{'crash_me_safe'}='crash me safe'; @@ -62,10 +63,13 @@ $limits{'operating_system'}= machine(); $prompts{'operating_system'}='crash-me tested on'; $retry_limit=3; -GetOptions("Information","help","server=s","debug","user=s","password=s","database=s","restart","force","quick","log-all-queries","comment=s","host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","batch-mode","config-file=s","log-queries-to-file=s","check-server") || usage(); +GetOptions("Information","help","server=s","debug","user=s","password=s","database=s","restart","force","quick","log-all-queries","comment=s","host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s","batch-mode","config-file=s","log-queries-to-file=s","check-server") || usage(); usage() if ($opt_help || $opt_Information); -$opt_config_file="$pwd/$opt_dir/$opt_server.cfg" if (length($opt_config_file) == 0); +$opt_suffix = '-'.$opt_suffix if (length($opt_suffix) == 0); +$opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg" if (length($opt_config_file) == 0); + +#!!! if ($opt_fix_limit_file) { @@ -298,6 +302,21 @@ report("INSERT with set syntax",'insert_with_set', "create table crash_q (a integer)", "insert into crash_q SET a=1", "drop table crash_q $drop_attr"); +report("INSERT with DEFAULT","insert_with_default", + "create table crash_me_q (a int)", + "insert into crash_me_q (a) values (DEFAULT)", + "drop table crash_me_q $drop_attr"); + +report("INSERT with empty value list","insert_with_empty_value_list", + "create table crash_me_q (a int)", + "insert into crash_me_q (a) values ()", + "drop table crash_me_q $drop_attr"); + +report("INSERT DEFAULT VALUES","insert_default_values", + "create table crash_me_q (a int)", + "insert into crash_me_q DEFAULT VALUES", + "drop table crash_me_q $drop_attr"); + report("allows end ';'","end_colon", "select * from crash_me;"); try_and_report("LIMIT number of rows","select_limit", ["with LIMIT", @@ -553,6 +572,13 @@ if (!defined($limits{'query_size'})) $query_size=$limits{'query_size'}; print "$limits{'query_size'}\n"; + +# +# Check for reserved words +# + +check_reserved_words($dbh); + # # Test database types # @@ -794,7 +820,7 @@ try_and_report("Automatic row id", "automatic_rowid", (["ASCII", "ascii", "ASCII('A')","65",0], ["CHAR", "char", "CHAR(65)" ,"A",1], ["CONCAT(2 arg)","concat", "concat('a','b')","ab",1], - ["DIFFERENCE()","difference","difference('abc','abe')",0,2], + ["DIFFERENCE()","difference","difference('abc','abe')",3,0], ["INSERT","insert","insert('abcd',2,2,'ef')","aefd",1], ["LEFT","left","left('abcd',2)","ab",1], ["LTRIM","ltrim","ltrim(' abcd')","abcd",1], @@ -2332,6 +2358,9 @@ $0 takes the following options: --batch-mode Don\'t ask any questions, quit on errors. +--config-file='filename' + Read limit results from specific file + --comment='some comment' Add this comment to the crash-me limit file @@ -2379,6 +2408,10 @@ $0 takes the following options: Known servers names are: Access, Adabas, AdabasD, Empress, Oracle, Informix, DB2, Mimer, mSQL, MS-SQL, MySQL, Pg, Solid or Sybase. For others $0 can\'t report the server version. +--suffix='suffix' (Default '') + Add suffix to the output filename. For instance if you run crash-me like "crash-me --suffix="myisam", + then output filename will look "mysql-myisam.cfg". + --user='user_name' User name to log into the SQL server. @@ -2687,6 +2720,228 @@ sub safe_query return $ok; } +sub check_reserved_words +{ + my ($dbh)= @_; + + my $answer, $prompt, $config, $keyword_type; + + my @keywords_type = ( "(ANSI SQL 92/99)", "(ANSI SQL 92)", "(ANSI SQL 99)", "(EXTRA)"); + my @keywords_ext = ( "ansi92/99", "ansi92", "ansi99", "extra"); + + my %reserved_words = ( + ABSOLUTE => 0, ACTION => 0, ADD => 0, + AFTER => 0, ALIAS => 0, ALL => 0, + ALLOCATE => 0, ALTER => 0, AND => 0, + ANY => 0, ARE => 0, AS => 0, + ASC => 0, ASSERTION => 0, AT => 0, + AUTHORIZATION => 0, BEFORE => 0, BEGIN => 0, + BIT => 0, BOOLEAN => 0, BOTH => 0, + BREADTH => 0, BY => 0, CALL => 0, + CASCADE => 0, CASCADED => 0, CASE => 0, + CAST => 0, CATALOG => 0, CHAR => 0, + CHARACTER => 0, CHECK => 0, CLOSE => 0, + COLLATE => 0, COLLATION => 0, COLUMN => 0, + COMMIT => 0, COMPLETION => 0, CONNECT => 0, + CONNECTION => 0, CONSTRAINT => 0, CONSTRAINTS => 0, + CONTINUE => 0, CORRESPONDING => 0, CREATE => 0, + CROSS => 0, CURRENT => 0, CURRENT_DATE => 0, + CURRENT_TIME => 0, CURRENT_TIMESTAMP => 0, CURRENT_USER => 0, + CURSOR => 0, CYCLE => 0, DATA => 0, + DATE => 0, DAY => 0, DEALLOCATE => 0, + DEC => 0, DECIMAL => 0, DECLARE => 0, + DEFAULT => 0, DEFERRABLE => 0, DEFERRED => 0, + DELETE => 0, DEPTH => 0, DESC => 0, + DESCRIBE => 0, DESCRIPTOR => 0, DIAGNOSTICS => 0, + DICTIONARY => 0, DISCONNECT => 0, DISTINCT => 0, + DOMAIN => 0, DOUBLE => 0, DROP => 0, + EACH => 0, ELSE => 0, ELSEIF => 0, + END => 0, END-EXEC => 0, EQUALS => 0, + ESCAPE => 0, EXCEPT => 0, EXCEPTION => 0, + EXEC => 0, EXECUTE => 0, EXTERNAL => 0, + FALSE => 0, FETCH => 0, FIRST => 0, + FLOAT => 0, FOR => 0, FOREIGN => 0, + FOUND => 0, FROM => 0, FULL => 0, + GENERAL => 0, GET => 0, GLOBAL => 0, + GO => 0, GOTO => 0, GRANT => 0, + GROUP => 0, HAVING => 0, HOUR => 0, + IDENTITY => 0, IF => 0, IGNORE => 0, + IMMEDIATE => 0, IN => 0, INDICATOR => 0, + INITIALLY => 0, INNER => 0, INPUT => 0, + INSERT => 0, INT => 0, INTEGER => 0, + INTERSECT => 0, INTERVAL => 0, INTO => 0, + IS => 0, ISOLATION => 0, JOIN => 0, + KEY => 0, LANGUAGE => 0, LAST => 0, + LEADING => 0, LEAVE => 0, LEFT => 0, + LESS => 0, LEVEL => 0, LIKE => 0, + LIMIT => 0, LOCAL => 0, LOOP => 0, + MATCH => 0, MINUTE => 0, MODIFY => 0, + MODULE => 0, MONTH => 0, NAMES => 0, + NATIONAL => 0, NATURAL => 0, NCHAR => 0, + NEW => 0, NEXT => 0, NO => 0, + NONE => 0, NOT => 0, NULL => 0, + NUMERIC => 0, OBJECT => 0, OF => 0, + OFF => 0, OLD => 0, ON => 0, + ONLY => 0, OPEN => 0, OPERATION => 0, + OPTION => 0, OR => 0, ORDER => 0, + OUTER => 0, OUTPUT => 0, PAD => 0, + PARAMETERS => 0, PARTIAL => 0, PRECISION => 0, + PREORDER => 0, PREPARE => 0, PRESERVE => 0, + PRIMARY => 0, PRIOR => 0, PRIVILEGES => 0, + PROCEDURE => 0, PUBLIC => 0, READ => 0, + REAL => 0, RECURSIVE => 0, REF => 0, + REFERENCES => 0, REFERENCING => 0, RELATIVE => 0, + RESIGNAL => 0, RESTRICT => 0, RETURN => 0, + RETURNS => 0, REVOKE => 0, RIGHT => 0, + ROLE => 0, ROLLBACK => 0, ROUTINE => 0, + ROW => 0, ROWS => 0, SAVEPOINT => 0, + SCHEMA => 0, SCROLL => 0, SEARCH => 0, + SECOND => 0, SECTION => 0, SELECT => 0, + SEQUENCE => 0, SESSION => 0, SESSION_USER => 0, + SET => 0, SIGNAL => 0, SIZE => 0, + SMALLINT => 0, SOME => 0, SPACE => 0, + SQL => 0, SQLEXCEPTION => 0, SQLSTATE => 0, + SQLWARNING => 0, STRUCTURE => 0, SYSTEM_USER => 0, + TABLE => 0, TEMPORARY => 0, THEN => 0, + TIME => 0, TIMESTAMP => 0, TIMEZONE_HOUR => 0, + TIMEZONE_MINUTE => 0, TO => 0, TRAILING => 0, + TRANSACTION => 0, TRANSLATION => 0, TRIGGER => 0, + TRUE => 0, UNDER => 0, UNION => 0, + UNIQUE => 0, UNKNOWN => 0, UPDATE => 0, + USAGE => 0, USER => 0, USING => 0, + VALUE => 0, VALUES => 0, VARCHAR => 0, + VARIABLE => 0, VARYING => 0, VIEW => 0, + WHEN => 0, WHENEVER => 0, WHERE => 0, + WHILE => 0, WITH => 0, WITHOUT => 0, + WORK => 0, WRITE => 0, YEAR => 0, + ZONE => 0, + + ASYNC => 1, AVG => 1, BETWEEN => 1, + BIT_LENGTH => 1, CHARACTER_LENGTH => 1, CHAR_LENGTH => 1, + COALESCE => 1, CONVERT => 1, COUNT => 1, + EXISTS => 1, EXTRACT => 1, INSENSITIVE => 1, + LOWER => 1, MAX => 1, MIN => 1, + NULLIF => 1, OCTET_LENGTH => 1, OID => 1, + OPERATORS => 1, OTHERS => 1, OVERLAPS => 1, + PENDANT => 1, POSITION => 1, PRIVATE => 1, + PROTECTED => 1, REPLACE => 1, SENSITIVE => 1, + SIMILAR => 1, SQLCODE => 1, SQLERROR => 1, + SUBSTRING => 1, SUM => 1, TEST => 1, + THERE => 1, TRANSLATE => 1, TRIM => 1, + TYPE => 1, UPPER => 1, VIRTUAL => 1, + VISIBLE => 1, WAIT => 1, + + ADMIN => 2, AGGREGATE => 2, ARRAY => 2, + BINARY => 2, BLOB => 2, CLASS => 2, + CLOB => 2, CONDITION => 2, CONSTRUCTOR => 2, + CONTAINS => 2, CUBE => 2, CURRENT_PATH => 2, + CURRENT_ROLE => 2, DATALINK => 2, DEREF => 2, + DESTROY => 2, DESTRUCTOR => 2, DETERMINISTIC => 2, + DO => 2, DYNAMIC => 2, EVERY => 2, + EXIT => 2, EXPAND => 2, EXPANDING => 2, + FREE => 2, FUNCTION => 2, GROUPING => 2, + HANDLER => 2, HAST => 2, HOST => 2, + INITIALIZE => 2, INOUT => 2, ITERATE => 2, + LARGE => 2, LATERAL => 2, LOCALTIME => 2, + LOCALTIMESTAMP => 2, LOCATOR => 2, MEETS => 2, + MODIFIES => 2, NCLOB => 2, NORMALIZE => 2, + ORDINALITY => 2, OUT => 2, PARAMETER => 2, + PATH => 2, PERIOD => 2, POSTFIX => 2, + PRECEDES => 2, PREFIX => 2, READS => 2, + REDO => 2, REPEAT => 2, RESULT => 2, + ROLLUP => 2, SETS => 2, SPECIFIC => 2, + SPECIFICTYPE => 2, START => 2, STATE => 2, + STATIC => 2, SUCCEEDS => 2, TERMINATE => 2, + THAN => 2, TREAT => 2, UNDO => 2, + UNTIL => 2, + + ANALYZE => 3, AUTO_INCREMENT => 3, BDB => 3, + BERKELEYDB => 3, BIGINT => 3, BTREE => 3, + CHANGE => 3, COLUMNS => 3, DATABASE => 3, + DATABASES => 3, DAY_HOUR => 3, DAY_MINUTE => 3, + DAY_SECOND => 3, DELAYED => 3, DISTINCTROW => 3, + ENCLOSED => 3, ERRORS => 3, ESCAPED => 3, + EXPLAIN => 3, FIELDS => 3, FULLTEXT => 3, + GEOMETRY => 3, HASH => 3, HIGH_PRIORITY => 3, + HOUR_MINUTE => 3, HOUR_SECOND => 3, INDEX => 3, + INFILE => 3, INNODB => 3, KEYS => 3, + KILL => 3, LINES => 3, LOAD => 3, + LOCK => 3, LONG => 3, LONGBLOB => 3, + LONGTEXT => 3, LOW_PRIORITY => 3, MASTER_SERVER_ID => 3, + MEDIUMBLOB => 3, MEDIUMINT => 3, MEDIUMTEXT => 3, + MIDDLEINT => 3, MINUTE_SECOND => 3, MRG_MYISAM => 3, + OPTIMIZE => 3, OPTIONALLY => 3, OUTFILE => 3, + PURGE => 3, REGEXP => 3, RENAME => 3, + REQUIRE => 3, RLIKE => 3, RTREE => 3, + SHOW => 3, SONAME => 3, SPATIAL => 3, + SQL_BIG_RESULT => 3,SQL_CALC_FOUND_ROWS => 3, SQL_SMALL_RESULT => 3, + SSL => 3, STARTING => 3, STRAIGHT_JOIN => 3, + STRIPED => 3, TABLES => 3, TERMINATED => 3, + TINYBLOB => 3, TINYINT => 3, TINYTEXT => 3, + TYPES => 3, UNLOCK => 3, UNSIGNED => 3, + USE => 3, USER_RESOURCES => 3, VARBINARY => 3, + WARNINGS => 3, XOR => 3, YEAR_MONTH => 3, + ZEROFILL => 3, + + BACKUP => 3, BREAK => 3, BROWSE => 3, + BULK => 3, CHECKPOINT => 3, CLUSTERED => 3, + COMPUTE => 3, CONTAINSTABLE => 3, DBCC => 3, + DENY => 3, DISK => 3, DISTRIBUTED => 3, + DUMMY => 3, DUMP => 3, ERRLVL => 3, + FILE => 3, FILLFACTOR => 3, FREETEXT => 3, + FREETEXTTABLE => 3, HOLDLOCK => 3, IDENTITYCOL => 3, + IDENTITY_INSERT => 3, LINENO => 3, NOCHECK => 3, + NONCLUSTERED => 3, OFFSETS => 3, OPENDATASOURCE => 3, + OPENQUERY => 3, OPENROWSET => 3, OPENXML => 3, + OVER => 3, PERCENT => 3, PLAN => 3, + PRINT => 3, PROC => 3, RAISERROR => 3, + READTEXT => 3, RECONFIGURE => 3, REPLICATION => 3, + RESTORE => 3, ROWCOUNT => 3, ROWGUIDCOL => 3, + RULE => 3, SAVE => 3, SETUSER => 3, + SHUTDOWN => 3, STATISTICS => 3, TEXTSIZE => 3, + TOP => 3, TRAN => 3, TRUNCATE => 3, + TSEQUAL => 3, UPDATETEXT => 3, WAITFOR => 3, + WRITETEXT => 3, + + ACCESS => 3, AUDIT => 3, CLUSTER => 3, + COMMENT => 3, COMPRESS => 3, EXCLUSIVE => 3, + IDENTIFIED => 3, INCREMENT => 3, INITIAL => 3, + MAXEXTENTS => 3, MINUS => 3, MLSLABEL => 3, + MODE => 3, NOAUDIT => 3, NOCOMPRESS => 3, + NOWAIT => 3, NUMBER => 3, OFFLINE => 3, + ONLINE => 3, PCTFREE => 3, RAW => 3, + RESOURCE => 3, ROWID => 3, ROWNUM => 3, + SHARE => 3, SUCCESSFUL => 3, SYNONYM => 3, + SYSDATE => 3, UID => 3, VALIDATE => 3, + VARCHAR2 => 3 + ); + + $dbh->do("drop table crash_me10"); + $dbh->do("create table crash_me10 (id int not null)") or warn "$dbh->errstr\n"; + $dbh->{RaiseError}= 1; + + foreach my $keyword (keys %reserved_words) + { + + $keyword_type= $reserved_words{$keyword}; + + $prompt= "Reserved keyword ".$keyword." ".$keywords_type[$keyword_type]; + $config= "reserved_word_".$keywords_ext[$keyword_type]."_".lc($keyword); + + eval { + $dbh->do("alter table crash_me10 add column $keyword int not null"); + }; + + $answer= ($@) ? "yes" : "no"; + + save_config_data($config,$answer,$prompt); + + print "$prompt: ",$limits{$config},"\n"; + + } + + $dbh->{RaiseError}= 0; +} # # Do a query on a query package object. @@ -3007,9 +3262,13 @@ sub safe_query_result } $result=0; # Ok $last_result= $row->[0]; # Save for report_result; + + # Note: + # if ($result_type == 2) We accept any return value as answer + if ($result_type == 0) # Compare numbers { - $row->[0] =~ s/,/,/; # Fix if ',' is used instead of '.' + $row->[0] =~ s/,/./; # Fix if ',' is used instead of '.' if ($row->[0] != $answer && (abs($row->[0]- $answer)/ (abs($row->[0]) + abs($answer))) > 0.01) { diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index 7f96c06ef99..533e7aea574 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -3470,7 +3470,8 @@ sub version if ($sth->execute && (@row = $sth->fetchrow_array) && $row[0] =~ /([\d\.]+)/) { - $version="sap-db $1"; + $version=$row[0]; + $verson =~ s/KERNEL/SAP DB/i; } $sth->finish; $dbh->disconnect; From 448644dc6bdd0abb71fe3b7dfc8ec5c20365f027 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 19:09:56 +0500 Subject: [PATCH 13/61] SCRUM task - cleanup interbase section in the server-cfg sql-bench/server-cfg.sh: clean-up interbase section corrected misprint in DSN, creating indexes,version(), and fields conversations. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql-bench/server-cfg.sh | 39 +++++++++++++++++---------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index f4174cc2fbf..5c9df32641b 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -86,6 +86,7 @@ tonu@x153.internalnet tonu@x3.internalnet venu@work.mysql.com vva@genie.(none) +walrus@kishkin.ru walrus@mysql.com worm@altair.is.lan zak@balfor.local diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index 7f96c06ef99..c8c298ef1a7 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -2985,7 +2985,7 @@ sub new bless $self; $self->{'cmp_name'} = "interbase"; - $self->{'data_source'} = "DBI:InterBase:database=$database:ib_dialect=3"; + $self->{'data_source'} = "DBI:InterBase:database=$database;ib_dialect=3"; $self->{'limits'} = \%limits; $self->{'blob'} = "blob"; $self->{'text'} = ""; @@ -3000,7 +3000,7 @@ sub new $limits{'max_tables'} = 65000; # Should be big enough $limits{'max_text_size'} = 15000; # Max size with default buffers. $limits{'query_size'} = 1000000; # Max size with default buffers. - $limits{'max_index'} = 31; # Max number of keys + $limits{'max_index'} = 65000; # Max number of keys $limits{'max_index_parts'} = 8; # Max segments/key $limits{'max_column_name'} = 128; # max table and column name @@ -3050,16 +3050,13 @@ sub new sub version { my ($self)=@_; - my ($dbh,$sth,$version,@row); - + my ($dbh,$version); + + $version='Interbase ?'; + $dbh=$self->connect(); -# $sth = $dbh->prepare("show version"); -# $sth->execute; -# @row = $sth->fetchrow_array; -# $version = $row[0]; -# $version =~ s/.*version \"(.*)\"$/$1/; + eval { $version = $dbh->func('version','ib_database_info')->{'version'}; }; $dbh->disconnect; - $version = "6.0Beta"; $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/); return $version; } @@ -3090,36 +3087,34 @@ sub connect sub create { my($self,$table_name,$fields,$index,$options) = @_; - my($query,@queries); + my($query,@queries,@keys,@indexes); $query="create table $table_name ("; foreach $field (@$fields) { - $field =~ s/ big_decimal/ float/i; - $field =~ s/ double/ float/i; + $field =~ s/ big_decimal/ decimal/i; + $field =~ s/ double/ double precision/i; $field =~ s/ tinyint/ smallint/i; - $field =~ s/ mediumint/ int/i; - $field =~ s/ integer/ int/i; + $field =~ s/ mediumint/ integer/i; + $field =~ s/\bint\b/integer/i; $field =~ s/ float\(\d,\d\)/ float/i; - $field =~ s/ date/ int/i; # Because of tcp ? $field =~ s/ smallint\(\d\)/ smallint/i; - $field =~ s/ int\(\d\)/ int/i; + $field =~ s/ integer\(\d\)/ integer/i; $query.= $field . ','; } foreach $ind (@$index) { - my @index; - if ( $ind =~ /\bKEY\b/i ){ + if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){ push(@keys,"ALTER TABLE $table_name ADD $ind"); }else{ - my @fields = split(' ',$index); + my @fields = split(' ',$ind); my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]"; - push(@index,$query); + push(@indexes,$query); } } substr($query,-1)=")"; # Remove last ','; $query.=" $options" if (defined($options)); - push(@queries,$query); + push(@queries,$query,@keys,@indexes); return @queries; } From 5fcd6ce31e2bdc0ebf5106ca27f96a11294d7209 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Dec 2002 21:38:00 +0100 Subject: [PATCH 14/61] order_by.result, key_diff.result: updated mysql-test/r/key_diff.result: updated mysql-test/r/order_by.result: updated --- mysql-test/r/key_diff.result | 2 +- mysql-test/r/order_by.result | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result index 4eaccc696f9..f8671639e2c 100644 --- a/mysql-test/r/key_diff.result +++ b/mysql-test/r/key_diff.result @@ -36,7 +36,7 @@ a a a a explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B; table type possible_keys key key_len ref rows Extra t1 ALL a NULL NULL NULL 5 -t2 ALL b NULL NULL NULL 5 Using where +t2 ref b b 4 t1.a 1 Using where select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a; a b a b A B a a diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 48773bfa916..62a42150eb3 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -450,9 +450,9 @@ gid sid uid 103853 5 250 EXPLAIN select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t1.gid, t3.uid; table type possible_keys key key_len ref rows Extra -t1 index PRIMARY PRIMARY 4 NULL 6 Using index -t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1 -t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 Using where; Using index +t3 index PRIMARY PRIMARY 2 NULL 6 Using index; Using temporary; Using filesort +t2 ref PRIMARY,uid uid 2 t3.uid 1 Using where +t1 eq_ref PRIMARY PRIMARY 4 t2.gid 1 Using index EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t1.gid,t3.skr; table type possible_keys key key_len ref rows Extra t1 index PRIMARY PRIMARY 4 NULL 6 Using index From f3b563df037353a7228a30276fc5b7a49ce565b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 12:44:17 +0200 Subject: [PATCH 15/61] Fixed rare bug in show processlist which could cause core dump if a new thread was connecting. sql/sql_show.cc: Fixed rare bug in show processlist which could cause core dump if a new thread was connecting. (We where calling mutex_unlock() without having ever called mutex_lock) sql/sql_udf.cc: Fixed warning from valgrind --- sql/sql_show.cc | 12 +++++++----- sql/sql_udf.cc | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 12979f77e56..a6285cfacd0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1025,6 +1025,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) THD *tmp; while ((tmp=it++)) { + struct st_my_thread_var *mysys_var; if ((tmp->net.vio || tmp->system_thread) && (!user || (tmp->user && !strcmp(tmp->user,user)))) { @@ -1034,12 +1035,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->user=thd->strdup(tmp->user ? tmp->user : (tmp->system_thread ? "system user" : "unauthenticated user")); thd_info->host=thd->strdup(tmp->host ? tmp->host : (tmp->ip ? tmp->ip : - (tmp->system_thread ? "none" : "connecting host"))); + (tmp->system_thread ? "none" : + "connecting host"))); if ((thd_info->db=tmp->db)) // Safe test thd_info->db=thd->strdup(thd_info->db); thd_info->command=(int) tmp->command; - if (tmp->mysys_var) - pthread_mutex_lock(&tmp->mysys_var->mutex); + if ((mysys_var= tmp->mysys_var)) + pthread_mutex_lock(&mysys_var->mutex); thd_info->proc_info= (char*) (tmp->killed ? "Killed" : 0); thd_info->state_info= (char*) (tmp->locked ? "Locked" : tmp->net.reading_or_writing ? @@ -1051,8 +1053,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) tmp->mysys_var && tmp->mysys_var->current_cond ? "Waiting on cond" : NullS); - if (tmp->mysys_var) - pthread_mutex_unlock(&tmp->mysys_var->mutex); + if (mysys_var) + pthread_mutex_unlock(&mysys_var->mutex); #if !defined(DONT_USE_THR_ALARM) && ! defined(SCO) if (pthread_kill(tmp->real_id,0)) diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 5705dccd8d0..82a5e5bc002 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -204,6 +204,8 @@ void udf_init() new_thd->version--; // Force close to free memory close_thread_tables(new_thd); delete new_thd; + /* Remember that we don't have a THD */ + my_pthread_setspecific_ptr(THR_THD, 0); DBUG_VOID_RETURN; } From 49162e0e54c085ecefb6893a5bd662e4f7b2f56a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 12:59:55 +0200 Subject: [PATCH 16/61] Added back -max to server name if we are using InnoDB. libmysql/libmysql.c: Compatibility fix sql/mysqld.cc: Added back -max if we are using InnoDB. (This should not be done in the 3.23 version) --- libmysql/libmysql.c | 4 ++-- sql/mysqld.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 9db1e1c9ab9..755d85dd04a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -939,7 +939,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, else { cur->data[field] = to; - if (len > end_to - to) + if (len > (ulong) (end_to - to)) { free_rows(result); net->last_errno=CR_UNKNOWN_ERROR; @@ -998,7 +998,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) } else { - if (len > end_pos - pos) + if (len > (ulong) (end_pos - pos)) { mysql->net.last_errno=CR_UNKNOWN_ERROR; strmov(mysql->net.last_error,ER(mysql->net.last_errno)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0895013c37e..17cf8f79646 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -184,17 +184,17 @@ static char **opt_argv; #ifdef __WIN__ #undef MYSQL_SERVER_SUFFIX #ifdef __NT__ -#if defined(HAVE_BERKELEY_DB) +#if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max-nt" #else #define MYSQL_SERVER_SUFFIX "-nt" #endif /* ...DB */ -#elif defined(HAVE_BERKELEY_DB) +#elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max" #else #define MYSQL_SERVER_SUFFIX "" #endif /* __NT__ */ -#endif +#endif /* __WIN__ */ #ifdef HAVE_BERKELEY_DB SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES; From 934f5cc4662ded62609ce64be15c54d327cc554e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 15:46:39 +0200 Subject: [PATCH 17/61] Ensure that BEGIN / COMMIT is handled properly if slave dies Added syntax support for CREATE TABLE foo (a char CHARACTER SET latin1) CHARSET=latin1; Docs/internals.texi: Update binary protocol description innobase/include/db0err.h: Merge from 3.23 mysql-test/r/insert.result: Updated test result from 3.23 sql/log.cc: Fixed bug in replication and log rotation sql/log_event.cc: Ensure that BEGIN / COMMIT is handled properly if slave dies sql/slave.cc: Fixed bug in replication and log rotation sql/slave.h: Ensure that BEGIN / COMMIT is handled properly if slave dies sql/sql_analyse.cc: Moved usage of res before res is destroyed (by bzero(&s...)) sql/sql_yacc.yy: Added syntax support for CREATE TABLE foo (a char CHARACTER SET latin1) CHARSET=latin1; To be able to read MySQL 4.1 dump files. --- Docs/internals.texi | 16 +++++++++++-- innobase/include/db0err.h | 3 ++- mysql-test/r/insert.result | 11 ++++++++- sql/log.cc | 5 ++++ sql/log_event.cc | 23 +++++++++++++++--- sql/slave.cc | 7 +++++- sql/slave.h | 10 ++++---- sql/sql_analyse.cc | 49 +++++++++++++++++++------------------- sql/sql_yacc.yy | 5 ++++ 9 files changed, 93 insertions(+), 36 deletions(-) diff --git a/Docs/internals.texi b/Docs/internals.texi index 7e364774e39..18bdc8d8b4c 100644 --- a/Docs/internals.texi +++ b/Docs/internals.texi @@ -1797,7 +1797,7 @@ The package contains the following information: @multitable @columnfractions .30 .70 @item Size @tab Comment -@item (param_count+7)/8 @tab Null bit map +@item (param_count+9)/8 @tab Null bit map (2 bits reserved for protocol) @item 1 @tab new_parameter_bound flag. Is set to 1 for first execute or if one has rebound the parameters. @item 2*param_count @tab Type of parameters (only given if new_parameter_bound flag is 1) @@ -1813,7 +1813,7 @@ The parameters are stored the following ways: @multitable @columnfractions .20 .10 .70 @item Type @tab Size @tab Comment -@item tynyint @tab 1 @tab One byte integer +@item tinyint @tab 1 @tab One byte integer @item short @tab 2 @tab @item int @tab 4 @tab @item longlong @tab 8 @tab @@ -1849,6 +1849,18 @@ bound parameters to the client. The server is always sending the data as type given for 'column type' for respective column. It's up to the client to convert the parameter to the requested type. +DATETIME, DATE and TIME are sent to the server in a binary format as follows: + +@multitable @columnfractions .20 .10 .70 +@item Type @tab Size @tab Comment +@item date @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second +@item datetime @tab 1 + 0-11 @tab Length + 2 byte year, 1 byte MMDDHHMMSS, 4 byte billionth of a second +@item time @tab 1 + 0-14 @tab Length + sign (0 = pos, 1= neg), 4 byte days, 1 byte HHMMDD, 4 byte billionth of a second +@end multitable + +The first byte is a length byte and then comes all parameters that are +not 0. (Always counted from the beginning). + @node Fulltext Search, , protocol, Top @chapter Fulltext Search in MySQL diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index 86b79b65bf2..ae4b0fe4cc5 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -42,7 +42,8 @@ Created 5/24/1996 Heikki Tuuri #define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint to a table failed */ #define DB_CORRUPTION 39 /* data structure corruption noticed */ - +#define DB_COL_APPEARS_TWICE_IN_INDEX 40 + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 2ffa9d88618..dedde4cc408 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -46,8 +46,17 @@ insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL); select * from t1; sid id skr 1 -skr 2 +skr 1 test 1 +insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL); +select * from t1; +sid id +rts 1 +rts 2 +skr 1 +skr 1 +test 1 +test 2 drop table t1; drop database if exists foo; create database foo; diff --git a/sql/log.cc b/sql/log.cc index 32dbdac1074..56019a76b22 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -654,7 +654,12 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) rli->linfo.log_file_name); goto err; } + /* + Reset position to current log. This involves setting both of the + position variables: + */ rli->relay_log_pos = BIN_LOG_HEADER_SIZE; + rli->pending = 0; strmake(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)-1); diff --git a/sql/log_event.cc b/sql/log_event.cc index 373e50b84f7..d451a5bc46c 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -208,9 +208,13 @@ int Log_event::exec_event(struct st_relay_log_info* rli) { if (rli) // QQ When is this not true ? { - rli->inc_pos(get_event_len(),log_pos); - DBUG_ASSERT(rli->sql_thd != 0); - flush_relay_log_info(rli); + if (rli->inside_transaction) + rli->inc_pending(get_event_len()); + else + { + rli->inc_pos(get_event_len(),log_pos); + flush_relay_log_info(rli); + } } return 0; } @@ -1707,6 +1711,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) mysql_log.write(thd,COM_QUERY,"%s",thd->query); DBUG_PRINT("query",("%s",thd->query)); mysql_parse(thd, thd->query, q_len); + + /* + Set a flag if we are inside an transaction so that we can restart + the transaction from the start if we are killed + + This will only be done if we are supporting transactional tables + in the slave. + */ + if (!strcmp(thd->query,"BEGIN")) + rli->inside_transaction= opt_using_transactions; + else if (!strcmp(thd->query,"COMMIT")) + rli->inside_transaction=0; + if ((expected_error != (actual_error = thd->net.last_errno)) && expected_error && !ignored_error_code(actual_error) && diff --git a/sql/slave.cc b/sql/slave.cc index eb53e488856..a4e0b029bbf 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2711,7 +2711,12 @@ static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg) if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name, errmsg)) <0) DBUG_RETURN(0); - my_b_seek(cur_log,rli->relay_log_pos); + /* + We want to start exactly where we was before: + relay_log_pos Current log pos + pending Number of bytes already processed from the event + */ + my_b_seek(cur_log,rli->relay_log_pos + rli->pending); DBUG_RETURN(cur_log); } diff --git a/sql/slave.h b/sql/slave.h index 721fd8534a0..cb368ad26b1 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -169,11 +169,13 @@ typedef struct st_relay_log_info volatile bool abort_slave, slave_running; bool log_pos_current; bool skip_log_purge; - + bool inside_transaction; + st_relay_log_info() - :info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0), - slave_run_id(0), inited(0), abort_slave(0), slave_running(0), - log_pos_current(0), skip_log_purge(0) + :info_fd(-1),cur_log_fd(-1), cur_log_old_open_count(0), abort_pos_wait(0), + slave_run_id(0), inited(0), abort_slave(0), slave_running(0), + log_pos_current(0), skip_log_purge(0), + inside_transaction(0) /* the default is autocommit=1 */ { relay_log_name[0] = master_log_name[0] = 0; bzero(&info_file,sizeof(info_file)); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 96bbd731882..cbd586b8d30 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -310,30 +310,6 @@ void field_str::add() was_maybe_zerofill = num_info.maybe_zerofill; } - if (room_in_tree) - { - if (res != &s) - s.copy(*res); - if (!tree_search(&tree, (void*) &s)) // If not in tree - { - s.copy(); // slow, when SAFE_MALLOC is in use - if (!tree_insert(&tree, (void*) &s, 0)) - { - room_in_tree = 0; // Remove tree, out of RAM ? - delete_tree(&tree); - } - else - { - bzero((char*) &s, sizeof(s)); // Let tree handle free of this - if ((treemem += length) > pc->max_treemem) - { - room_in_tree = 0; // Remove tree, too big tree - delete_tree(&tree); - } - } - } - } - if (!found) { found = 1; @@ -364,6 +340,31 @@ void field_str::add() max_arg.copy(*res); } } + + if (room_in_tree) + { + if (res != &s) + s.copy(*res); + if (!tree_search(&tree, (void*) &s)) // If not in tree + { + s.copy(); // slow, when SAFE_MALLOC is in use + if (!tree_insert(&tree, (void*) &s, 0)) + { + room_in_tree = 0; // Remove tree, out of RAM ? + delete_tree(&tree); + } + else + { + bzero((char*) &s, sizeof(s)); // Let tree handle free of this + if ((treemem += length) > pc->max_treemem) + { + room_in_tree = 0; // Remove tree, too big tree + delete_tree(&tree); + } + } + } + } + if ((num_info.zerofill && (max_length != min_length)) || (was_zero_fill && (max_length != min_length))) can_be_still_num = 0; // zerofilled numbers must be of same length diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7cb05d6bd3c..2eb32d16bb7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CACHE_SYM %token CASCADE %token CAST_SYM +%token CHARSET %token CHECKSUM_SYM %token CHECK_SYM %token COMMITTED_SYM @@ -855,6 +856,8 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } + | CHARSET opt_equal ident {} + | CHAR_SYM SET opt_equal ident {} | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; }; @@ -1088,6 +1091,7 @@ attribute: opt_binary: /* empty */ {} | BINARY { Lex->type|=BINARY_FLAG; }; + | CHAR_SYM SET opt_equal ident {} references: REFERENCES table_ident opt_on_delete {} @@ -3192,6 +3196,7 @@ keyword: | BOOLEAN_SYM {} | CACHE_SYM {} | CHANGED {} + | CHARSET {} | CHECKSUM_SYM {} | CIPHER_SYM {} | CLIENT_SYM {} From ff50fc4fe5f33722cbe13e04be393d6a2d4bf5ce Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 18:27:46 +0100 Subject: [PATCH 18/61] - tagged ChangeSet 1.1276.3.1 as MySQL 3.23.54 - bumped up version number in configure.in to 3.23.55 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 3a5c1a56408..7a4498bff97 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 3.23.54) +AM_INIT_AUTOMAKE(mysql, 3.23.55) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From aaf9a98e1368a19010da4bc4e7ba06943c2d8279 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 19:37:09 +0100 Subject: [PATCH 19/61] - moved manual pages from "man" to "man/man1" for the binary distribution --- scripts/make_binary_distribution.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 9d25943bb52..c2b1a0cb2b3 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -50,7 +50,7 @@ mkdir $BASE $BASE/bin $BASE/data $BASE/data/mysql $BASE/data/test \ $BASE/include $BASE/lib $BASE/support-files $BASE/share $BASE/share/mysql \ $BASE/tests $BASE/scripts $BASE/sql-bench $BASE/mysql-test \ $BASE/mysql-test/t $BASE/mysql-test/r \ - $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/man + $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/man $BASE/man/man1 chmod o-rwx $BASE/data $BASE/data/* @@ -107,7 +107,7 @@ rm $BASE/include/Makefile*; rm $BASE/include/*.in $CP tests/*.res tests/*.tst tests/*.pl $BASE/tests $CP support-files/* $BASE/support-files -$CP man/*.? $BASE/man +$CP man/*.1 $BASE/man/man1 $CP -r sql/share/* $BASE/share/mysql rm -f $BASE/share/mysql/Makefile* $BASE/share/mysql/*/*.OLD From 182de7c203bf543520584318aa6936e69fdc9942 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 21:22:57 +0200 Subject: [PATCH 20/61] Add CHARSET keyword (missing from last push) sql/field.cc: Small safety fix --- sql/field.cc | 6 ++++-- sql/lex.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index afd594b7045..aae4fac2a38 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4220,9 +4220,11 @@ void Field_blob::get_key_image(char *buff,uint length) char *blob; if ((uint32) length > blob_length) { -#ifdef HAVE_purify + /* + Must clear this as we do a memcmp in opt_range.cc to detect + identical keys + */ bzero(buff+2+blob_length, (length-blob_length)); -#endif length=(uint) blob_length; } int2store(buff,length); diff --git a/sql/lex.h b/sql/lex.h index bf0abc323e1..826b9b4a9ef 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -80,6 +80,7 @@ static SYMBOL symbols[] = { { "CASE", SYM(CASE_SYM),0,0}, { "CHAR", SYM(CHAR_SYM),0,0}, { "CHARACTER", SYM(CHAR_SYM),0,0}, + { "CHARSET", SYM(CHARSET),0,0}, { "CHANGE", SYM(CHANGE),0,0}, { "CHANGED", SYM(CHANGED),0,0}, { "CHECK", SYM(CHECK_SYM),0,0}, From b870cfa5952056bbde9d0a92c63d87ade129d27f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 21:24:28 +0200 Subject: [PATCH 21/61] log.cc: We must not commit inside InnoDB when LOAD DATA INFILE just writes a block to the binlog; only commit if the log event type is QUERY_EVENT or EXECUTE_LOAD_EVENT sql/log.cc: We must not commit inside InnoDB when LOAD DATA INFILE just writes a block to the binlog; only commit if the log event type is QUERY_EVENT or EXECUTE_LOAD_EVENT --- sql/log.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 56019a76b22..21c88cc1616 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1115,8 +1115,20 @@ bool MYSQL_LOG::write(Log_event* event_info) if (file == &log_file) { - error = ha_report_binlog_offset_and_commit(thd, log_file_name, + /* + LOAD DATA INFILE in AUTOCOMMIT=1 mode writes to the binlog + chunks also before it is successfully completed. We only report + the binlog write and do the commit inside the transactional table + handler if the log event type is appropriate. + */ + + if (event_info->get_type_code() == QUERY_EVENT + || event_info->get_type_code() == EXEC_LOAD_EVENT) + { + error = ha_report_binlog_offset_and_commit(thd, log_file_name, file->pos_in_file); + } + should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size); } @@ -1159,7 +1171,7 @@ uint MYSQL_LOG::next_file_id() NOTE - We only come here if there is something in the cache. - - The thing in the cache is always a complete transcation + - The thing in the cache is always a complete transaction - 'cache' needs to be reinitialized after this functions returns. IMPLEMENTATION From 25c8f58ac7710db353a1078f22988cdaa5633817 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Dec 2002 11:06:55 +0200 Subject: [PATCH 22/61] - Fix handling of suffix option - Replace function 'check_reserved_words' with correct one BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql-bench/crash-me.sh | 390 +++++++++++++++++++-------------------- 2 files changed, 196 insertions(+), 195 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 5c9df32641b..a55a5f46496 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -62,6 +62,7 @@ pem@mysql.com peter@linux.local peter@mysql.com ram@ram.(none) +ranger@regul.home.lan root@x3.internalnet salle@geopard.(none) salle@geopard.online.bg diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index d18070d30b7..b101a7f595a 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -66,7 +66,7 @@ $retry_limit=3; GetOptions("Information","help","server=s","debug","user=s","password=s","database=s","restart","force","quick","log-all-queries","comment=s","host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s","batch-mode","config-file=s","log-queries-to-file=s","check-server") || usage(); usage() if ($opt_help || $opt_Information); -$opt_suffix = '-'.$opt_suffix if (length($opt_suffix) == 0); +$opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0); $opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg" if (length($opt_config_file) == 0); #!!! @@ -2726,223 +2726,223 @@ sub check_reserved_words my $answer, $prompt, $config, $keyword_type; - my @keywords_type = ( "(ANSI SQL 92/99)", "(ANSI SQL 92)", "(ANSI SQL 99)", "(EXTRA)"); - my @keywords_ext = ( "ansi92/99", "ansi92", "ansi99", "extra"); + my @keywords_ext = ( "ansi-92/99", "ansi92", "ansi99", "extra"); my %reserved_words = ( - ABSOLUTE => 0, ACTION => 0, ADD => 0, - AFTER => 0, ALIAS => 0, ALL => 0, - ALLOCATE => 0, ALTER => 0, AND => 0, - ANY => 0, ARE => 0, AS => 0, - ASC => 0, ASSERTION => 0, AT => 0, - AUTHORIZATION => 0, BEFORE => 0, BEGIN => 0, - BIT => 0, BOOLEAN => 0, BOTH => 0, - BREADTH => 0, BY => 0, CALL => 0, - CASCADE => 0, CASCADED => 0, CASE => 0, - CAST => 0, CATALOG => 0, CHAR => 0, - CHARACTER => 0, CHECK => 0, CLOSE => 0, - COLLATE => 0, COLLATION => 0, COLUMN => 0, - COMMIT => 0, COMPLETION => 0, CONNECT => 0, - CONNECTION => 0, CONSTRAINT => 0, CONSTRAINTS => 0, - CONTINUE => 0, CORRESPONDING => 0, CREATE => 0, - CROSS => 0, CURRENT => 0, CURRENT_DATE => 0, - CURRENT_TIME => 0, CURRENT_TIMESTAMP => 0, CURRENT_USER => 0, - CURSOR => 0, CYCLE => 0, DATA => 0, - DATE => 0, DAY => 0, DEALLOCATE => 0, - DEC => 0, DECIMAL => 0, DECLARE => 0, - DEFAULT => 0, DEFERRABLE => 0, DEFERRED => 0, - DELETE => 0, DEPTH => 0, DESC => 0, - DESCRIBE => 0, DESCRIPTOR => 0, DIAGNOSTICS => 0, - DICTIONARY => 0, DISCONNECT => 0, DISTINCT => 0, - DOMAIN => 0, DOUBLE => 0, DROP => 0, - EACH => 0, ELSE => 0, ELSEIF => 0, - END => 0, END-EXEC => 0, EQUALS => 0, - ESCAPE => 0, EXCEPT => 0, EXCEPTION => 0, - EXEC => 0, EXECUTE => 0, EXTERNAL => 0, - FALSE => 0, FETCH => 0, FIRST => 0, - FLOAT => 0, FOR => 0, FOREIGN => 0, - FOUND => 0, FROM => 0, FULL => 0, - GENERAL => 0, GET => 0, GLOBAL => 0, - GO => 0, GOTO => 0, GRANT => 0, - GROUP => 0, HAVING => 0, HOUR => 0, - IDENTITY => 0, IF => 0, IGNORE => 0, - IMMEDIATE => 0, IN => 0, INDICATOR => 0, - INITIALLY => 0, INNER => 0, INPUT => 0, - INSERT => 0, INT => 0, INTEGER => 0, - INTERSECT => 0, INTERVAL => 0, INTO => 0, - IS => 0, ISOLATION => 0, JOIN => 0, - KEY => 0, LANGUAGE => 0, LAST => 0, - LEADING => 0, LEAVE => 0, LEFT => 0, - LESS => 0, LEVEL => 0, LIKE => 0, - LIMIT => 0, LOCAL => 0, LOOP => 0, - MATCH => 0, MINUTE => 0, MODIFY => 0, - MODULE => 0, MONTH => 0, NAMES => 0, - NATIONAL => 0, NATURAL => 0, NCHAR => 0, - NEW => 0, NEXT => 0, NO => 0, - NONE => 0, NOT => 0, NULL => 0, - NUMERIC => 0, OBJECT => 0, OF => 0, - OFF => 0, OLD => 0, ON => 0, - ONLY => 0, OPEN => 0, OPERATION => 0, - OPTION => 0, OR => 0, ORDER => 0, - OUTER => 0, OUTPUT => 0, PAD => 0, - PARAMETERS => 0, PARTIAL => 0, PRECISION => 0, - PREORDER => 0, PREPARE => 0, PRESERVE => 0, - PRIMARY => 0, PRIOR => 0, PRIVILEGES => 0, - PROCEDURE => 0, PUBLIC => 0, READ => 0, - REAL => 0, RECURSIVE => 0, REF => 0, - REFERENCES => 0, REFERENCING => 0, RELATIVE => 0, - RESIGNAL => 0, RESTRICT => 0, RETURN => 0, - RETURNS => 0, REVOKE => 0, RIGHT => 0, - ROLE => 0, ROLLBACK => 0, ROUTINE => 0, - ROW => 0, ROWS => 0, SAVEPOINT => 0, - SCHEMA => 0, SCROLL => 0, SEARCH => 0, - SECOND => 0, SECTION => 0, SELECT => 0, - SEQUENCE => 0, SESSION => 0, SESSION_USER => 0, - SET => 0, SIGNAL => 0, SIZE => 0, - SMALLINT => 0, SOME => 0, SPACE => 0, - SQL => 0, SQLEXCEPTION => 0, SQLSTATE => 0, - SQLWARNING => 0, STRUCTURE => 0, SYSTEM_USER => 0, - TABLE => 0, TEMPORARY => 0, THEN => 0, - TIME => 0, TIMESTAMP => 0, TIMEZONE_HOUR => 0, - TIMEZONE_MINUTE => 0, TO => 0, TRAILING => 0, - TRANSACTION => 0, TRANSLATION => 0, TRIGGER => 0, - TRUE => 0, UNDER => 0, UNION => 0, - UNIQUE => 0, UNKNOWN => 0, UPDATE => 0, - USAGE => 0, USER => 0, USING => 0, - VALUE => 0, VALUES => 0, VARCHAR => 0, - VARIABLE => 0, VARYING => 0, VIEW => 0, - WHEN => 0, WHENEVER => 0, WHERE => 0, - WHILE => 0, WITH => 0, WITHOUT => 0, - WORK => 0, WRITE => 0, YEAR => 0, - ZONE => 0, + 'ABSOLUTE' => 0, 'ACTION' => 0, 'ADD' => 0, + 'AFTER' => 0, 'ALIAS' => 0, 'ALL' => 0, + 'ALLOCATE' => 0, 'ALTER' => 0, 'AND' => 0, + 'ANY' => 0, 'ARE' => 0, 'AS' => 0, + 'ASC' => 0, 'ASSERTION' => 0, 'AT' => 0, + 'AUTHORIZATION' => 0, 'BEFORE' => 0, 'BEGIN' => 0, + 'BIT' => 0, 'BOOLEAN' => 0, 'BOTH' => 0, + 'BREADTH' => 0, 'BY' => 0, 'CALL' => 0, + 'CASCADE' => 0, 'CASCADED' => 0, 'CASE' => 0, + 'CAST' => 0, 'CATALOG' => 0, 'CHAR' => 0, + 'CHARACTER' => 0, 'CHECK' => 0, 'CLOSE' => 0, + 'COLLATE' => 0, 'COLLATION' => 0, 'COLUMN' => 0, + 'COMMIT' => 0, 'COMPLETION' => 0, 'CONNECT' => 0, + 'CONNECTION' => 0, 'CONSTRAINT' => 0, 'CONSTRAINTS' => 0, + 'CONTINUE' => 0, 'CORRESPONDING' => 0, 'CREATE' => 0, + 'CROSS' => 0, 'CURRENT' => 0, 'CURRENT_DATE' => 0, + 'CURRENT_TIME' => 0,'CURRENT_TIMESTAMP' => 0, 'CURRENT_USER' => 0, + 'CURSOR' => 0, 'CYCLE' => 0, 'DATA' => 0, + 'DATE' => 0, 'DAY' => 0, 'DEALLOCATE' => 0, + 'DEC' => 0, 'DECIMAL' => 0, 'DECLARE' => 0, + 'DEFAULT' => 0, 'DEFERRABLE' => 0, 'DEFERRED' => 0, + 'DELETE' => 0, 'DEPTH' => 0, 'DESC' => 0, + 'DESCRIBE' => 0, 'DESCRIPTOR' => 0, 'DIAGNOSTICS' => 0, + 'DICTIONARY' => 0, 'DISCONNECT' => 0, 'DISTINCT' => 0, + 'DOMAIN' => 0, 'DOUBLE' => 0, 'DROP' => 0, + 'EACH' => 0, 'ELSE' => 0, 'ELSEIF' => 0, + 'END' => 0, 'END-EXEC' => 0, 'EQUALS' => 0, + 'ESCAPE' => 0, 'EXCEPT' => 0, 'EXCEPTION' => 0, + 'EXEC' => 0, 'EXECUTE' => 0, 'EXTERNAL' => 0, + 'FALSE' => 0, 'FETCH' => 0, 'FIRST' => 0, + 'FLOAT' => 0, 'FOR' => 0, 'FOREIGN' => 0, + 'FOUND' => 0, 'FROM' => 0, 'FULL' => 0, + 'GENERAL' => 0, 'GET' => 0, 'GLOBAL' => 0, + 'GO' => 0, 'GOTO' => 0, 'GRANT' => 0, + 'GROUP' => 0, 'HAVING' => 0, 'HOUR' => 0, + 'IDENTITY' => 0, 'IF' => 0, 'IGNORE' => 0, + 'IMMEDIATE' => 0, 'IN' => 0, 'INDICATOR' => 0, + 'INITIALLY' => 0, 'INNER' => 0, 'INPUT' => 0, + 'INSERT' => 0, 'INT' => 0, 'INTEGER' => 0, + 'INTERSECT' => 0, 'INTERVAL' => 0, 'INTO' => 0, + 'IS' => 0, 'ISOLATION' => 0, 'JOIN' => 0, + 'KEY' => 0, 'LANGUAGE' => 0, 'LAST' => 0, + 'LEADING' => 0, 'LEAVE' => 0, 'LEFT' => 0, + 'LESS' => 0, 'LEVEL' => 0, 'LIKE' => 0, + 'LIMIT' => 0, 'LOCAL' => 0, 'LOOP' => 0, + 'MATCH' => 0, 'MINUTE' => 0, 'MODIFY' => 0, + 'MODULE' => 0, 'MONTH' => 0, 'NAMES' => 0, + 'NATIONAL' => 0, 'NATURAL' => 0, 'NCHAR' => 0, + 'NEW' => 0, 'NEXT' => 0, 'NO' => 0, + 'NONE' => 0, 'NOT' => 0, 'NULL' => 0, + 'NUMERIC' => 0, 'OBJECT' => 0, 'OF' => 0, + 'OFF' => 0, 'OLD' => 0, 'ON' => 0, + 'ONLY' => 0, 'OPEN' => 0, 'OPERATION' => 0, + 'OPTION' => 0, 'OR' => 0, 'ORDER' => 0, + 'OUTER' => 0, 'OUTPUT' => 0, 'PAD' => 0, + 'PARAMETERS' => 0, 'PARTIAL' => 0, 'PRECISION' => 0, + 'PREORDER' => 0, 'PREPARE' => 0, 'PRESERVE' => 0, + 'PRIMARY' => 0, 'PRIOR' => 0, 'PRIVILEGES' => 0, + 'PROCEDURE' => 0, 'PUBLIC' => 0, 'READ' => 0, + 'REAL' => 0, 'RECURSIVE' => 0, 'REF' => 0, + 'REFERENCES' => 0, 'REFERENCING' => 0, 'RELATIVE' => 0, + 'RESIGNAL' => 0, 'RESTRICT' => 0, 'RETURN' => 0, + 'RETURNS' => 0, 'REVOKE' => 0, 'RIGHT' => 0, + 'ROLE' => 0, 'ROLLBACK' => 0, 'ROUTINE' => 0, + 'ROW' => 0, 'ROWS' => 0, 'SAVEPOINT' => 0, + 'SCHEMA' => 0, 'SCROLL' => 0, 'SEARCH' => 0, + 'SECOND' => 0, 'SECTION' => 0, 'SELECT' => 0, + 'SEQUENCE' => 0, 'SESSION' => 0, 'SESSION_USER' => 0, + 'SET' => 0, 'SIGNAL' => 0, 'SIZE' => 0, + 'SMALLINT' => 0, 'SOME' => 0, 'SPACE' => 0, + 'SQL' => 0, 'SQLEXCEPTION' => 0, 'SQLSTATE' => 0, + 'SQLWARNING' => 0, 'STRUCTURE' => 0, 'SYSTEM_USER' => 0, + 'TABLE' => 0, 'TEMPORARY' => 0, 'THEN' => 0, + 'TIME' => 0, 'TIMESTAMP' => 0, 'TIMEZONE_HOUR' => 0, + 'TIMEZONE_MINUTE' => 0, 'TO' => 0, 'TRAILING' => 0, + 'TRANSACTION' => 0, 'TRANSLATION' => 0, 'TRIGGER' => 0, + 'TRUE' => 0, 'UNDER' => 0, 'UNION' => 0, + 'UNIQUE' => 0, 'UNKNOWN' => 0, 'UPDATE' => 0, + 'USAGE' => 0, 'USER' => 0, 'USING' => 0, + 'VALUE' => 0, 'VALUES' => 0, 'VARCHAR' => 0, + 'VARIABLE' => 0, 'VARYING' => 0, 'VIEW' => 0, + 'WHEN' => 0, 'WHENEVER' => 0, 'WHERE' => 0, + 'WHILE' => 0, 'WITH' => 0, 'WITHOUT' => 0, + 'WORK' => 0, 'WRITE' => 0, 'YEAR' => 0, + 'ZONE' => 0, - ASYNC => 1, AVG => 1, BETWEEN => 1, - BIT_LENGTH => 1, CHARACTER_LENGTH => 1, CHAR_LENGTH => 1, - COALESCE => 1, CONVERT => 1, COUNT => 1, - EXISTS => 1, EXTRACT => 1, INSENSITIVE => 1, - LOWER => 1, MAX => 1, MIN => 1, - NULLIF => 1, OCTET_LENGTH => 1, OID => 1, - OPERATORS => 1, OTHERS => 1, OVERLAPS => 1, - PENDANT => 1, POSITION => 1, PRIVATE => 1, - PROTECTED => 1, REPLACE => 1, SENSITIVE => 1, - SIMILAR => 1, SQLCODE => 1, SQLERROR => 1, - SUBSTRING => 1, SUM => 1, TEST => 1, - THERE => 1, TRANSLATE => 1, TRIM => 1, - TYPE => 1, UPPER => 1, VIRTUAL => 1, - VISIBLE => 1, WAIT => 1, + 'ASYNC' => 1, 'AVG' => 1, 'BETWEEN' => 1, + 'BIT_LENGTH' => 1,'CHARACTER_LENGTH' => 1, 'CHAR_LENGTH' => 1, + 'COALESCE' => 1, 'CONVERT' => 1, 'COUNT' => 1, + 'EXISTS' => 1, 'EXTRACT' => 1, 'INSENSITIVE' => 1, + 'LOWER' => 1, 'MAX' => 1, 'MIN' => 1, + 'NULLIF' => 1, 'OCTET_LENGTH' => 1, 'OID' => 1, + 'OPERATORS' => 1, 'OTHERS' => 1, 'OVERLAPS' => 1, + 'PENDANT' => 1, 'POSITION' => 1, 'PRIVATE' => 1, + 'PROTECTED' => 1, 'REPLACE' => 1, 'SENSITIVE' => 1, + 'SIMILAR' => 1, 'SQLCODE' => 1, 'SQLERROR' => 1, + 'SUBSTRING' => 1, 'SUM' => 1, 'TEST' => 1, + 'THERE' => 1, 'TRANSLATE' => 1, 'TRIM' => 1, + 'TYPE' => 1, 'UPPER' => 1, 'VIRTUAL' => 1, + 'VISIBLE' => 1, 'WAIT' => 1, - ADMIN => 2, AGGREGATE => 2, ARRAY => 2, - BINARY => 2, BLOB => 2, CLASS => 2, - CLOB => 2, CONDITION => 2, CONSTRUCTOR => 2, - CONTAINS => 2, CUBE => 2, CURRENT_PATH => 2, - CURRENT_ROLE => 2, DATALINK => 2, DEREF => 2, - DESTROY => 2, DESTRUCTOR => 2, DETERMINISTIC => 2, - DO => 2, DYNAMIC => 2, EVERY => 2, - EXIT => 2, EXPAND => 2, EXPANDING => 2, - FREE => 2, FUNCTION => 2, GROUPING => 2, - HANDLER => 2, HAST => 2, HOST => 2, - INITIALIZE => 2, INOUT => 2, ITERATE => 2, - LARGE => 2, LATERAL => 2, LOCALTIME => 2, - LOCALTIMESTAMP => 2, LOCATOR => 2, MEETS => 2, - MODIFIES => 2, NCLOB => 2, NORMALIZE => 2, - ORDINALITY => 2, OUT => 2, PARAMETER => 2, - PATH => 2, PERIOD => 2, POSTFIX => 2, - PRECEDES => 2, PREFIX => 2, READS => 2, - REDO => 2, REPEAT => 2, RESULT => 2, - ROLLUP => 2, SETS => 2, SPECIFIC => 2, - SPECIFICTYPE => 2, START => 2, STATE => 2, - STATIC => 2, SUCCEEDS => 2, TERMINATE => 2, - THAN => 2, TREAT => 2, UNDO => 2, - UNTIL => 2, + 'ADMIN' => 2, 'AGGREGATE' => 2, 'ARRAY' => 2, + 'BINARY' => 2, 'BLOB' => 2, 'CLASS' => 2, + 'CLOB' => 2, 'CONDITION' => 2, 'CONSTRUCTOR' => 2, + 'CONTAINS' => 2, 'CUBE' => 2, 'CURRENT_PATH' => 2, + 'CURRENT_ROLE' => 2, 'DATALINK' => 2, 'DEREF' => 2, + 'DESTROY' => 2, 'DESTRUCTOR' => 2, 'DETERMINISTIC' => 2, + 'DO' => 2, 'DYNAMIC' => 2, 'EVERY' => 2, + 'EXIT' => 2, 'EXPAND' => 2, 'EXPANDING' => 2, + 'FREE' => 2, 'FUNCTION' => 2, 'GROUPING' => 2, + 'HANDLER' => 2, 'HAST' => 2, 'HOST' => 2, + 'INITIALIZE' => 2, 'INOUT' => 2, 'ITERATE' => 2, + 'LARGE' => 2, 'LATERAL' => 2, 'LOCALTIME' => 2, + 'LOCALTIMESTAMP' => 2, 'LOCATOR' => 2, 'MEETS' => 2, + 'MODIFIES' => 2, 'NCLOB' => 2, 'NORMALIZE' => 2, + 'ORDINALITY' => 2, 'OUT' => 2, 'PARAMETER' => 2, + 'PATH' => 2, 'PERIOD' => 2, 'POSTFIX' => 2, + 'PRECEDES' => 2, 'PREFIX' => 2, 'READS' => 2, + 'REDO' => 2, 'REPEAT' => 2, 'RESULT' => 2, + 'ROLLUP' => 2, 'SETS' => 2, 'SPECIFIC' => 2, + 'SPECIFICTYPE' => 2, 'START' => 2, 'STATE' => 2, + 'STATIC' => 2, 'SUCCEEDS' => 2, 'TERMINATE' => 2, + 'THAN' => 2, 'TREAT' => 2, 'UNDO' => 2, + 'UNTIL' => 2, - ANALYZE => 3, AUTO_INCREMENT => 3, BDB => 3, - BERKELEYDB => 3, BIGINT => 3, BTREE => 3, - CHANGE => 3, COLUMNS => 3, DATABASE => 3, - DATABASES => 3, DAY_HOUR => 3, DAY_MINUTE => 3, - DAY_SECOND => 3, DELAYED => 3, DISTINCTROW => 3, - ENCLOSED => 3, ERRORS => 3, ESCAPED => 3, - EXPLAIN => 3, FIELDS => 3, FULLTEXT => 3, - GEOMETRY => 3, HASH => 3, HIGH_PRIORITY => 3, - HOUR_MINUTE => 3, HOUR_SECOND => 3, INDEX => 3, - INFILE => 3, INNODB => 3, KEYS => 3, - KILL => 3, LINES => 3, LOAD => 3, - LOCK => 3, LONG => 3, LONGBLOB => 3, - LONGTEXT => 3, LOW_PRIORITY => 3, MASTER_SERVER_ID => 3, - MEDIUMBLOB => 3, MEDIUMINT => 3, MEDIUMTEXT => 3, - MIDDLEINT => 3, MINUTE_SECOND => 3, MRG_MYISAM => 3, - OPTIMIZE => 3, OPTIONALLY => 3, OUTFILE => 3, - PURGE => 3, REGEXP => 3, RENAME => 3, - REQUIRE => 3, RLIKE => 3, RTREE => 3, - SHOW => 3, SONAME => 3, SPATIAL => 3, - SQL_BIG_RESULT => 3,SQL_CALC_FOUND_ROWS => 3, SQL_SMALL_RESULT => 3, - SSL => 3, STARTING => 3, STRAIGHT_JOIN => 3, - STRIPED => 3, TABLES => 3, TERMINATED => 3, - TINYBLOB => 3, TINYINT => 3, TINYTEXT => 3, - TYPES => 3, UNLOCK => 3, UNSIGNED => 3, - USE => 3, USER_RESOURCES => 3, VARBINARY => 3, - WARNINGS => 3, XOR => 3, YEAR_MONTH => 3, - ZEROFILL => 3, + 'ACCESS' => 3, 'ANALYZE' => 3, 'AUDIT' => 3, + 'AUTO_INCREMENT' => 3, 'BACKUP' => 3, 'BDB' => 3, + 'BERKELEYDB' => 3, 'BIGINT' => 3, 'BREAK' => 3, + 'BROWSE' => 3, 'BTREE' => 3, 'BULK' => 3, + 'CHANGE' => 3, 'CHECKPOINT' => 3, 'CLUSTER' => 3, + 'CLUSTERED' => 3, 'COLUMNS' => 3, 'COMMENT' => 3, + 'COMPRESS' => 3, 'COMPUTE' => 3, 'CONTAINSTABLE' => 3, + 'DATABASE' => 3, 'DATABASES' => 3, 'DAY_HOUR' => 3, + 'DAY_MINUTE' => 3, 'DAY_SECOND' => 3, 'DBCC' => 3, + 'DELAYED' => 3, 'DENY' => 3, 'DISK' => 3, + 'DISTINCTROW' => 3, 'DISTRIBUTED' => 3, 'DUMMY' => 3, + 'DUMP' => 3, 'ENCLOSED' => 3, 'ERRLVL' => 3, + 'ERRORS' => 3, 'ESCAPED' => 3, 'EXCLUSIVE' => 3, + 'EXPLAIN' => 3, 'FIELDS' => 3, 'FILE' => 3, + 'FILLFACTOR' => 3, 'FREETEXT' => 3, 'FREETEXTTABLE' => 3, + 'FULLTEXT' => 3, 'GEOMETRY' => 3, 'HASH' => 3, + 'HIGH_PRIORITY' => 3, 'HOLDLOCK' => 3, 'HOUR_MINUTE' => 3, + 'HOUR_SECOND' => 3, 'IDENTIFIED' => 3, 'IDENTITYCOL' => 3, + 'IDENTITY_INSERT' => 3, 'INCREMENT' => 3, 'INDEX' => 3, + 'INFILE' => 3, 'INITIAL' => 3, 'INNODB' => 3, + 'KEYS' => 3, 'KILL' => 3, 'LINENO' => 3, + 'LINES' => 3, 'LOAD' => 3, 'LOCK' => 3, + 'LONG' => 3, 'LONGBLOB' => 3, 'LONGTEXT' => 3, + 'LOW_PRIORITY' => 3, 'MASTER_SERVER_ID' => 3, 'MAXEXTENTS' => 3, + 'MEDIUMBLOB' => 3, 'MEDIUMINT' => 3, 'MEDIUMTEXT' => 3, + 'MIDDLEINT' => 3, 'MINUS' => 3, 'MINUTE_SECOND' => 3, + 'MLSLABEL' => 3, 'MODE' => 3, 'MRG_MYISAM' => 3, + 'NOAUDIT' => 3, 'NOCHECK' => 3, 'NOCOMPRESS' => 3, + 'NONCLUSTERED' => 3, 'NOWAIT' => 3, 'NUMBER' => 3, + 'OFFLINE' => 3, 'OFFSETS' => 3, 'ONLINE' => 3, + 'OPENDATASOURCE' => 3, 'OPENQUERY' => 3, 'OPENROWSET' => 3, + 'OPENXML' => 3, 'OPTIMIZE' => 3, 'OPTIONALLY' => 3, + 'OUTFILE' => 3, 'OVER' => 3, 'PCTFREE' => 3, + 'PERCENT' => 3, 'PLAN' => 3, 'PRINT' => 3, + 'PROC' => 3, 'PURGE' => 3, 'RAISERROR' => 3, + 'RAW' => 3, 'READTEXT' => 3, 'RECONFIGURE' => 3, + 'REGEXP' => 3, 'RENAME' => 3, 'REPLICATION' => 3, + 'REQUIRE' => 3, 'RESOURCE' => 3, 'RESTORE' => 3, + 'RLIKE' => 3, 'ROWCOUNT' => 3, 'ROWGUIDCOL' => 3, + 'ROWID' => 3, 'ROWNUM' => 3, 'RTREE' => 3, + 'RULE' => 3, 'SAVE' => 3, 'SETUSER' => 3, + 'SHARE' => 3, 'SHOW' => 3, 'SHUTDOWN' => 3, + 'SONAME' => 3, 'SPATIAL' => 3, 'SQL_BIG_RESULT' => 3, +'SQL_CALC_FOUND_ROWS' => 3,'SQL_SMALL_RESULT' => 3, 'SSL' => 3, + 'STARTING' => 3, 'STATISTICS' => 3, 'STRAIGHT_JOIN' => 3, + 'STRIPED' => 3, 'SUCCESSFUL' => 3, 'SYNONYM' => 3, + 'SYSDATE' => 3, 'TABLES' => 3, 'TERMINATED' => 3, + 'TEXTSIZE' => 3, 'TINYBLOB' => 3, 'TINYINT' => 3, + 'TINYTEXT' => 3, 'TOP' => 3, 'TRAN' => 3, + 'TRUNCATE' => 3, 'TSEQUAL' => 3, 'TYPES' => 3, + 'UID' => 3, 'UNLOCK' => 3, 'UNSIGNED' => 3, + 'UPDATETEXT' => 3, 'USE' => 3, 'USER_RESOURCES' => 3, + 'VALIDATE' => 3, 'VARBINARY' => 3, 'VARCHAR2' => 3, + 'WAITFOR' => 3, 'WARNINGS' => 3, 'WRITETEXT' => 3, + 'XOR' => 3, 'YEAR_MONTH' => 3, 'ZEROFILL' => 3 +); - BACKUP => 3, BREAK => 3, BROWSE => 3, - BULK => 3, CHECKPOINT => 3, CLUSTERED => 3, - COMPUTE => 3, CONTAINSTABLE => 3, DBCC => 3, - DENY => 3, DISK => 3, DISTRIBUTED => 3, - DUMMY => 3, DUMP => 3, ERRLVL => 3, - FILE => 3, FILLFACTOR => 3, FREETEXT => 3, - FREETEXTTABLE => 3, HOLDLOCK => 3, IDENTITYCOL => 3, - IDENTITY_INSERT => 3, LINENO => 3, NOCHECK => 3, - NONCLUSTERED => 3, OFFSETS => 3, OPENDATASOURCE => 3, - OPENQUERY => 3, OPENROWSET => 3, OPENXML => 3, - OVER => 3, PERCENT => 3, PLAN => 3, - PRINT => 3, PROC => 3, RAISERROR => 3, - READTEXT => 3, RECONFIGURE => 3, REPLICATION => 3, - RESTORE => 3, ROWCOUNT => 3, ROWGUIDCOL => 3, - RULE => 3, SAVE => 3, SETUSER => 3, - SHUTDOWN => 3, STATISTICS => 3, TEXTSIZE => 3, - TOP => 3, TRAN => 3, TRUNCATE => 3, - TSEQUAL => 3, UPDATETEXT => 3, WAITFOR => 3, - WRITETEXT => 3, - - ACCESS => 3, AUDIT => 3, CLUSTER => 3, - COMMENT => 3, COMPRESS => 3, EXCLUSIVE => 3, - IDENTIFIED => 3, INCREMENT => 3, INITIAL => 3, - MAXEXTENTS => 3, MINUS => 3, MLSLABEL => 3, - MODE => 3, NOAUDIT => 3, NOCOMPRESS => 3, - NOWAIT => 3, NUMBER => 3, OFFLINE => 3, - ONLINE => 3, PCTFREE => 3, RAW => 3, - RESOURCE => 3, ROWID => 3, ROWNUM => 3, - SHARE => 3, SUCCESSFUL => 3, SYNONYM => 3, - SYSDATE => 3, UID => 3, VALIDATE => 3, - VARCHAR2 => 3 - ); $dbh->do("drop table crash_me10"); - $dbh->do("create table crash_me10 (id int not null)") or warn "$dbh->errstr\n"; - $dbh->{RaiseError}= 1; - foreach my $keyword (keys %reserved_words) + foreach my $keyword (sort {$a cmp $b} keys %reserved_words) { - $keyword_type= $reserved_words{$keyword}; - $prompt= "Reserved keyword ".$keyword." ".$keywords_type[$keyword_type]; + $prompt= "Keyword ".$keyword; $config= "reserved_word_".$keywords_ext[$keyword_type]."_".lc($keyword); + $dbh->{RaiseError}= 1; + + $answer= "yes"; + eval { - $dbh->do("alter table crash_me10 add column $keyword int not null"); + $dbh->do("create table crash_me10 ($keyword int not null)"); }; - $answer= ($@) ? "yes" : "no"; + $dbh->{RaiseError}= 0; + + if (!$@) + { + $answer= "no"; + $dbh->do("drop table crash_me10"); + } save_config_data($config,$answer,$prompt); print "$prompt: ",$limits{$config},"\n"; - } - - $dbh->{RaiseError}= 0; } - + # # Do a query on a query package object. # From e6783a8785925f0e7433cd96d8f7f8b5c6d0c9a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Dec 2002 21:01:32 +0200 Subject: [PATCH 23/61] Removed compiler warnings Fixed wrong variable name for Windows VC++Files/innobase/innobase.dsp: Don't use precompiled headers (doesn't work with samba) VC++Files/myisammrg/myisammrg.dsp: Add missing files VC++Files/mysqlbinlog/mysqlbinlog.dsp: Fixed included paths VC++Files/mysqldemb/mysqldemb.dsp: Don't use precompiled headers (doesn't work with samba) VC++Files/mysqlserver/mysqlserver.dsp: Don't use precompiled headers (doesn't work with samba) VC++Files/sql/mysqld.dsp: Fixed paths innobase/include/univ.i: Removed compiler warning myisammrg/myrg_open.c: Removed compiler warning sql/ha_myisam.cc: Removed compiler warning Fixed wrong (but not dangerous) if statement sql/ha_myisammrg.cc: Removed compiler warning sql/mysqld.cc: Fixed wrong variable name for Windows sql/sql_update.cc: Removed not used label --- VC++Files/innobase/innobase.dsp | 12 ++++++++---- VC++Files/myisammrg/myisammrg.dsp | 4 ++++ VC++Files/mysqlbinlog/mysqlbinlog.dsp | 6 +++--- VC++Files/mysqldemb/mysqldemb.dsp | 6 ++++-- VC++Files/mysqlserver/mysqlserver.dsp | 12 ++---------- VC++Files/sql/mysqld.dsp | 2 +- innobase/include/univ.i | 3 ++- myisammrg/myrg_open.c | 3 ++- sql/ha_myisam.cc | 4 ++-- sql/ha_myisammrg.cc | 2 +- sql/mysqld.cc | 2 +- sql/sql_update.cc | 2 -- 12 files changed, 30 insertions(+), 28 deletions(-) diff --git a/VC++Files/innobase/innobase.dsp b/VC++Files/innobase/innobase.dsp index a9dd33217be..0c2b656f043 100644 --- a/VC++Files/innobase/innobase.dsp +++ b/VC++Files/innobase/innobase.dsp @@ -43,7 +43,8 @@ RSC=rc.exe # PROP Intermediate_Dir "debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MTd /W3 /GX /Z7 /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c +# ADD CPP /nologo /G6 /MTd /W3 /GX /Z7 /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe @@ -66,7 +67,8 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "release" # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c +# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe @@ -89,7 +91,8 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "innobase___Win32_nt" # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c +# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe @@ -112,7 +115,8 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "innobase___Win32_Max_nt" # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c +# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe diff --git a/VC++Files/myisammrg/myisammrg.dsp b/VC++Files/myisammrg/myisammrg.dsp index e91d1f4e696..e8f86dac0e8 100644 --- a/VC++Files/myisammrg/myisammrg.dsp +++ b/VC++Files/myisammrg/myisammrg.dsp @@ -122,6 +122,10 @@ SOURCE=.\myrg_queue.c # End Source File # Begin Source File +SOURCE=.\myrg_range.c +# End Source File +# Begin Source File + SOURCE=.\myrg_rfirst.c # End Source File # Begin Source File diff --git a/VC++Files/mysqlbinlog/mysqlbinlog.dsp b/VC++Files/mysqlbinlog/mysqlbinlog.dsp index 5d3ff2bb090..94723b0a127 100644 --- a/VC++Files/mysqlbinlog/mysqlbinlog.dsp +++ b/VC++Files/mysqlbinlog/mysqlbinlog.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /I "../client" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /I "../sql" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /I "../" /I "../client" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c +# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /I "../" /I "../sql" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -88,7 +88,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\mysqlbinlog.cpp +SOURCE=..\client\mysqlbinlog.cpp # End Source File # End Group # Begin Group "Header Files" diff --git a/VC++Files/mysqldemb/mysqldemb.dsp b/VC++Files/mysqldemb/mysqldemb.dsp index 7b844a68511..25dc1f6fee1 100644 --- a/VC++Files/mysqldemb/mysqldemb.dsp +++ b/VC++Files/mysqldemb/mysqldemb.dsp @@ -41,7 +41,8 @@ RSC=rc.exe # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /YX /FD /c +# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe @@ -64,7 +65,8 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x416 /d "_DEBUG" # ADD RSC /l 0x416 /d "_DEBUG" BSC32=bscmake.exe diff --git a/VC++Files/mysqlserver/mysqlserver.dsp b/VC++Files/mysqlserver/mysqlserver.dsp index 7991131c3a8..84c547ef453 100644 --- a/VC++Files/mysqlserver/mysqlserver.dsp +++ b/VC++Files/mysqlserver/mysqlserver.dsp @@ -41,7 +41,7 @@ RSC=rc.exe # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "MYSQL_SERVER" /D "__WIN__" /YX /FD /c +# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /YX /FD /c # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" BSC32=bscmake.exe @@ -64,7 +64,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /YX /FD /GZ /c # ADD BASE RSC /l 0x416 /d "_DEBUG" # ADD RSC /l 0x416 /d "_DEBUG" BSC32=bscmake.exe @@ -80,13 +80,5 @@ LIB32=link.exe -lib # Name "mysqlserver - Win32 Release" # Name "mysqlserver - Win32 Debug" -# Begin Source File - -SOURCE=..\sql\set_var.cpp -# End Source File -# Begin Source File - -SOURCE=..\sql\sql_load.cpp -# End Source File # End Target # End Project diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp index ac5550ad2b2..c550407da30 100644 --- a/VC++Files/sql/mysqld.dsp +++ b/VC++Files/sql/mysqld.dsp @@ -218,7 +218,7 @@ SOURCE=.\derror.cpp # End Source File # Begin Source File -SOURCE=..\client\errmsg.c +SOURCE=..\libmysql\errmsg.c # End Source File # Begin Source File diff --git a/innobase/include/univ.i b/innobase/include/univ.i index f32161fed20..43130549eae 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -9,7 +9,8 @@ Created 1/20/1994 Heikki Tuuri #ifndef univ_i #define univ_i -#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) +#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__) +#undef __WIN__ #define __WIN__ #include diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 6a3c8dd86d9..f996277d287 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -32,7 +32,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { - int save_errno,i,j,errpos; + int save_errno,i,errpos; uint files,dir_length,length,options, key_parts; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; @@ -113,6 +113,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) options= (uint) ~0; for (i=files ; i-- > 0 ; ) { + uint j; m_info->open_tables[i].table=isam; m_info->options|=isam->s->options; options&=isam->s->options; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 0560afdf068..fcef1284385 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -628,7 +628,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) the following 'if', thought conceptually wrong, is a useful optimization nevertheless. */ - if (file->state != &file->s->state.state); + if (file->state != &file->s->state.state) file->s->state.state = *file->state; if (file->s->base.auto_key) update_auto_increment_key(¶m, file, 1); @@ -952,7 +952,7 @@ int ha_myisam::extra(enum ha_extra_function operation) int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size) { - if ((specialflag & SPECIAL_SAFE_MODE) & operation == HA_EXTRA_WRITE_CACHE) + if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE) return 0; return mi_extra(file, operation, (void*) &cache_size); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index efebeb8b46d..b043c6fd942 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -254,7 +254,7 @@ int ha_myisammrg::extra(enum ha_extra_function operation) int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) { - if ((specialflag & SPECIAL_SAFE_MODE) & operation == HA_EXTRA_WRITE_CACHE) + if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE) return 0; return myrg_extra(file, operation, (void*) &cache_size); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1a575932417..f18395f81d2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2148,7 +2148,7 @@ The server will not act as a slave."); (void) thr_setconcurrency(concurrency); // 10 by default #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA { - hEventShutdown=CreateEvent(0, FALSE, FALSE, event_name); + hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) sql_print_error("Warning: Can't create thread to handle shutdown requests"); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2416a99faa8..8a349671c50 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -402,8 +402,6 @@ int mysql_multi_update(THD *thd, (ORDER *)NULL, options | SELECT_NO_JOIN_CACHE, result); - -end: delete result; DBUG_RETURN(res); } From d8a0617508abcb8d56e8889ca3166b8a5a11b8fa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 09:56:02 +0100 Subject: [PATCH 24/61] - added missing "test" to $NOHUP_NICENESS test (thanks to Nick Gaugler for spotting and reporting this) --- scripts/safe_mysqld.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh index 96568bd5d19..c2b6b8cd8b7 100644 --- a/scripts/safe_mysqld.sh +++ b/scripts/safe_mysqld.sh @@ -159,7 +159,7 @@ then NOHUP_NICENESS=`nohup nice 2>&1` if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1 then - if $NOHUP_NICENESS -gt 0 + if test $NOHUP_NICENESS -gt 0 then $NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup" else From 6a2ce08600d55898d3a4487f8d502aa3d9d988c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 12:05:24 +0200 Subject: [PATCH 25/61] RESET SLAVE and CHANGE MASTER will now give an error if slave is running. This fixes a problem in replication where RESET SLAVE could crash a running slave. mysql-test/r/rpl_failsafe.result: Added missing drop mysql-test/r/rpl_log_pos.result: Added slave stop before change master mysql-test/t/rpl_log_pos.test: Added slave stop before change master sql/sql_parse.cc: reset_slave() sends it's own errors sql/sql_repl.cc: reset_slave() sends it own error. RESET SLAVE and CHANGE MASTER will now give an error if slave is running. This fixes a problem in replication where RESET SLAVE could crash a running slave. --- mysql-test/r/rpl_failsafe.result | 1 + mysql-test/r/rpl_log_pos.result | 4 ++ mysql-test/t/rpl_log_pos.test | 4 ++ sql/sql_parse.cc | 37 ++++++++++++---- sql/sql_repl.cc | 75 +++++++++++++++++++------------- 5 files changed, 82 insertions(+), 39 deletions(-) diff --git a/mysql-test/r/rpl_failsafe.result b/mysql-test/r/rpl_failsafe.result index 14b749fada9..7e8aeea64f7 100644 --- a/mysql-test/r/rpl_failsafe.result +++ b/mysql-test/r/rpl_failsafe.result @@ -1,4 +1,5 @@ slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index 6883da76180..e76b565813f 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -10,7 +10,9 @@ master-bin.001 79 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space 127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 124 +slave stop; change master to master_log_pos=73; +slave start; slave stop; change master to master_log_pos=73; show slave status; @@ -20,6 +22,7 @@ slave start; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space 127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No Yes 0 0 73 4 +slave stop; change master to master_log_pos=173; slave start; show slave status; @@ -32,6 +35,7 @@ create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); insert into t1 values (1),(2),(3); +slave stop; change master to master_log_pos=79; slave start; select * from t1; diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index f585fa233c5..e11ba92cfa7 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -8,7 +8,9 @@ connection slave; sync_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; +slave stop; change master to master_log_pos=73; +slave start; sleep 5; slave stop; @@ -19,6 +21,7 @@ slave start; sleep 5; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; +slave stop; change master to master_log_pos=173; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT slave start; @@ -32,6 +35,7 @@ create table t1 (n int); insert into t1 values (1),(2),(3); save_master_pos; connection slave; +slave stop; change master to master_log_pos=79; slave start; sync_with_master; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8f1e9c37eae..bb26826b620 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1136,10 +1136,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_global_access(thd,RELOAD_ACL)) break; mysql_log.write(thd,command,NullS); - if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0)) - send_error(net,0); - else - send_eof(net); + /* error sending is deferred to reload_acl_and_cache */ + reload_acl_and_cache(thd, options, (TABLE_LIST*) 0) ; break; } case COM_SHUTDOWN: @@ -2347,10 +2345,8 @@ mysql_execute_command(void) case SQLCOM_RESET: if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables)) goto error; - if (reload_acl_and_cache(thd, lex->type, tables)) - send_error(&thd->net,0); - else - send_ok(&thd->net); + /* error sending is deferred to reload_acl_and_cache */ + reload_acl_and_cache(thd, lex->type, tables) ; break; case SQLCOM_KILL: kill_one_thread(thd,lex->thread_id); @@ -3332,10 +3328,15 @@ static bool check_dup(const char *db, const char *name, TABLE_LIST *tables) return 0; } + +/* + Reload/resets privileges and the different caches +*/ + bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) { bool result=0; - + bool error_already_sent=0; select_errors=0; /* Write if more errors */ if (options & REFRESH_GRANT) { @@ -3393,11 +3394,29 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) { LOCK_ACTIVE_MI; if (reset_slave(thd, active_mi)) + { result=1; + /* + reset_slave() sends error itself. + If it didn't, one would either change reset_slave()'s prototype, to + pass *errorcode and *errmsg to it when it's called or + change reset_slave to use my_error() to register the error. + */ + error_already_sent=1; + } UNLOCK_ACTIVE_MI; } if (options & REFRESH_USER_RESOURCES) reset_mqh(thd,(LEX_USER *) NULL); + + if (thd && !error_already_sent) + { + if (result) + send_error(&thd->net,0); + else + send_ok(&thd->net); + } + return result; } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ee16b84f87e..02440f511e1 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -695,20 +695,48 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) return 0; } + +/* + Remove all relay logs and start replication from the start + + SYNOPSIS + reset_slave() + thd Thread handler + mi Master info for the slave + + + NOTES + We don't send ok in this functions as this is called from + reload_acl_and_cache() which may have done other tasks, which may + have failed for which we want to send and error. + + RETURN + 0 ok + 1 error + In this case error is sent to the client with send_error() +*/ + + int reset_slave(THD *thd, MASTER_INFO* mi) { MY_STAT stat_area; char fname[FN_REFLEN]; - int restart_thread_mask = 0,error=0; + int thread_mask= 0, error= 0; + uint sql_errno=0; const char* errmsg=0; DBUG_ENTER("reset_slave"); lock_slave_threads(mi); - init_thread_mask(&restart_thread_mask,mi,0 /* not inverse */); - if ((error=terminate_slave_threads(mi,restart_thread_mask,1 /*skip lock*/)) - || (error=purge_relay_logs(&mi->rli, thd, - 1 /* just reset */, - &errmsg))) + init_thread_mask(&thread_mask,mi,0 /* not inverse */); + if (thread_mask) // We refuse if any slave thread is running + { + sql_errno= ER_SLAVE_MUST_STOP; + error=1; + goto err; + } + if ((error= purge_relay_logs(&mi->rli, thd, + 1 /* just reset */, + &errmsg))) goto err; end_master_info(mi); @@ -724,17 +752,15 @@ int reset_slave(THD *thd, MASTER_INFO* mi) error=1; goto err; } - if (restart_thread_mask) - error=start_slave_threads(0 /* mutex not needed */, - 1 /* wait for start*/, - mi,master_info_file,relay_log_info_file, - restart_thread_mask); - // TODO: fix error messages so they get to the client + err: unlock_slave_threads(mi); + if (thd && error) + send_error(&thd->net, sql_errno, errmsg); DBUG_RETURN(error); } + void kill_zombie_dump_threads(uint32 slave_server_id) { pthread_mutex_lock(&LOCK_thread_count); @@ -766,23 +792,20 @@ void kill_zombie_dump_threads(uint32 slave_server_id) int change_master(THD* thd, MASTER_INFO* mi) { - int error=0,restart_thread_mask; + int thread_mask; const char* errmsg=0; bool need_relay_log_purge=1; DBUG_ENTER("change_master"); - // kill slave thread lock_slave_threads(mi); - init_thread_mask(&restart_thread_mask,mi,0 /*not inverse*/); - if (restart_thread_mask && - (error=terminate_slave_threads(mi, - restart_thread_mask, - 1 /*skip lock*/))) + init_thread_mask(&thread_mask,mi,0 /*not inverse*/); + if (thread_mask) // We refuse if any slave thread is running { - send_error(&thd->net,error); + net_printf(&thd->net,ER_SLAVE_MUST_STOP); unlock_slave_threads(mi); DBUG_RETURN(1); } + thd->proc_info = "changing master"; LEX_MASTER_INFO* lex_mi = &thd->lex.mi; // TODO: see if needs re-write @@ -851,6 +874,7 @@ int change_master(THD* thd, MASTER_INFO* mi) &errmsg)) { net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg); + unlock_slave_threads(mi); DBUG_RETURN(1); } } @@ -881,18 +905,9 @@ int change_master(THD* thd, MASTER_INFO* mi) pthread_cond_broadcast(&mi->data_cond); pthread_mutex_unlock(&mi->rli.data_lock); - thd->proc_info = "starting slave"; - if (restart_thread_mask) - error=start_slave_threads(0 /* mutex not needed*/, - 1 /* wait for start*/, - mi,master_info_file,relay_log_info_file, - restart_thread_mask); unlock_slave_threads(mi); thd->proc_info = 0; - if (error) - send_error(&thd->net,error); - else - send_ok(&thd->net); + send_ok(&thd->net); DBUG_RETURN(0); } From 726f29f7e55d815e95bf56cb4b194302fa0c85f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 13:47:25 +0100 Subject: [PATCH 26/61] - fixed another typo in NOHUP_NICENESS testing --- scripts/safe_mysqld.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh index c2b6b8cd8b7..67a38e49e01 100644 --- a/scripts/safe_mysqld.sh +++ b/scripts/safe_mysqld.sh @@ -161,7 +161,7 @@ then then if test $NOHUP_NICENESS -gt 0 then - $NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup" + NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup" else NOHUP_NICENESS="nice -$NOHUP_NICENESS nohup" fi From f84ce68116187295429174721214b809f8ef10dd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 16:01:51 +0200 Subject: [PATCH 27/61] Forbid SLAVE STOP if the thread executing the query has locked tables. This removes a possible deadlock situation. --- sql/sql_parse.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ddbc34b2c7e..f26be7f47e0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1376,6 +1376,24 @@ mysql_execute_command(void) start_slave(thd); break; case SQLCOM_SLAVE_STOP: + /* + if the client thread has locked tables, a deadlock is possible. + Assume that + - the client thread does LOCK TABLE t READ. + - then the master updates t. + - then the SQL slave thread wants to update t, + so it waits for the client thread because t is locked by it. + - then the client thread does SLAVE STOP. + SLAVE STOP waits for the SQL slave thread to terminate its + update t, which waits for the client thread because t is locked by it. + To prevent that, refuse SLAVE STOP if the + client thread has locked tables + */ + if (thd->locked_tables || thd->active_transaction()) + { + send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + break; + } stop_slave(thd); break; From d2bae465344fcc81bb6fca940ed2025da7b52798 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 16:28:15 +0200 Subject: [PATCH 28/61] Fixed possible replication problem in LOAD DATA INFILE with innodb tables. --- sql/sql_load.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index cfb12b8a5bf..6375ba46fd7 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -269,11 +269,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->time_stamp=save_time_stamp; table->next_number_field=0; - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; - } } if (file >= 0) my_close(file,MYF(0)); free_blobs(table); /* if pack_blob was used */ @@ -292,7 +287,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, mysql_bin_log.write(&d); } } - DBUG_RETURN(-1); // Error on read + error= -1; // Error on read + goto err; } sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted, info.records-info.copied,thd->cuted_fields); @@ -326,6 +322,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } if (transactional_table) error=ha_autocommit_or_rollback(thd,error); + +err: + if (thd->lock) + { + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; + } DBUG_RETURN(error); } From 094c801d9bb5899e5a0a50a9ac67bff331a42090 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 15:42:31 +0100 Subject: [PATCH 29/61] - HP/UX 11 compile fix: fixed "records_in_range" class definition in sql/ha_myisammrg.h (removed "ha_myisammrg::") --- sql/ha_myisammrg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 8e33b99e418..440b51e660f 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -69,7 +69,7 @@ class ha_myisammrg: public handler int rnd_next(byte *buf); int rnd_pos(byte * buf, byte *pos); void position(const byte *record); - ha_rows ha_myisammrg::records_in_range(int inx, + ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, enum ha_rkey_function start_search_flag, const byte *end_key,uint end_key_len, From 50d569a3ec9865a8559241e52850e48ed7000196 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 16:38:52 +0100 Subject: [PATCH 30/61] Fixed syntax error in sql_yacc.yy (with bison 1.75). sql/sql_yacc.yy: Fixed syntax error (with bison 1.75). --- sql/sql_yacc.yy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2eb32d16bb7..e26e57b8bbd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1090,8 +1090,9 @@ attribute: opt_binary: /* empty */ {} - | BINARY { Lex->type|=BINARY_FLAG; }; + | BINARY { Lex->type|=BINARY_FLAG; } | CHAR_SYM SET opt_equal ident {} + ; references: REFERENCES table_ident opt_on_delete {} From 05e6b27a13b21cab3f918f425eefc559efc84a6e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 12:05:45 +0200 Subject: [PATCH 31/61] Transactions in AUTOCOMMIT=0 mode didn't rotate binary log. --- sql/log.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/log.cc b/sql/log.cc index 33c7414644a..b6c842e551d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -807,6 +807,9 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) log_file.pos_in_file); if (error) goto err; + + if (my_b_tell(&log_file) >= (my_off_t) max_binlog_size) + new_file(1); // inside mutex } error=0; From 697f939e2c8e4188ac180fb10b04a9f5bf035c91 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 12:25:33 +0200 Subject: [PATCH 32/61] Make --lower-case-table-names default on MacOSX --- configure.in | 8 ++++---- sql/mysqld.cc | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/configure.in b/configure.in index 7a4498bff97..41e44a9e970 100644 --- a/configure.in +++ b/configure.in @@ -915,8 +915,8 @@ case $SYSTEM_TYPE in *darwin5*) if test "$ac_cv_prog_gcc" = "yes" then - CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" - CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" + CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE" + CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE" MAX_C_OPTIMIZE="-O" with_named_curses="" fi @@ -924,8 +924,8 @@ case $SYSTEM_TYPE in *darwin6*) if test "$ac_cv_prog_gcc" = "yes" then - CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" - CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" + CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE" + CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE" MAX_C_OPTIMIZE="-O" fi ;; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 17cf8f79646..a5fc7eabe46 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2976,7 +2976,12 @@ CHANGEABLE_VAR changeable_vars[] = { { "long_query_time", (long*) &long_query_time, 10, 1, LONG_TIMEOUT, 0, 1 }, { "lower_case_table_names", (long*) &lower_case_table_names, - IF_WIN(1,0), 0, 1, 0, 1 }, +#ifdef FN_NO_CASE_SENCE + 1 +#else + 0 +#endif + ,0, 1, 0, 1 }, { "max_allowed_packet", (long*) &max_allowed_packet, 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024 }, { "max_binlog_cache_size", (long*) &max_binlog_cache_size, From b512c8b83a52a7ef44e33b1b2c7e53dc64d28826 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 12:45:31 +0200 Subject: [PATCH 33/61] Transactions in AUTOCOMMIT=0 mode didn't rotate binary log Don't enable any bulk insert or record caching code if inserting less than MIN_ROWS_TO_USE_BULK_INSERT rows (100) myisam/mi_check.c: Fixed bug in copying statistics for disabled index mysql-test/r/distinct.result: Fix result after not doing key statistics for first insert. mysql-test/r/fulltext.result: Fix result after not doing key statistics for first insert. mysql-test/r/insert.result: Fix result after not doing key statistics for first insert. mysql-test/r/key_diff.result: Fix result after not doing key statistics for first insert. mysql-test/r/order_by.result: Fix result after not doing key statistics for first insert. mysql-test/r/select.result: Fix result after not doing key statistics for first insert. mysql-test/r/show_check.result: Fix result after not doing key statistics for first insert. sql/ha_myisam.cc: Don't disable index when inserting only a few rows sql/log.cc: Transactions in AUTOCOMMIT=0 mode didn't rotate binary log. sql/sql_insert.cc: Don't enable any bulk insert or record caching code if inserting less than MIN_ROWS_TO_USE_BULK_INSERT --- myisam/mi_check.c | 14 +++++++------- mysql-test/r/distinct.result | 8 ++++---- mysql-test/r/fulltext.result | 4 ++-- mysql-test/r/insert.result | 4 ++-- mysql-test/r/key_diff.result | 2 +- mysql-test/r/order_by.result | 6 +++--- mysql-test/r/select.result | 4 ++-- mysql-test/r/show_check.result | 2 +- sql/ha_myisam.cc | 17 ++++++++++++----- sql/log.cc | 7 +++++++ sql/sql_insert.cc | 3 ++- 11 files changed, 43 insertions(+), 28 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index b984f0e6ee6..d1165899bea 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -368,8 +368,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) { /* Remember old statistics for key */ memcpy((char*) rec_per_key_part, - (char*) share->state.rec_per_key_part+ - (uint) (rec_per_key_part - param->rec_per_key_part), + (char*) (share->state.rec_per_key_part + + (uint) (rec_per_key_part - param->rec_per_key_part)), keyinfo->keysegs*sizeof(*rec_per_key_part)); continue; } @@ -1912,8 +1912,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, { /* Remember old statistics for key */ memcpy((char*) rec_per_key_part, - (char*) share->state.rec_per_key_part+ - (uint) (rec_per_key_part - param->rec_per_key_part), + (char*) (share->state.rec_per_key_part + + (uint) (rec_per_key_part - param->rec_per_key_part)), sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part)); continue; } @@ -2272,8 +2272,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, { /* Remember old statistics for key */ memcpy((char*) rec_per_key_part, - (char*) share->state.rec_per_key_part+ - (uint) (rec_per_key_part - param->rec_per_key_part), + (char*) (share->state.rec_per_key_part+ + (uint) (rec_per_key_part - param->rec_per_key_part)), sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part)); i--; continue; @@ -2435,7 +2435,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, got_error=0; if (&share->state.state != info->state) - memcpy( &share->state.state, info->state, sizeof(*info->state)); + memcpy(&share->state.state, info->state, sizeof(*info->state)); err: got_error|= flush_blocks(param,share->kfile); diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 919478c7265..020d6c6534f 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3); INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2'); explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; table type possible_keys key key_len ref rows Extra -t1 ALL PRIMARY NULL NULL NULL 2 Using temporary -t2 ref a a 4 t1.a 1 Using index -t3 ref a a 5 t1.b 1 Using where; Using index +t3 index a a 5 NULL 6 Using index; Using temporary +t2 index a a 4 NULL 5 Using index; Distinct +t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 Using where; Distinct SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; a 1 @@ -190,7 +190,7 @@ insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; table type possible_keys key key_len ref rows Extra t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary -t3 ref a a 5 t1.a 1 Using where; Using index; Distinct +t3 ref a a 5 t1.a 10 Using where; Using index; Distinct select distinct t1.a from t1,t3 where t1.a=t3.a; a 1 diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index fc1e0788087..edf109fcc93 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -135,8 +135,8 @@ id 3 show keys from t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t2 1 tig 1 ticket A 3 NULL NULL YES BTREE -t2 1 tix 1 inhalt A 1 1 NULL YES FULLTEXT +t2 1 tig 1 ticket A NULL NULL NULL YES BTREE +t2 1 tix 1 inhalt A NULL 1 NULL YES FULLTEXT show create table t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index dedde4cc408..69b790ff35b 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -46,7 +46,7 @@ insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL); select * from t1; sid id skr 1 -skr 1 +skr 2 test 1 insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL); select * from t1; @@ -54,7 +54,7 @@ sid id rts 1 rts 2 skr 1 -skr 1 +skr 2 test 1 test 2 drop table t1; diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result index f8671639e2c..4eaccc696f9 100644 --- a/mysql-test/r/key_diff.result +++ b/mysql-test/r/key_diff.result @@ -36,7 +36,7 @@ a a a a explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B; table type possible_keys key key_len ref rows Extra t1 ALL a NULL NULL NULL 5 -t2 ref b b 4 t1.a 1 Using where +t2 ALL b NULL NULL NULL 5 Using where select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a; a b a b A B a a diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 62a42150eb3..48773bfa916 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -450,9 +450,9 @@ gid sid uid 103853 5 250 EXPLAIN select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t1.gid, t3.uid; table type possible_keys key key_len ref rows Extra -t3 index PRIMARY PRIMARY 2 NULL 6 Using index; Using temporary; Using filesort -t2 ref PRIMARY,uid uid 2 t3.uid 1 Using where -t1 eq_ref PRIMARY PRIMARY 4 t2.gid 1 Using index +t1 index PRIMARY PRIMARY 4 NULL 6 Using index +t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1 +t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 Using where; Using index EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t1.gid,t3.skr; table type possible_keys key key_len ref rows Extra t1 index PRIMARY PRIMARY 4 NULL 6 Using index diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 51cd67ac832..a921d75f20a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3239,8 +3239,8 @@ Field Type Null Key Default Extra Privileges show keys from t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE -t2 0 fld1 1 fld1 A 0 NULL NULL BTREE -t2 1 fld3 1 fld3 A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A NULL NULL NULL BTREE drop table t4, t3, t2, t1; DO 1; DO benchmark(100,1+1),1,1; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 70548311e26..2c32d766a38 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -9,7 +9,7 @@ Table Op Msg_type Msg_text test.t1 check status Table is already up to date check table t1 changed; Table Op Msg_type Msg_text -test.t1 check status Table is already up to date +test.t1 check status OK insert into t1 values (5,5,5); check table t1 changed; Table Op Msg_type Msg_text diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index fcef1284385..797fe97ea74 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -682,17 +682,24 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) mi_extra(file, HA_EXTRA_NO_KEYS, 0); else { - /* Only disable old index if the table was empty */ - if (file->state->records == 0) + /* + Only disable old index if the table was empty and we are inserting + a lot of rows. + We should not do this for only a few rows as this is slower and + we don't want to update the key statistics based of only a few rows. + */ + if (file->state->records == 0 && + rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT) mi_disable_non_unique_index(file,rows); else { mi_init_bulk_insert(file, - current_thd->variables.bulk_insert_buff_size, rows); - table->bulk_insert= 1; + current_thd->variables.bulk_insert_buff_size, + rows); + table->bulk_insert= 1; + } } } - } enable_activate_all_index=1; } else diff --git a/sql/log.cc b/sql/log.cc index 21c88cc1616..58f5298dad0 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1239,6 +1239,13 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) log_file.pos_in_file))) goto err; signal_update(); + if (my_b_tell(&log_file) >= (my_off_t) max_binlog_size) + { + pthread_mutex_lock(&LOCK_index); + new_file(0); // inside mutex + pthread_mutex_unlock(&LOCK_index); + } + } VOID(pthread_mutex_unlock(&LOCK_log)); DBUG_RETURN(0); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 4d1b2e59f60..56a89e0bd1c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -187,7 +187,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, thd->proc_info="update"; if (duplic == DUP_IGNORE || duplic == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - if ((lock_type != TL_WRITE_DELAYED && !(specialflag & SPECIAL_SAFE_MODE))) + if ((lock_type != TL_WRITE_DELAYED && !(specialflag & SPECIAL_SAFE_MODE)) && + values_list.elements >= MIN_ROWS_TO_USE_BULK_INSERT) { table->file->extra_opt(HA_EXTRA_WRITE_CACHE, min(thd->variables.read_buff_size, From 0c8582b3c3691aedd72812721b6c6e83fc5256d8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 12:57:12 +0200 Subject: [PATCH 34/61] On windows, delete any conflicting 'to' files on rename(from,to) This fixes a bug with REPAIR TABLE t1 USE_FRM on windows. mysys/my_rename.c: On windows, delete any conflicting 'to' files on rename(from,to) --- mysys/my_rename.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mysys/my_rename.c b/mysys/my_rename.c index ea895ffcf76..1b7f434e792 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -46,6 +46,13 @@ int my_rename(const char *from, const char *to, myf MyFlags) } #endif #if defined(HAVE_RENAME) +#ifdef __WIN__ + /* + On windows we can't rename over an existing file: + Remove any conflicting files: + */ + (void) my_delete(to, MYF(0)); +#endif if (rename(from,to)) #else if (link(from, to) || unlink(from)) From 0bc6909f02abd8fc68ab90c8e7503596cf2b299e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 15:32:36 +0200 Subject: [PATCH 35/61] Fix for a bug with mysql_select_db() on manually created database and lower case table names. --- sql/sql_db.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7fcda7948a2..e61a2aa60c5 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -323,6 +323,9 @@ bool mysql_change_db(THD *thd,const char *name) uint db_access; DBUG_ENTER("mysql_change_db"); + if (lower_case_table_names) + casedn_str(dbname); + if (!dbname || !(length=strip_sp(dbname))) { x_free(dbname); /* purecov: inspected */ From db4a9c8018c2e8626fa7c67d1ae08c9d90efcc4b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Dec 2002 22:38:33 +0200 Subject: [PATCH 36/61] perror.c: Add to perror the code 150 about wrong foreign key def extra/perror.c: Add to perror the code 150 about wrong foreign key def --- extra/perror.c | 1 + 1 file changed, 1 insertion(+) diff --git a/extra/perror.c b/extra/perror.c index 4d05adf29aa..e22ce467949 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -80,6 +80,7 @@ static HA_ERRORS ha_errlist[]= { 147,"Lock table is full; Restart program with a larger locktable"}, { 148,"Updates are not allowed under a read only transactions"}, { 149,"Lock deadlock; Retry transaction"}, + { 150,"Foreign key constraint is incorrectly formed"}, { -30999, "DB_INCOMPLETE: Sync didn't finish"}, { -30998, "DB_KEYEMPTY: Key/data deleted or never created"}, { -30997, "DB_KEYEXIST: The key/data pair already exists"}, From c82d6fddb94d0d69a05e846f2431ce25f9a21663 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Dec 2002 17:28:53 +0200 Subject: [PATCH 37/61] Use delayed create index for LOAD DATA INFILE, INSERT ... SELECT and CREATE ... SELECT (Accidently disabled by a recent push) --- sql/ha_myisam.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 797fe97ea74..0a419879e3a 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -689,7 +689,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) we don't want to update the key statistics based of only a few rows. */ if (file->state->records == 0 && - rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT) + (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT)) mi_disable_non_unique_index(file,rows); else { From f1c832d3978558495975febad4e3c99c5831070f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Dec 2002 22:55:29 +0500 Subject: [PATCH 38/61] Add log lines to crash-me result file sql-bench/crash-me.sh: add tagline for emacs add log lines to result file remove wrong prompt for WEEK() sql-bench/server-cfg.sh: cleanup field conversation --- sql-bench/crash-me.sh | 384 +++++++++++++++++++++++++++++----------- sql-bench/server-cfg.sh | 25 +-- 2 files changed, 293 insertions(+), 116 deletions(-) diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index b101a7f595a..8f49da917c3 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -1,4 +1,5 @@ #!@PERL@ +# -*- perl -*- # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB # # This library is free software; you can redistribute it and/or @@ -68,6 +69,10 @@ usage() if ($opt_help || $opt_Information); $opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0); $opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg" if (length($opt_config_file) == 0); +$log_prefix=' ###'; # prefix for log lines in result file +$safe_query_log=''; +$safe_query_result_log=''; +$log{"crash-me"}=""; #!!! @@ -167,11 +172,11 @@ $prompt="drop table require cascade/restrict"; $drop_attr=""; $dbh->do("drop table crash_me"); $dbh->do("drop table crash_me cascade"); -if (!safe_query(["create table crash_me (a integer not null)", +if (!safe_query_l('drop_requires_cascade',["create table crash_me (a integer not null)", "drop table crash_me"])) { $dbh->do("drop table crash_me cascade"); - if (safe_query(["create table crash_me (a integer not null)", + if (safe_query_l('drop_requires_cascade',["create table crash_me (a integer not null)", "drop table crash_me cascade"])) { save_config_data('drop_requires_cascade',"yes","$prompt"); @@ -196,10 +201,10 @@ $dbh->do("drop table crash_q $drop_attr"); $dbh->do("drop table crash_q1 $drop_attr"); $prompt="Tables without primary key"; -if (!safe_query(["create table crash_me (a integer not null,b char(10) not null)", +if (!safe_query_l('no_primary_key',["create table crash_me (a integer not null,b char(10) not null)", "insert into crash_me (a,b) values (1,'a')"])) { - if (!safe_query(["create table crash_me (a integer not null,b char(10) not null, primary key (a))", + if (!safe_query_l('no_primary_key',["create table crash_me (a integer not null,b char(10) not null, primary key (a))", "insert into crash_me (a,b) values (1,'a')"])) { die "Can't create table 'crash_me' with one record: $DBI::errstr\n"; @@ -421,9 +426,9 @@ check_and_report("Group on column with null values",'group_by_null', $prompt="Having"; if (!defined($limits{'having'})) { # Complicated because of postgreSQL - if (!safe_query_result("select a from crash_me group by a having a > 0",1,0)) + if (!safe_query_result_l("having","select a from crash_me group by a having a > 0",1,0)) { - if (!safe_query_result("select a from crash_me group by a having a < 0", + if (!safe_query_result_l("having","select a from crash_me group by a having a < 0", 1,0)) { save_config_data("having","error",$prompt); } else @@ -465,7 +470,7 @@ $logical_value= $limits{'logical_value'}; $false=0; $result="no"; -if ($res=safe_query("select (1=1)=true $end_query")) { +if ($res=safe_query_l('has_true_false',"select (1=1)=true $end_query")) { $false="false"; $result="yes"; } @@ -730,33 +735,33 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" || my $type=$limits{'type_extra_float(2_arg)'} eq "yes" ? "float(4,1)" : "decimal(4,1)"; my $result="undefined"; - if (execute_and_check(["create table crash_q (q1 $type)", + if (execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.14)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.1,0) && - execute_and_check(["create table crash_q (q1 $type)", + execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.16)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.1,0)) { $result="truncate"; } - elsif (execute_and_check(["create table crash_q (q1 $type)", + elsif (execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.14)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.1,0) && - execute_and_check(["create table crash_q (q1 $type)", + execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.16)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.2,0)) { $result="round"; } - elsif (execute_and_check(["create table crash_q (q1 $type)", + elsif (execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.14)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.14,0) && - execute_and_check(["create table crash_q (q1 $type)", + execute_and_check("storage_of_float",["create table crash_q (q1 $type)", "insert into crash_q values(1.16)"], "select q1 from crash_q", ["drop table crash_q $drop_attr"],1.16,0)) @@ -1202,6 +1207,7 @@ if ($limits{'functions'} eq 'yes') "select $tmp $end_query",[], undef(),4); } $prompt="Need to cast NULL for arithmetic"; + add_log("Need_cast_for_null"," Check if numeric_null ($numeric_null) is 'NULL'"); save_config_data("Need_cast_for_null", ($numeric_null eq "NULL") ? "no" : "yes", $prompt); @@ -1220,15 +1226,15 @@ else save_incomplete('func_extra_noround','Function NOROUND'); # 1) check if noround() function is supported - $error = safe_query("select noround(22.6) $end_query"); + $error = safe_query_l('func_extra_noround',"select noround(22.6) $end_query"); if ($error ne 1) # syntax error -- noround is not supported { $resultat = 'no' } else # Ok, now check if it really works { - $error=safe_query( "create table crash_me_nr (a int)", + $error=safe_query_l('func_extra_noround', [ "create table crash_me_nr (a int)", "insert into crash_me_nr values(noround(10.2))", - "drop table crash_me_nr $drop_attr"); + "drop table crash_me_nr $drop_attr"]); if ($error eq 1) { $resultat = "syntax only"; } else { @@ -1246,26 +1252,23 @@ check_parenthesis("func_sql_","USER"); # Test: WEEK() { - my $explain=""; my $resultat="no"; my $error; print "WEEK:"; save_incomplete('func_odbc_week','WEEK'); - $error = safe_query_result("select week(DATE '1997-02-01') $end_query",5,0); + $error = safe_query_result_l('func_odbc_week',"select week(DATE '1997-02-01') $end_query",5,0); # actually this query must return 4 or 5 in the $last_result, # $error can be 1 (not supported at all) , -1 ( probably USA weeks) # and 0 - EURO weeks if ($error == -1) { if ($last_result == 4) { $resultat = 'USA'; - $explain = ' started from Sunday'; } else { $resultat='error'; - $explain = " must return 4 or 5, but $last_error"; + add_log('func_odbc_week'," must return 4 or 5, but $last_result"); } } elsif ($error == 0) { $resultat = 'EURO'; - $explain = ' started from Monday'; } print " $resultat\n"; save_config_data('func_odbc_week',$resultat,"WEEK $explain"); @@ -1486,27 +1489,27 @@ report("index in create table",'index_in_create', # later if (!(defined($limits{'create_index'}) && defined($limits{'drop_index'}))) { - if ($res=safe_query("create index crash_q on crash_me (a)")) + if ($res=safe_query_l('create_index',"create index crash_q on crash_me (a)")) { $res="yes"; $drop_res="yes"; $end_drop_keyword=""; - if (!safe_query("drop index crash_q")) + if (!safe_query_l('drop_index',"drop index crash_q")) { # Can't drop the standard way; Check if mSQL - if (safe_query("drop index crash_q from crash_me")) + if (safe_query_l('drop_index',"drop index crash_q from crash_me")) { $drop_res="with 'FROM'"; # Drop is not ANSI SQL $end_drop_keyword="drop index %i from %t"; } # else check if Access or MySQL - elsif (safe_query("drop index crash_q on crash_me")) + elsif (safe_query_l('drop_index',"drop index crash_q on crash_me")) { $drop_res="with 'ON'"; # Drop is not ANSI SQL $end_drop_keyword="drop index %i on %t"; } # else check if MS-SQL - elsif (safe_query("drop index crash_me.crash_q")) + elsif (safe_query_l('drop_index',"drop index crash_me.crash_q")) { $drop_res="with 'table.index'"; # Drop is not ANSI SQL $end_drop_keyword="drop index %t.%i"; @@ -1516,7 +1519,7 @@ if (!(defined($limits{'create_index'}) && defined($limits{'drop_index'}))) { # Old MySQL 3.21 supports only the create index syntax # This means that the second create doesn't give an error. - $res=safe_query(["create index crash_q on crash_me (a)", + $res=safe_query_l('create_index',["create index crash_q on crash_me (a)", "create index crash_q on crash_me (a)", "drop index crash_q"]); $res= $res ? 'ignored' : 'yes'; @@ -1760,17 +1763,17 @@ report("views","views", save_incomplete('foreign_key','foreign keys'); # 1) check if foreign keys are supported - safe_query(create_table("crash_me_qf",["a integer not null"], + safe_query_l('foreign_key',create_table("crash_me_qf",["a integer not null"], ["primary key (a)"])); - $error = safe_query( create_table("crash_me_qf2",["a integer not null", + $error = safe_query_l('foreign_key', create_table("crash_me_qf2",["a integer not null", "foreign key (a) references crash_me_qf (a)"], [])); if ($error eq 1) # OK -- syntax is supported { $resultat = 'error'; # now check if foreign key really works - safe_query( "insert into crash_me_qf values (1)"); - if (safe_query( "insert into crash_me_qf2 values (2)") eq 1) { + safe_query_l('foreign_key', "insert into crash_me_qf values (1)"); + if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1) { $resultat = 'syntax only'; } else { $resultat = 'yes'; @@ -1779,7 +1782,7 @@ report("views","views", } else { $resultat = "no"; } - safe_query( "drop table crash_me_qf2 $drop_attr","drop table crash_me_qf $drop_attr"); + safe_query_l('foreign_key', "drop table crash_me_qf2 $drop_attr","drop table crash_me_qf $drop_attr"); print "$resultat\n"; save_config_data('foreign_key',$resultat,"foreign keys"); } @@ -2056,6 +2059,7 @@ if ($limits{'create_index'} ne 'no') if ($limits{'create_index'} eq 'ignored' || $limits{'unique_in_create'} eq 'yes') { # This should be true + add_log('max_index'," max_unique_index=$limits{'max_unique_index'} ,so max_index must be same"); save_config_data('max_index',$limits{'max_unique_index'},"max index"); print "indexes: $limits{'max_index'}\n"; } @@ -2063,10 +2067,10 @@ if ($limits{'create_index'} ne 'no') { if (!defined($limits{'max_index'})) { - assert("create table crash_q ($key_definitions)"); + safe_query_l('max_index',"create table crash_q ($key_definitions)"); for ($i=1; $i <= min($limits{'max_columns'},$max_keys) ; $i++) { - last if (!safe_query("create index crash_q$i on crash_q (q$i)")); + last if (!safe_query_l('max_index',"create index crash_q$i on crash_q (q$i)")); } save_config_data('max_index',$i == $max_keys ? $max_keys : $i, "max index"); @@ -2082,10 +2086,10 @@ if ($limits{'create_index'} ne 'no') print "indexs: $limits{'max_index'}\n"; if (!defined($limits{'max_unique_index'})) { - assert("create table crash_q ($key_definitions)"); + safe_query_l('max_unique_index',"create table crash_q ($key_definitions)"); for ($i=0; $i < min($limits{'max_columns'},$max_keys) ; $i++) { - last if (!safe_query("create unique index crash_q$i on crash_q (q$i)")); + last if (!safe_query_l('max_unique_index',"create unique index crash_q$i on crash_q (q$i)")); } save_config_data('max_unique_index',$i == $max_keys ? $max_keys : $i, "max unique index"); @@ -2101,7 +2105,7 @@ if ($limits{'create_index'} ne 'no') print "unique indexes: $limits{'max_unique_index'}\n"; if (!defined($limits{'max_index_parts'})) { - assert("create table crash_q ($key_definitions)"); + safe_query_l('max_index_parts',"create table crash_q ($key_definitions)"); $end_drop=$end_drop_keyword; $end_drop =~ s/%i/crash_q1%d/; $end_drop =~ s/%t/crash_q/; @@ -2182,23 +2186,23 @@ if (!defined($limits{$key})) { print "$prompt="; save_incomplete($key,$prompt); - if (!safe_query($server->create("crash_me_a",["a decimal(10,2)","b decimal(10,2)"]))) + if (!safe_query_l($key,$server->create("crash_me_a",["a decimal(10,2)","b decimal(10,2)"]))) { print DBI->errstr(); die "Can't create table 'crash_me_a' $DBI::errstr\n"; }; - if (!safe_query(["insert into crash_me_a (a,b) values (11.4,18.9)"])) + if (!safe_query_l($key,["insert into crash_me_a (a,b) values (11.4,18.9)"])) { die "Can't insert into table 'crash_me_a' a record: $DBI::errstr\n"; }; $arithmetic_safe = 'no'; $arithmetic_safe = 'yes' - if ( (safe_query_result('select count(*) from crash_me_a where a+b=30.3',1,0) == 0) - and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0) - and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0) - and (safe_query_result('select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0) ); + if ( (safe_query_result_l($key,'select count(*) from crash_me_a where a+b=30.3',1,0) == 0) + and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0) + and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0) + and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0) ); save_config_data($key,$arithmetic_safe,$prompt); print "$arithmetic_safe\n"; assert("drop table crash_me_a $drop_attr"); @@ -2214,11 +2218,12 @@ if (!safe_query($server->create("crash_me_n",["i integer","r integer"]))) print DBI->errstr(); die "Can't create table 'crash_me_n' $DBI::errstr\n"; }; -assert("insert into crash_me_n (i) values(1)"); -assert("insert into crash_me_n values(2,2)"); -assert("insert into crash_me_n values(3,3)"); -assert("insert into crash_me_n values(4,4)"); -assert("insert into crash_me_n (i) values(5)"); + +safe_query_l("position_of_null",["insert into crash_me_n (i) values(1)", +"insert into crash_me_n values(2,2)", +"insert into crash_me_n values(3,3)", +"insert into crash_me_n values(4,4)", +"insert into crash_me_n (i) values(5)"]); $key = "position_of_null"; $prompt ="Where is null values in sorted recordset"; @@ -2228,7 +2233,8 @@ if (!defined($limits{$key})) print "$prompt="; $sth=$dbh->prepare("select r from crash_me_n order by r "); $sth->execute; - $limit= detect_null_position($sth); + add_log($key,"< select r from crash_me_n order by r "); + $limit= detect_null_position($key,$sth); $sth->finish; print "$limit\n"; save_config_data($key,$limit,$prompt); @@ -2244,7 +2250,8 @@ if (!defined($limits{$key})) print "$prompt="; $sth=$dbh->prepare("select r from crash_me_n order by r desc"); $sth->execute; - $limit= detect_null_position($sth); + add_log($key,"< select r from crash_me_n order by r desc"); + $limit= detect_null_position($key,$sth); $sth->finish; print "$limit\n"; save_config_data($key,$limit,$prompt); @@ -2269,18 +2276,31 @@ $dbh->disconnect || warn $dbh->errstr; save_all_config_data(); exit 0; +# End of test +# + +$dbh->do("drop table crash_me $drop_attr"); # Remove temporary table + +print "crash-me safe: $limits{'crash_me_safe'}\n"; +print "reconnected $reconnect_count times\n"; + +$dbh->disconnect || warn $dbh->errstr; +save_all_config_data(); +exit 0; + # Check where is nulls in the sorted result (for) # it expects exactly 5 rows in the result sub detect_null_position { + my $key = shift; my $sth = shift; my ($z,$r1,$r2,$r3,$r4,$r5); - $r1 = $sth->fetchrow_array; - $r2 = $sth->fetchrow_array; - $r3 = $sth->fetchrow_array; - $r4 = $sth->fetchrow_array; - $r5 = $sth->fetchrow_array; + $r1 = $sth->fetchrow_array; add_log($key,"> $r1"); + $r2 = $sth->fetchrow_array; add_log($key,"> $r2"); + $r3 = $sth->fetchrow_array; add_log($key,"> $r3"); + $r4 = $sth->fetchrow_array; add_log($key,"> $r4"); + $r5 = $sth->fetchrow_array; add_log($key,"> $r5"); return "first" if ( !defined($r1) && !defined($r2) && defined($r3)); return "last" if ( !defined($r5) && !defined($r4) && defined($r3)); return "random"; @@ -2291,16 +2311,24 @@ sub check_parenthesis { my $fn=shift; my $resultat='no'; my $param_name=$prefix.lc($fn); + my $r; save_incomplete($param_name,$fn); - if (safe_query("select $fn $end_query") == 1) + $r = safe_query("select $fn $end_query"); + add_log($param_name,$safe_query_log); + if ($r == 1) { $resultat="yes"; } - elsif ( safe_query("select $fn() $end_query") == 1) - { - $resultat="with_parenthesis"; + else{ + $r = safe_query("select $fn() $end_query"); + add_log($param_name,$safe_query_log); + if ( $r == 1) + { + $resultat="with_parenthesis"; + } } + save_config_data($param_name,$resultat,$fn); } @@ -2313,16 +2341,22 @@ sub check_constraint { save_incomplete($key,$prompt); print "$prompt="; my $res = 'no'; - - if ( ($t=safe_query($create)) == 1) + my $t; + $t=safe_query($create); + add_log($key,$safe_query_log); + if ( $t == 1) { $res='yes'; - if (safe_query($check) == 1) + $t= safe_query($check); + add_log($key,$safe_query_log); + if ($t == 1) { $res='syntax only'; } } safe_query($drop); + add_log($key,$safe_query_log); + save_config_data($key,$res,$prompt); print "$res\n"; } @@ -2633,6 +2667,15 @@ sub check_connect # # print query if debugging # +sub repr_query { + my $query=shift; + if (length($query) > 130) + { + $query=substr($query,0,120) . "...(" . (length($query)-120) . ")"; + } + return $query; +} + sub print_query { my ($query)=@_; @@ -2652,10 +2695,19 @@ sub print_query # Note that all rows are executed (to ensure that we execute drop table commands) # +sub safe_query_l { + my $key = shift; + my $q = shift; + my $r = safe_query($q); + add_log($key,$safe_query_log); + return $r; +} + sub safe_query { my($queries)=@_; my($query,$ok,$retry_ok,$retry,@tmp,$sth); + $safe_query_log=""; $ok=1; if (ref($queries) ne "ARRAY") { @@ -2666,9 +2718,11 @@ sub safe_query { printf "query1: %-80.80s ...(%d - %d)\n",$query,length($query),$retry_limit if ($opt_log_all_queries); print LOG "$query;\n" if ($opt_log); + $safe_query_log .= "< $query\n"; if (length($query) > $query_size) { $ok=0; + $safe_query_log .= "Query is too long\n"; next; } @@ -2678,6 +2732,7 @@ sub safe_query if (! ($sth=$dbh->prepare($query))) { print_query($query); + $safe_query_log .= "> couldn't prepare:". $dbh->errstr. "\n"; $retry=100 if (!$server->abort_if_fatal_error()); # Force a reconnect because of Access drop table bug! if ($retry == $retry_limit-2) @@ -2692,6 +2747,7 @@ sub safe_query if (!$sth->execute()) { print_query($query); + $safe_query_log .= "> execute error:". $dbh->errstr. "\n"; $retry=100 if (!$server->abort_if_fatal_error()); # Force a reconnect because of Access drop table bug! if ($retry == $retry_limit-2) @@ -2705,6 +2761,8 @@ sub safe_query { $retry = $retry_limit; $retry_ok = 1; + $safe_query_log .= "> OK\n"; + } $sth->finish; } @@ -2912,7 +2970,7 @@ sub check_reserved_words ); - $dbh->do("drop table crash_me10"); + safe_query("drop table crash_me10 $drop_attr"); foreach my $keyword (sort {$a cmp $b} keys %reserved_words) { @@ -2921,28 +2979,14 @@ sub check_reserved_words $prompt= "Keyword ".$keyword; $config= "reserved_word_".$keywords_ext[$keyword_type]."_".lc($keyword); - $dbh->{RaiseError}= 1; - - $answer= "yes"; - - eval { - $dbh->do("create table crash_me10 ($keyword int not null)"); - }; - - $dbh->{RaiseError}= 0; - - if (!$@) - { - $answer= "no"; - $dbh->do("drop table crash_me10"); - } - - save_config_data($config,$answer,$prompt); - + report_fail($prompt,$config, + "create table crash_me10 ($keyword int not null)", + "drop table crash_me10 $drop_attr" + ); print "$prompt: ",$limits{$config},"\n"; } } - + # # Do a query on a query package object. # @@ -3002,7 +3046,17 @@ sub report print "$prompt: "; if (!defined($limits{$limit})) { - save_config_data($limit,safe_query(\@queries) ? "yes" : "no",$prompt); + my $queries_result = safe_query(\@queries); + add_log($limit, $safe_query_log); + my $report_result; + if ( $queries_result) { + $report_result= "yes"; + add_log($limit,"As far as all queries returned OK, result is YES"); + } else { + $report_result= "no"; + add_log($limit,"As far as some queries didnt return OK, result is NO"); + } + save_config_data($limit,$report_result,$prompt); } print "$limits{$limit}\n"; return $limits{$limit} ne "no"; @@ -3014,7 +3068,17 @@ sub report_fail print "$prompt: "; if (!defined($limits{$limit})) { - save_config_data($limit,safe_query(\@queries) ? "no" : "yes",$prompt); + my $queries_result = safe_query(\@queries); + add_log($limit, $safe_query_log); + my $report_result; + if ( $queries_result) { + $report_result= "no"; + add_log($limit,"As far as all queries returned OK, result is NO"); + } else { + $report_result= "yes"; + add_log($limit,"As far as some queries didnt return OK, result is YES"); + } + save_config_data($limit,$report_result,$prompt); } print "$limits{$limit}\n"; return $limits{$limit} ne "no"; @@ -3034,7 +3098,7 @@ sub report_one $result="no"; foreach $query (@$queries) { - if (safe_query($query->[0])) + if (safe_query_l($limit,$query->[0])) { $result= $query->[1]; last; @@ -3058,6 +3122,7 @@ sub report_result { save_incomplete($limit,$prompt); $error=safe_query_result($query,"1",2); + add_log($limit,$safe_query_result_log); save_config_data($limit,$error ? "not supported" :$last_result,$prompt); } print "$limits{$limit}\n"; @@ -3078,16 +3143,19 @@ sub report_trans $dbh->rollback; $dbh->{AutoCommit} = 1; if (safe_query_result($check,"","")) { + add_log($limit,$safe_query_result_log); save_config_data($limit,"yes",$limit); } safe_query($clear); } else { + add_log($limit,$safe_query_log); save_config_data($limit,"error",$limit); } $dbh->{AutoCommit} = 1; } else { + add_log($limit,"Couldnt undef autocommit ?? "); save_config_data($limit,"no",$limit); } safe_query($clear); @@ -3106,20 +3174,26 @@ sub report_rollback { if (safe_query(\@$queries)) { + add_log($limit,$safe_query_log); + $dbh->rollback; $dbh->{AutoCommit} = 1; if (safe_query($check)) { + add_log($limit,$safe_query_log); save_config_data($limit,"no",$limit); } else { + add_log($limit,$safe_query_log); save_config_data($limit,"yes",$limit); }; safe_query($clear); } else { + add_log($limit,$safe_query_log); save_config_data($limit,"error",$limit); } } else { + add_log($limit,'Couldnt undef Autocommit??'); save_config_data($limit,"error",$limit); } safe_query($clear); @@ -3141,8 +3215,14 @@ sub check_and_report { save_incomplete($limit,$prompt); $tmp=1-safe_query(\@$pre); - $tmp=safe_query_result($query,$answer,$string_type) if (!$tmp); + add_log($limit,$safe_query_log); + if (!$tmp) + { + $tmp=safe_query_result($query,$answer,$string_type) ; + add_log($limit,$safe_query_result_log); + }; safe_query(\@$post); + add_log($limit,$safe_query_log); delete $limits{$limit}; if ($function == 3) # Report error as 'no'. { @@ -3180,7 +3260,7 @@ sub try_and_report foreach $test (@tests) { my $tmp_type= shift(@$test); - if (safe_query(\@$test)) + if (safe_query_l($limit,\@$test)) { $type=$tmp_type; goto outer; @@ -3199,32 +3279,44 @@ sub try_and_report sub execute_and_check { - my ($pre,$query,$post,$answer,$string_type)=@_; + my ($key,$pre,$query,$post,$answer,$string_type)=@_; my ($tmp); - $tmp=safe_query(\@$pre); - $tmp=safe_query_result($query,$answer,$string_type) == 0 if ($tmp); - safe_query(\@$post); + $tmp=safe_query_l($key,\@$pre); + + $tmp=safe_query_result_l($key,$query,$answer,$string_type) == 0 if ($tmp); + safe_query_l($key,\@$post); return $tmp; } # returns 0 if ok, 1 if error, -1 if wrong answer # Sets $last_result to value of query +sub safe_query_result_l{ + my ($key,$query,$answer,$result_type)=@_; + my $r = safe_query_result($query,$answer,$result_type); + add_log($key,$safe_query_result_log); + return $r; +} sub safe_query_result { my ($query,$answer,$result_type)=@_; my ($sth,$row,$result,$retry); undef($last_result); - + $safe_query_result_log=""; + printf "\nquery3: %-80.80s\n",$query if ($opt_log_all_queries); print LOG "$query;\n" if ($opt_log); + $safe_query_result_log="<".$query."\n"; + for ($retry=0; $retry < $retry_limit ; $retry++) { if (!($sth=$dbh->prepare($query))) { print_query($query); + $safe_query_result_log .= "> prepare failed:".$dbh->errstr."\n"; + if ($server->abort_if_fatal_error()) { check_connect(); # Check that server is still up @@ -3236,6 +3328,7 @@ sub safe_query_result if (!$sth->execute) { print_query($query); + $safe_query_result_log .= "> execute failed:".$dbh->errstr."\n"; if ($server->abort_if_fatal_error()) { check_connect(); # Check that server is still up @@ -3252,6 +3345,7 @@ sub safe_query_result if (!($row=$sth->fetchrow_arrayref)) { print "\nquery: $query didn't return any result\n" if ($opt_debug); + $safe_query_result_log .= "> didn't return any result:".$dbh->errstr."\n"; $sth->finish; return ($result_type == 8) ? 0 : 1; } @@ -3262,7 +3356,7 @@ sub safe_query_result } $result=0; # Ok $last_result= $row->[0]; # Save for report_result; - + $safe_query_result_log .= ">".$last_result."\n"; # Note: # if ($result_type == 2) We accept any return value as answer @@ -3273,34 +3367,55 @@ sub safe_query_result (abs($row->[0]) + abs($answer))) > 0.01) { $result=-1; + $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; } } elsif ($result_type == 1) # Compare where end space may differ { $row->[0] =~ s/\s+$//; - $result=-1 if ($row->[0] ne $answer); + if ($row->[0] ne $answer) + { + $result=-1; + $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; + } ; } elsif ($result_type == 3) # This should be a exact match { - $result= -1 if ($row->[0] ne $answer); + if ($row->[0] ne $answer) + { + $result= -1; + $safe_query_result_log .= "we expected '$answer' but got '$last_result' \n"; + }; } elsif ($result_type == 4) # If results should be NULL { - $result= -1 if (defined($row->[0])); + if (defined($row->[0])) + { + $result= -1; + $safe_query_result_log .= "We expected NULL but got '$last_result' \n"; + }; } elsif ($result_type == 5) # Result should have given prefix { - $result= -1 if (length($row->[0]) < length($answer) && - substr($row->[0],1,length($answer)) ne $answer); + if (length($row->[0]) < length($answer) && + substr($row->[0],1,length($answer)) ne $answer) + { + $result= -1 ; + $safe_query_result_log .= "result must have prefix '$answer', but '$last_result' \n"; + }; } elsif ($result_type == 6) # Exact match but ignore errors { - $result= 1 if ($row->[0] ne $answer); + if ($row->[0] ne $answer) + { $result= 1; + $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; + } ; } elsif ($result_type == 7) # Compare against array of numbers { if ($row->[0] != $answer->[0]) { + $safe_query_result_log .= "must be '$answer->[0]' \n"; $result= -1; } else @@ -3309,16 +3424,20 @@ sub safe_query_result shift @$answer; while (($row=$sth->fetchrow_arrayref)) { + $safe_query_result_log .= ">$row\n"; + $value=shift(@$answer); if (!defined($value)) { print "\nquery: $query returned to many results\n" if ($opt_debug); + $safe_query_result_log .= "It returned to many results \n"; $result= 1; last; } if ($row->[0] != $value) { + $safe_query_result_log .= "Must return $value here \n"; $result= -1; last; } @@ -3327,6 +3446,7 @@ sub safe_query_result { print "\nquery: $query returned too few results\n" if ($opt_debug); + $safe_query_result_log .= "It returned too few results \n"; $result= 1; } } @@ -3345,7 +3465,7 @@ sub safe_query_result sub find_limit() { my ($prompt,$limit,$query)=@_; - my ($first,$end,$i,$tmp); + my ($first,$end,$i,$tmp,@tmp_array, $queries); print "$prompt: "; if (defined($end=$limits{$limit})) { @@ -3353,10 +3473,30 @@ sub find_limit() return $end; } save_incomplete($limit,$prompt); + add_log($limit,"We are trying (example with N=5):"); + $queries = $query->query(5); + if (ref($queries) ne "ARRAY") + { + push(@tmp_array,$queries); + $queries= \@tmp_array; + } + foreach $tmp (@$queries) + { add_log($limit,repr_query($tmp)); } + if (defined($queries = $query->check_query())) + { + if (ref($queries) ne "ARRAY") + { + @tmp_array=(); + push(@tmp_array,$queries); + $queries= \@tmp_array; + } + foreach $tmp (@$queries) + { add_log($limit,repr_query($tmp)); } + } if (defined($query->{'init'}) && !defined($end=$limits{'restart'}{'tohigh'})) { - if (!safe_query($query->{'init'})) + if (!safe_query_l($limit,$query->{'init'})) { $query->cleanup(); return "error"; @@ -3384,7 +3524,7 @@ sub find_limit() $end= $query->max_limit(); $i=int(($end+$first)/2); } - + my $log_str = ""; unless(limit_query($query,0+$end)) { while ($first < $end) { @@ -3393,11 +3533,13 @@ sub find_limit() if (limit_query($query,$i)) { $first=$i; + $log_str .= " $i:OK"; $i=$first+int(($end-$first+1)/2); # to be a bit faster to go up } else - { + { $end=$i-1; + $log_str .= " $i:FAIL"; $i=$first+int(($end-$first+4)/5); # Prefere lower on errors } } @@ -3409,6 +3551,7 @@ sub find_limit() $end= $query->{'max_limit'}; } print "$end\n"; + add_log($limit,$log_str); save_config_data($limit,$end,$prompt); delete $limits{'restart'}; return $end; @@ -3460,6 +3603,7 @@ sub read_config_data { $limits{$key}=$limit eq "null"? undef : $limit; $prompts{$key}=length($prompt) ? substr($prompt,2) : ""; + $last_read=$key; delete $limits{'restart'}; } else @@ -3473,6 +3617,11 @@ sub read_config_data } } } + elsif (/\s*###(.*)$/) # log line + { + # add log line for previously read key + $log{$last_read} .= "$1\n"; + } elsif (!/^\s*$/ && !/^\#/) { die "Wrong config row: $_\n"; @@ -3494,6 +3643,18 @@ sub save_config_data print CONFIG_FILE "$key=$limit\t# $prompt\n"; $limits{$key}=$limit; $limit_changed=1; +# now write log lines (immediatelly after limits) + my $line; + my $last_line_was_empty=0; + foreach $line (split /\n/, $log{$key}) + { + print CONFIG_FILE " ###$line\n" + unless ( ($last_line_was_empty eq 1) + && ($line =~ /^\s+$/) ); + $last_line_was_empty= ($line =~ /^\s+$/)?1:0; + + }; + if (($opt_restart && $limits{'operating_system'} =~ /windows/i) || ($limits{'operating_system'} =~ /NT/)) { @@ -3504,6 +3665,12 @@ sub save_config_data } } +sub add_log +{ + my $key = shift; + my $line = shift; + $log{$key} .= $line . "\n"; +} sub save_all_config_data { @@ -3523,6 +3690,16 @@ sub save_all_config_data $tmp="$key=$limits{$key}"; print CONFIG_FILE $tmp . ("\t" x (int((32-min(length($tmp),32)+7)/8)+1)) . "# $prompts{$key}\n"; + my $line; + my $last_line_was_empty=0; + foreach $line (split /\n/, $log{$key}) + { + print CONFIG_FILE " ###$line\n" + unless ( ($last_line_was_empty eq 1) + && ($line =~ /^\s+$/) ); + $last_line_was_empty= ($line =~ /^\s+$/)?1:0; + + }; } close CONFIG_FILE; } @@ -3800,7 +3977,6 @@ sub new bless $self; } - sub query { my ($self,$i)=@_; diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index 247fd6c116d..31b8628ad79 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -1,4 +1,5 @@ #!@PERL@ +# -*- perl -*- # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB # # This library is free software; you can redistribute it and/or @@ -671,9 +672,9 @@ sub create $field =~ s/int\(\d*\)/int/; $field =~ s/float\(\d*,\d*\)/float/; $field =~ s/ double/ float/; - $field =~ s/ decimal/ float/i; - $field =~ s/ big_decimal/ float/i; - $field =~ s/ date/ int/i; +# $field =~ s/ decimal/ float/i; +# $field =~ s/ big_decimal/ float/i; +# $field =~ s/ date/ int/i; # Pg doesn't have blob, it has text instead $field =~ s/ blob/ text/; $query.= $field . ','; @@ -946,9 +947,9 @@ sub create $field =~ s/ double/ float/i; # Solid doesn't have blob, it has long varchar $field =~ s/ blob/ long varchar/; - $field =~ s/ decimal/ float/i; - $field =~ s/ big_decimal/ float/i; - $field =~ s/ date/ int/i; +# $field =~ s/ decimal/ float/i; +# $field =~ s/ big_decimal/ float/i; +# $field =~ s/ date/ int/i; $query.= $field . ','; } substr($query,-1)=")"; # Remove last ','; @@ -1194,9 +1195,9 @@ sub create $field =~ s/ blob/ text/; $field =~ s/ varchar\((\d+)\)/ char($1,3)/; $field =~ s/ char\((\d+)\)/ char($1,3)/; - $field =~ s/ decimal/ float/i; - $field =~ s/ big_decimal/ longfloat/i; - $field =~ s/ date/ int/i; +# $field =~ s/ decimal/ float/i; +# $field =~ s/ big_decimal/ longfloat/i; +# $field =~ s/ date/ int/i; $field =~ s/ float(.*)/ float/i; if ($field =~ / int\((\d+)\)/) { if ($1 > 4) { @@ -2896,8 +2897,8 @@ sub create $query="create table $table_name ("; foreach $field (@$fields) { - $field =~ s/ decimal/ double(10,2)/i; - $field =~ s/ big_decimal/ double(10,2)/i; +# $field =~ s/ decimal/ double(10,2)/i; +# $field =~ s/ big_decimal/ double(10,2)/i; $field =~ s/ tinyint\(.*\)/ smallint/i; $field =~ s/ smallint\(.*\)/ smallint/i; $field =~ s/ mediumint/ integer/i; @@ -3092,7 +3093,7 @@ sub create $query="create table $table_name ("; foreach $field (@$fields) { - $field =~ s/ big_decimal/ decimal/i; +# $field =~ s/ big_decimal/ decimal/i; $field =~ s/ double/ double precision/i; $field =~ s/ tinyint/ smallint/i; $field =~ s/ mediumint/ integer/i; From e003d42e4af56c5785010f1f2426bd5bfa778ba3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Dec 2002 22:16:57 +0200 Subject: [PATCH 39/61] fix for a bug in CASE ...WHEN ... sql/sql_db.cc: fix for lower case ... --- mysql-test/r/case.result | 4 ++++ mysql-test/t/case.test | 5 +++++ sql/item_cmpfunc.cc | 2 ++ sql/sql_db.cc | 2 -- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 073164aa035..9ba33daaa4d 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -40,3 +40,7 @@ fcase count(*) nothing 2 one 1 two 1 +color +orange +yellow +green diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index 79511f5f546..f2b8d42e07c 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -30,3 +30,8 @@ insert into t1 values(1),(2),(3),(4); select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase; select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase; drop table t1; +drop table if exists t; +create table t1 (row int not null, col int not null, val varchar(255) not null); +insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); +select max(case col when 1 then val else null end) as color from t1 group by row; +drop table if exists t; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 07704e3385f..0d10b17ad87 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -687,6 +687,8 @@ String *Item_func_case::val_str(String *str) } if (!(res=item->val_str(str))) null_value=1; + else + null_value=item->null_value; return res; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e61a2aa60c5..338d3161bd4 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -371,8 +371,6 @@ bool mysql_change_db(THD *thd,const char *name) } send_ok(&thd->net); x_free(thd->db); - if (lower_case_table_names) - casedn_str(dbname); thd->db=dbname; thd->db_access=db_access; DBUG_RETURN(0); From 53239a714a17549863330facf3a8ea3bf74924c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Dec 2002 19:00:00 +0200 Subject: [PATCH 40/61] Fix for found rows in multi-table updates --- mysql-test/r/multi_update.result | 10 ++++++++++ mysql-test/t/multi_update.test | 10 ++++++++++ sql/sql_update.cc | 5 ++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 8cf035343b1..fe028a4cb95 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -236,3 +236,13 @@ n d 1 30 1 30 drop table t1,t2; +drop table if exists t1,t2,t3; +CREATE TABLE t1 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t1 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'),(10,''),(11,''),(12,''),(13,''); +CREATE TABLE t2 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t2 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'); +CREATE TABLE t3 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t3 VALUES (1,'jedan'),(2,'dva'); +update t1,t2 set t1.naziv="aaaa" where t1.broj=t2.broj; +update t1,t2,t3 set t1.naziv="bbbb", t2.naziv="aaaa" where t1.broj=t2.broj and t2.broj=t3.broj; +drop table if exists t1,t2,t3; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index ff456b710c1..088b355a17c 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -214,3 +214,13 @@ UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n; select * from t1; select * from t2; drop table t1,t2; +drop table if exists t1,t2,t3; +CREATE TABLE t1 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t1 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'),(10,''),(11,''),(12,''),(13,''); +CREATE TABLE t2 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t2 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'); +CREATE TABLE t3 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM; +INSERT INTO t3 VALUES (1,'jedan'),(2,'dva'); +update t1,t2 set t1.naziv="aaaa" where t1.broj=t2.broj; +update t1,t2,t3 set t1.naziv="bbbb", t2.naziv="aaaa" where t1.broj=t2.broj and t2.broj=t3.broj; +drop table if exists t1,t2,t3; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 8a349671c50..9817dcd2be5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -614,7 +614,6 @@ bool multi_update::send_data(List ¬_used_values) TABLE_LIST *cur_table; DBUG_ENTER("multi_update::send_data"); - found++; for (cur_table= update_tables; cur_table ; cur_table= cur_table->next) { TABLE *table= cur_table->table; @@ -630,6 +629,7 @@ bool multi_update::send_data(List ¬_used_values) store_record(table,1); if (fill_record(*fields_for_table[offset], *values_for_table[offset])) DBUG_RETURN(1); + found++; if (compare_record(table, thd->query_id)) { int error; @@ -656,7 +656,7 @@ bool multi_update::send_data(List ¬_used_values) int error; TABLE *tmp_table= tmp_tables[offset]; fill_record(tmp_table->field+1, *values_for_table[offset]); - + found++; /* Store pointer to row */ memcpy((char*) tmp_table->field[0]->ptr, (char*) table->file->ref, table->file->ref_length); @@ -754,7 +754,6 @@ int multi_update::do_updates(bool from_send_error) continue; // May happen on dup key goto err; } - found++; if ((local_error= table->file->rnd_pos(table->record[0], ref_pos))) goto err; table->status|= STATUS_UPDATED; From 4debc215006816d68ea921580d3f38fc77879767 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Dec 2002 00:38:38 +0500 Subject: [PATCH 41/61] crash-me.sh: Wrap long lines, New test - date_format_inresult (returns which date format dbms uses in the result set) New tests: -date_format_ISO -date_format_ISO_with_date (checks if DBMS supports YYYY-MM-DD or DATE 'YYYY-MM-DD' formats) -date_format_EUR -date_format_EUR_with_date (the same but 'DD.MM.YYYY' format) -date_format_USA -date_format_USA_with_date ( the same but 'MM/DD/YYYY' format) -date_format_YYYYMMDD -date_format_YYYYMMDD_with_date sql-bench/crash-me.sh: Wrap long lines, New test - date_format_inresult (returns which date format dbms uses in the result set) New tests: -date_format_ISO -date_format_ISO_with_date (checks if DBMS supports YYYY-MM-DD or DATE 'YYYY-MM-DD' formats) -date_format_EUR -date_format_EUR_with_date (the same but 'DD.MM.YYYY' format) -date_format_USA -date_format_USA_with_date ( the same but 'MM/DD/YYYY' format) -date_format_YYYYMMDD -date_format_YYYYMMDD_with_date --- sql-bench/crash-me.sh | 817 +++++++++++++++++++++++++++++------------- 1 file changed, 569 insertions(+), 248 deletions(-) diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index 8f49da917c3..adea23c5884 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -64,11 +64,16 @@ $limits{'operating_system'}= machine(); $prompts{'operating_system'}='crash-me tested on'; $retry_limit=3; -GetOptions("Information","help","server=s","debug","user=s","password=s","database=s","restart","force","quick","log-all-queries","comment=s","host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s","batch-mode","config-file=s","log-queries-to-file=s","check-server") || usage(); +GetOptions("Information","help","server=s","debug","user=s","password=s", +"database=s","restart","force","quick","log-all-queries","comment=s", +"host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s", +"batch-mode","config-file=s","log-queries-to-file=s","check-server") + || usage(); usage() if ($opt_help || $opt_Information); $opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0); -$opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg" if (length($opt_config_file) == 0); +$opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg" + if (length($opt_config_file) == 0); $log_prefix=' ###'; # prefix for log lines in result file $safe_query_log=''; $safe_query_result_log=''; @@ -121,7 +126,8 @@ if (length($opt_comment)) $opt_log=0; if (length($opt_log_queries_to_file)) { - open(LOG,">$opt_log_queries_to_file") || die "Can't open file $opt_log_queries_to_file\n"; + open(LOG,">$opt_log_queries_to_file") || + die "Can't open file $opt_log_queries_to_file\n"; $opt_log=1; } @@ -172,11 +178,13 @@ $prompt="drop table require cascade/restrict"; $drop_attr=""; $dbh->do("drop table crash_me"); $dbh->do("drop table crash_me cascade"); -if (!safe_query_l('drop_requires_cascade',["create table crash_me (a integer not null)", +if (!safe_query_l('drop_requires_cascade', + ["create table crash_me (a integer not null)", "drop table crash_me"])) { $dbh->do("drop table crash_me cascade"); - if (safe_query_l('drop_requires_cascade',["create table crash_me (a integer not null)", + if (safe_query_l('drop_requires_cascade', + ["create table crash_me (a integer not null)", "drop table crash_me cascade"])) { save_config_data('drop_requires_cascade',"yes","$prompt"); @@ -201,11 +209,14 @@ $dbh->do("drop table crash_q $drop_attr"); $dbh->do("drop table crash_q1 $drop_attr"); $prompt="Tables without primary key"; -if (!safe_query_l('no_primary_key',["create table crash_me (a integer not null,b char(10) not null)", +if (!safe_query_l('no_primary_key', + ["create table crash_me (a integer not null,b char(10) not null)", "insert into crash_me (a,b) values (1,'a')"])) { - if (!safe_query_l('no_primary_key',["create table crash_me (a integer not null,b char(10) not null, primary key (a))", - "insert into crash_me (a,b) values (1,'a')"])) + if (!safe_query_l('no_primary_key', + ["create table crash_me (a integer not null,b char(10) not null". + ", primary key (a))", + "insert into crash_me (a,b) values (1,'a')"])) { die "Can't create table 'crash_me' with one record: $DBI::errstr\n"; } @@ -328,8 +339,10 @@ try_and_report("LIMIT number of rows","select_limit", "select * from crash_me limit 1"], ["with TOP", "select TOP 1 * from crash_me"]); -report("SELECT with LIMIT #,#","select_limit2", "select * from crash_me limit 1,1"); -report("SELECT with LIMIT # OFFSET #","select_limit3", "select * from crash_me limit 1 offset 1"); +report("SELECT with LIMIT #,#","select_limit2", + "select * from crash_me limit 1,1"); +report("SELECT with LIMIT # OFFSET #", + "select_limit3", "select * from crash_me limit 1 offset 1"); # The following alter table commands MUST be kept together! if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))")) @@ -351,7 +364,8 @@ if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))")) "alter table crash_q alter b set default 10"); report_one("Alter table drop column",'alter_drop_col', [["alter table crash_q drop column b","yes"], - ["alter table crash_q drop column b restrict","with restrict/cascade"]]); + ["alter table crash_q drop column b restrict", + "with restrict/cascade"]]); report("Alter table rename table",'alter_rename_table', "alter table crash_q rename to crash_q1"); } @@ -373,13 +387,14 @@ report("truncate","truncate_table", "drop table crash_q $drop_attr"); if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))") && - $dbh->do("create table crash_q1 (a integer, b integer,c1 CHAR(10) not null)")) + $dbh->do("create table crash_q1 (a integer, b integer,c1 CHAR(10) not null)")) { report("Alter table add constraint",'alter_add_constraint', "alter table crash_q add constraint c2 check(a > b)"); report_one("Alter table drop constraint",'alter_drop_constraint', [["alter table crash_q drop constraint c2","yes"], - ["alter table crash_q drop constraint c2 restrict","with restrict/cascade"]]); + ["alter table crash_q drop constraint c2 restrict", + "with restrict/cascade"]]); report("Alter table add unique",'alter_add_unique', "alter table crash_q add constraint u1 unique(c1)"); try_and_report("Alter table drop unique",'alter_drop_unique', @@ -395,7 +410,8 @@ if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))") && ["with add primary key", "alter table crash_q1 add primary key(c1)"]); report("Alter table add foreign key",'alter_add_foreign_key', - "alter table crash_q add constraint f1 foreign key(c1) references crash_q1(c1)"); + "alter table crash_q add constraint f1 foreign key(c1)", + " references crash_q1(c1)"); try_and_report("Alter table drop foreign key",'alter_drop_foreign_key', ["with drop constraint", "alter table crash_q drop constraint f1"], @@ -426,10 +442,12 @@ check_and_report("Group on column with null values",'group_by_null', $prompt="Having"; if (!defined($limits{'having'})) { # Complicated because of postgreSQL - if (!safe_query_result_l("having","select a from crash_me group by a having a > 0",1,0)) + if (!safe_query_result_l("having", + "select a from crash_me group by a having a > 0",1,0)) { - if (!safe_query_result_l("having","select a from crash_me group by a having a < 0", - 1,0)) + if (!safe_query_result_l("having", + "select a from crash_me group by a having a < 0", + 1,0)) { save_config_data("having","error",$prompt); } else { save_config_data("having","yes",$prompt); } @@ -516,7 +534,8 @@ else if ($i == 0) { - print "Can't connect to server: $DBI::errstr. Please start it and try again\n"; + print "Can't connect to server: $DBI::errstr.". + " Please start it and try again\n"; exit 1; } $dbh=safe_connect(); @@ -549,7 +568,9 @@ if (!defined($limits{'query_size'})) } for ($i=$first ; $i < $end ; $i*=2) { - last if (!safe_query($query . (" " x ($i - length($query)-length($end_query) -1)) . "$select$end_query")); + last if (!safe_query($query . + (" " x ($i - length($query)-length($end_query) -1)) + . "$select$end_query")); $first=$i; save_config_data("restart",$i,"") if ($opt_restart); } @@ -599,7 +620,8 @@ check_reserved_words($dbh); "interval month", "interval day", "interval day to hour", "interval day to minute", "interval day to second", - "interval hour", "interval hour to minute", "interval hour to second", + "interval hour", "interval hour to minute", + "interval hour to second", "interval minute", "interval minute to second", "interval second", "national character varying(20)", @@ -664,6 +686,7 @@ foreach $types (@types) # Test some type limits # + check_and_report("Remembers end space in char()","remember_end_space", ["create table crash_q (a char(10))", "insert into crash_q values('hello ')"], @@ -679,55 +702,6 @@ check_and_report("Remembers end space in varchar()", ["drop table crash_q $drop_attr"], 'hello ',6); -check_and_report("Supports 0000-00-00 dates","date_zero", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values ('0000-00-00')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "0000-00-00",1); - -check_and_report("Supports 0001-01-01 dates","date_one", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values (DATE '0001-01-01')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "0001-01-01",1); - -check_and_report("Supports 9999-12-31 dates","date_last", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values (DATE '9999-12-31')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "9999-12-31",1); - -check_and_report("Supports 'infinity dates","date_infinity", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values ('infinity')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "infinity",1); - -if (!defined($limits{'date_with_YY'})) -{ - check_and_report("Supports YY-MM-DD dates","date_with_YY", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values ('98-03-03')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "1998-03-03",5); - if ($limits{'date_with_YY'} eq "yes") - { - undef($limits{'date_with_YY'}); - check_and_report("Supports YY-MM-DD 2000 compilant dates", - "date_with_YY", - ["create table crash_me2 (a date not null)", - "insert into crash_me2 values ('10-03-03')"], - "select a from crash_me2", - ["drop table crash_me2 $drop_attr"], - "2010-03-03",5); - } -} - if (($limits{'type_extra_float(2_arg)'} eq "yes" || $limits{'type_sql_decimal(2_arg)'} eq "yes") && (!defined($limits{'storage_of_float'}))) @@ -775,13 +749,17 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" || try_and_report("Type for row id", "rowid", ["rowid", - "create table crash_q (a rowid)","drop table crash_q $drop_attr"], + "create table crash_q (a rowid)", + "drop table crash_q $drop_attr"], ["auto_increment", - "create table crash_q (a int not null auto_increment, primary key(a))","drop table crash_q $drop_attr"], + "create table crash_q (a int not null auto_increment". + ", primary key(a))","drop table crash_q $drop_attr"], ["oid", - "create table crash_q (a oid, primary key(a))","drop table crash_q $drop_attr"], + "create table crash_q (a oid, primary key(a))", + "drop table crash_q $drop_attr"], ["serial", - "create table crash_q (a serial, primary key(a))","drop table crash_q $drop_attr"]); + "create table crash_q (a serial, primary key(a))", + "drop table crash_q $drop_attr"]); try_and_report("Automatic row id", "automatic_rowid", ["_rowid", @@ -798,21 +776,26 @@ try_and_report("Automatic row id", "automatic_rowid", (["+, -, * and /","+","5*3-4/2+1",14,0], ["ANSI SQL SUBSTRING","substring","substring('abcd' from 2 for 2)","bc",1], ["BIT_LENGTH","bit_length","bit_length('abc')",24,0], - ["searched CASE","searched_case","case when 1 > 2 then 'false' when 2 > 1 then 'true' end", "true",1], - ["simple CASE","simple_case","case 2 when 1 then 'false' when 2 then 'true' end", "true",1], + ["searched CASE","searched_case", + "case when 1 > 2 then 'false' when 2 > 1 then 'true' end", "true",1], + ["simple CASE","simple_case", + "case 2 when 1 then 'false' when 2 then 'true' end", "true",1], ["CAST","cast","CAST(1 as CHAR)","1",1], ["CHARACTER_LENGTH","character_length","character_length('abcd')","4",0], ["CHAR_LENGTH","char_length","char_length(b)","10",0], - ["CHAR_LENGTH(constant)","char_length(constant)","char_length('abcd')","4",0], + ["CHAR_LENGTH(constant)","char_length(constant)", + "char_length('abcd')","4",0], ["COALESCE","coalesce","coalesce($char_null,'bcd','qwe')","bcd",1], ["CURRENT_DATE","current_date","current_date",0,2], ["CURRENT_TIME","current_time","current_time",0,2], ["CURRENT_TIMESTAMP","current_timestamp","current_timestamp",0,2], - ["EXTRACT","extract_sql","extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0], + ["EXTRACT","extract_sql", + "extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0], ["LOCALTIME","localtime","localtime",0,2], ["LOCALTIMESTAMP","localtimestamp","localtimestamp",0,2], ["LOWER","lower","LOWER('ABC')","abc",1], - ["NULLIF with strings","nullif_string","NULLIF(NULLIF('first','second'),'first')",undef(),4], + ["NULLIF with strings","nullif_string", + "NULLIF(NULLIF('first','second'),'first')",undef(),4], ["NULLIF with numbers","nullif_num","NULLIF(NULLIF(1,2),1)",undef(),4], ["OCTET_LENGTH","octet_length","octet_length('abc')",3,0], ["POSITION","position","position('ll' in 'hello')",3,0], @@ -869,14 +852,6 @@ try_and_report("Automatic row id", "automatic_rowid", ["TRUNCATE","truncate","truncate(18.18,-1)",10,0], ["NOW","now","now()",0,2], # Any value is acceptable ["CURDATE","curdate","curdate()",0,2], - ["DAYNAME","dayname","dayname(DATE '1997-02-01')","",2], - ["MONTH","month","month(DATE '1997-02-01')","",2], - ["MONTHNAME","monthname","monthname(DATE '1997-02-01')","",2], - ["DAYOFMONTH","dayofmonth","dayofmonth(DATE '1997-02-01')",1,0], - ["DAYOFWEEK","dayofweek","dayofweek(DATE '1997-02-01')",7,0], - ["DAYOFYEAR","dayofyear","dayofyear(DATE '1997-02-01')",32,0], - ["QUARTER","quarter","quarter(DATE '1997-02-01')",1,0], - ["YEAR","year","year(DATE '1997-02-01')",1997,0], ["CURTIME","curtime","curtime()",0,2], ["HOUR","hour","hour('12:13:14')",12,0], ["ANSI HOUR","hour_time","hour(TIME '12:13:14')",12,0], @@ -886,7 +861,8 @@ try_and_report("Automatic row id", "automatic_rowid", "timestampadd(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')", "1997-01-01 00:00:01",1], ["TIMESTAMPDIFF","timestampdiff", - "timestampdiff(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')","1",0], + "timestampdiff(SQL_TSI_SECOND,'1997-01-01 00:00:02',". + " '1997-01-01 00:00:01')","1",0], ["USER()","user()","user()",0,2], ["DATABASE","database","database()",0,2], ["IFNULL","ifnull","ifnull(2,3)",2,0], @@ -902,7 +878,6 @@ try_and_report("Automatic row id", "automatic_rowid", ["<> in SELECT","<>","1<>1","0",0], ["=","=","(1=1)",1,$logical_value], ["~* (case insensitive compare)","~*","'hi' ~* 'HI'",1,$logical_value], - ["ADD_MONTHS","add_months","add_months('1997-01-01',1)","1997-02-01",0], # oracle the date plus n months ["AND and OR in SELECT","and_or","1=1 AND 2=2",$logical_value,0], ["AND as '&&'",'&&',"1=1 && 2=2",$logical_value,0], ["ASCII_CHAR", "ascii_char", "ASCII_CHAR(65)","A",1], @@ -916,40 +891,38 @@ try_and_report("Automatic row id", "automatic_rowid", ["CONCAT(list)","concat_list", "concat('a','b','c','d')","abcd",1], ["CONVERT","convert","convert(CHAR,5)","5",1], ["COSH","cosh","cosh(0)","1",0], # oracle hyperbolic cosine of n. - ["DATEADD","dateadd","dateadd(day,3,'Nov 30 1997')",0,2], - ["DATEDIFF","datediff","datediff(month,'Oct 21 1997','Nov 30 1997')",0,2], - ["DATENAME","datename","datename(month,'Nov 30 1997')",0,2], - ["DATEPART","datepart","datepart(month,'July 20 1997')",0,2], - ["DATE_FORMAT","date_format", "date_format('1997-01-02 03:04:05','M W D Y y m d h i s w')", 0,2], ["ELT","elt","elt(2,'ONE','TWO','THREE')","TWO",1], ["ENCRYPT","encrypt","encrypt('hello')",0,2], ["FIELD","field","field('IBM','NCA','ICL','SUN','IBM','DIGITAL')",4,0], ["FORMAT","format","format(1234.5555,2)","1,234.56",1], - ["FROM_DAYS","from_days","from_days(729024)","1996-01-01",1], - ["FROM_UNIXTIME","from_unixtime","from_unixtime(0)",0,2], ["GETDATE","getdate","getdate()",0,2], - ["GREATEST","greatest","greatest('HARRY','HARRIOT','HAROLD')","HARRY",1], # oracle + ["GREATEST","greatest","greatest('HARRY','HARRIOT','HAROLD')","HARRY",1], ["IF","if", "if(5,6,7)",6,0], ["IN on numbers in SELECT","in_num","2 in (3,2,5,9,5,1)",$logical_value,0], ["IN on strings in SELECT","in_str","'monty' in ('david','monty','allan')", $logical_value,0], - ["INITCAP","initcap","initcap('the soap')","The Soap",1], # oracle Returns char, with the first letter of each word in uppercase + ["INITCAP","initcap","initcap('the soap')","The Soap",1], + # oracle Returns char, with the first letter of each word in uppercase ["INSTR (Oracle syntax)", "instr_oracle", "INSTR('CORPORATE FLOOR','OR',3,2)" ,"14",0], # oracle instring - ["INSTRB", "instrb", "INSTRB('CORPORATE FLOOR','OR',5,2)" ,"27",0], # oracle instring in bytes + ["INSTRB", "instrb", "INSTRB('CORPORATE FLOOR','OR',5,2)" ,"27",0], + # oracle instring in bytes ["INTERVAL","interval","interval(55,10,20,30,40,50,60,70,80,90,100)",5,0], - ["LAST_DAY","last_day","last_day('1997-04-01')","1997-04-30",0], # oracle last day of month of date ["LAST_INSERT_ID","last_insert_id","last_insert_id()",0,2], - ["LEAST","least","least('HARRY','HARRIOT','HAROLD')","HAROLD",1], # oracle - ["LENGTHB","lengthb","lengthb('CANDIDE')","14",0], # oracle length in bytes - ["LIKE ESCAPE in SELECT","like_escape","'%' like 'a%' escape 'a'",$logical_value,0], + ["LEAST","least","least('HARRY','HARRIOT','HAROLD')","HAROLD",1], + # oracle + ["LENGTHB","lengthb","lengthb('CANDIDE')","14",0], + # oracle length in bytes + ["LIKE ESCAPE in SELECT","like_escape", + "'%' like 'a%' escape 'a'",$logical_value,0], ["LIKE in SELECT","like","'a' like 'a%'",$logical_value,0], - ["LN","ln","ln(95)","4.55387689",0], # oracle natural logarithm of n + ["LN","ln","ln(95)","4.55387689",0], + # oracle natural logarithm of n ["LOCATE as INSTR","instr","instr('hello','ll')",3,0], - ["LOG(m,n)","log(m_n)","log(10,100)","2",0], # oracle logarithm, base m, of n - ["LOGN","logn","logn(2)","0.693147",0], # informix + ["LOG(m,n)","log(m_n)","log(10,100)","2",0], + # oracle logarithm, base m, of n + ["LOGN","logn","logn(2)","0.693147",0], + # informix ["LPAD","lpad","lpad('hi',4,'??')",'??hi',3], - ["MDY","mdy","mdy(7,1,1998)","1998-07-01",0], # informix ["MOD as %","%","10%7","3",0], - ["MONTHS_BETWEEN","months_between","months_between('1997-02-02','1997-01-01')","1.03225806",0], # oracle number of months between 2 dates ["NOT BETWEEN in SELECT","not_between","5 not between 4 and 6",0,0], ["NOT LIKE in SELECT","not_like","'a' not like 'a%'",0,0], ["NOT as '!' in SELECT","!","! 1",0,0], @@ -959,10 +932,9 @@ try_and_report("Automatic row id", "automatic_rowid", ["PASSWORD","password","password('hello')",0,2], ["PASTE", "paste", "paste('ABCDEFG',3,2,'1234')","AB1234EFG",1], ["PATINDEX","patindex","patindex('%a%','crash')",3,0], - ["PERIOD_ADD","period_add","period_add(9602,-12)",199502,0], - ["PERIOD_DIFF","period_diff","period_diff(199505,199404)",13,0], ["POW","pow","pow(3,2)",9,0], - ["RANGE","range","range(a)","0.0",0], # informix range(a) = max(a) - min(a) + ["RANGE","range","range(a)","0.0",0], + # informix range(a) = max(a) - min(a) ["REGEXP in SELECT","regexp","'a' regexp '^(a|b)*\$'",$logical_value,0], ["REPLICATE","replicate","replicate('a',5)","aaaaa",1], ["REVERSE","reverse","reverse('abcd')","dcba",1], @@ -974,23 +946,26 @@ try_and_report("Automatic row id", "automatic_rowid", ["STR","str","str(123.45,5,1)",123.5,3], ["STRCMP","strcmp","strcmp('abc','adc')",-1,0], ["STUFF","stuff","stuff('abc',2,3,'xyz')",'axyz',3], - ["SUBSTRB", "substrb", "SUBSTRB('ABCDEFG',5,4.2)" ,"CD",1], # oracle substring with bytes + ["SUBSTRB", "substrb", "SUBSTRB('ABCDEFG',5,4.2)" ,"CD",1], + # oracle substring with bytes ["SUBSTRING as MID","mid","mid('hello',3,2)","ll",1], - ["SUBSTRING_INDEX","substring_index","substring_index('www.tcx.se','.',-2)", "tcx.se",1], + ["SUBSTRING_INDEX","substring_index", + "substring_index('www.tcx.se','.',-2)", "tcx.se",1], ["SYSDATE","sysdate","sysdate()",0,2], ["TAIL","tail","tail('ABCDEFG',3)","EFG",0], - ["TANH","tanh","tanh(1)","0.462117157",0], # oracle hyperbolic tangent of n + ["TANH","tanh","tanh(1)","0.462117157",0], + # oracle hyperbolic tangent of n ["TIME_TO_SEC","time_to_sec","time_to_sec('01:23:21')","5001",0], - ["TO_DAYS","to_days","to_days(DATE '1996-01-01')",729024,0], ["TRANSLATE","translate","translate('abc','bc','de')",'ade',3], - ["TRIM; Many char extension","trim_many_char","trim(':!' FROM ':abc!')","abc",3], - ["TRIM; Substring extension","trim_substring","trim('cb' FROM 'abccb')","abc",3], + ["TRIM; Many char extension", + "trim_many_char","trim(':!' FROM ':abc!')","abc",3], + ["TRIM; Substring extension", + "trim_substring","trim('cb' FROM 'abccb')","abc",3], ["TRUNC","trunc","trunc(18.18,-1)",10,0], # oracle ["UID","uid","uid",0,2], # oracle uid from user ["UNIX_TIMESTAMP","unix_timestamp","unix_timestamp()",0,2], ["USERENV","userenv","userenv",0,2], # oracle user enviroment ["VERSION","version","version()",0,2], - ["WEEKDAY","weekday","weekday(DATE '1997-11-29')",5,0], ["automatic num->string convert","auto_num2string","concat('a',2)","a2",1], ["automatic string->num convert","auto_string2num","'1'+2",3,0], ["concatenation with +","concat_as_+","'abc' + 'def'","abcdef",1], @@ -1000,8 +975,8 @@ try_and_report("Automatic row id", "automatic_rowid", ["RFILL (3 arg)",'rfill3arg',"rfill('abcd','.',6)",'abcd..',1], ["RPAD (4 arg)",'rpad4arg',"rpad('abcd',2,'+-',8)",'abcd+-+-',1], ["LPAD (4 arg)",'rpad4arg',"lpad('abcd',2,'+-',8)",'+-+-abcd',1], - ["SAPDB compatible TRIM (1 arg)",'trim1arg',"trim(' abcd ')",'abcd',1], - ["SAPDB compatible TRIM (2 arg)",'trim2arg',"trim('..abcd..','.')",'abcd',1], + ["TRIM (1 arg)",'trim1arg',"trim(' abcd ')",'abcd',1], + ["TRIM (2 arg)",'trim2arg',"trim('..abcd..','.')",'abcd',1], ["LTRIM (2 arg)",'ltrim2arg',"ltrim('..abcd..','.')",'abcd..',1], ["RTRIM (2 arg)",'rtrim2arg',"rtrim('..abcd..','.')",'..abcd',1], ["EXPAND",'expand2arg',"expand('abcd',6)",'abcd ',0], @@ -1015,34 +990,24 @@ try_and_report("Automatic row id", "automatic_rowid", ["FLOAT",'float',"float(6666.66,4)",6667,0], ["LENGTH",'length',"length(1)",2,0], ["INDEX",'index',"index('abcdefg','cd',1,1)",3,0], - ["ADDDATE",'adddate',"ADDDATE('20021201',3)",'20021204',0], - ["SUBDATE",'subdate',"SUBDATE('20021204',3)",'20021201',0], - ["DATEDIFF (2 arg)",'datediff2arg',"DATEDIFF('20021204','20021201')",'3',0], # sapdb - ["DAYOFWEEK with sapdb internal date as arg",'dayofweek_sapdb',"DAYOFWEEK('19630816')",'5',0], - ["WEEKOFYEAR",'weekofyear',"WEEKOFYEAR('19630816')",'33',0], - ["DAYOFMONTH with sapdb internal date as arg",'dayofmonth_sapdb',"dayofmonth('19630816')",'16',0], - ["DAYOFYEAR with sapdb internal date as arg",'dayofyear_sapdb',"DAYOFYEAR('19630816')",'228',0], - ["MAKEDATE",'makedate',"MAKEDATE(1963,228)",'19630816',0], - ["DAYNAME with sapdb internal date as arg",'dayname_sapdb',"DAYNAME('19630816')",'Friday',0], - ["MONTHNAME with sapdb internal date as arg",'monthname_sapdb',"MONTHNAME('19630816')",'August',0], ["ADDTIME",'addtime',"ADDTIME('00200212','00000300')",'00200215',0], - ["SUBTIME",'subdate',"SUBDATE('00200215','00000300')",'00200212',0], + ["SUBTIME",'subtime',"SUBTIME('00200215','00000300')",'00200212',0], ["TIMEDIFF",'timediff',"TIMEDIFF('00200215','00200212')",'00000003',0], ["MAKETIME",'maketime',"MAKETIME(20,02,12)",'00200212',0], - ["YEAR with sapdb internal date as arg",'year_sapdb',"YEAR('20021201')",'2002',0], - ["MONTH with sapdb internal date as arg",'month_sapdb',"MONTH('20021201')",'12',0], - ["DAY",'day',"DAY('20021201')",1,0], - ["HOUR with sapdb internal time as arg",'hour_sapdb',"HOUR('00200212')",20,0], - ["MINUTE with sapdb internal time as arg",'minute_sapdb',"MINUTE('00200212')",2,0], - ["SECOND with sapdb internal time as arg",'second_sapdb',"SECOND('00200212')",12,0], - ["MICROSECOND",'microsecond',"MICROSECOND('19630816200212111111')",'111111',0], - ["TIMESTAMP",'timestamp',"timestamp('19630816','00200212')",'19630816200212000000',0], + ["HOUR with sapdb internal time as arg", + 'hour_sapdb',"HOUR('00200212')",20,0], + ["MINUTE with sapdb internal time as arg", + 'minute_sapdb',"MINUTE('00200212')",2,0], + ["SECOND with sapdb internal time as arg", + 'second_sapdb',"SECOND('00200212')",12,0], + ["MICROSECOND",'microsecond', + "MICROSECOND('19630816200212111111')",'111111',0], + ["TIMESTAMP",'timestamp', + "timestamp('19630816','00200212')",'19630816200212000000',0], ["TIME",'time',"time('00200212')",'00200212',0], - ["DATE",'date',"date('19630816')",'19630816',0], ["VALUE",'value',"value(NULL,'WALRUS')",'WALRUS',0], ["DECODE",'decode',"DECODE('S-103','T72',1,'S-103',2,'Leopard',3)",2,0], ["NUM",'num',"NUM('2123')",2123,0], - ["CHAR (conversation date)",'char_date',"CHAR(DATE('19630816'),EUR)",'16.08.1963',0], ["CHR (any type to string)",'chr_str',"CHR(67)",'67',0], ["HEX",'hex',"HEX('A')",41,0], ); @@ -1068,7 +1033,8 @@ try_and_report("Automatic row id", "automatic_rowid", ( ["BIT_AND",'bit_and',"bit_and(a)",1,0], ["BIT_OR", 'bit_or', "bit_or(a)",1,0], - ["COUNT(DISTINCT expr,expr,...)","count_distinct_list","count(distinct a,b)",1,0], + ["COUNT(DISTINCT expr,expr,...)", + "count_distinct_list","count(distinct a,b)",1,0], ["STD","std","std(a)",0,0], ["STDDEV","stddev","stddev(a)",0,0], ["VARIANCE","variance","variance(a)",0,0], @@ -1084,13 +1050,16 @@ try_and_report("Automatic row id", "automatic_rowid", ["IN on numbers","in_num","2 in (3,2,5,9,5,1)",1,0], ["LIKE ESCAPE","like_escape","b like '%' escape 'a'",1,0], ["LIKE","like","b like 'a%'",1,0], - ["MATCH UNIQUE","match_unique","1 match unique (select a from crash_me)",1,0], + ["MATCH UNIQUE","match_unique", + "1 match unique (select a from crash_me)",1,0], ["MATCH","match","1 match (select a from crash_me)",1,0], ["MATCHES","matches","b matcjhes 'a*'",1,0], ["NOT BETWEEN","not_between","7 not between 4 and 6",1,0], - ["NOT EXISTS","not_exists","not exists (select * from crash_me where a = 2)",1,0], + ["NOT EXISTS","not_exists", + "not exists (select * from crash_me where a = 2)",1,0], ["NOT LIKE","not_like","b not like 'b%'",1,0], - ["NOT UNIQUE","not_unique","not unique (select * from crash_me where a = 2)",1,0], + ["NOT UNIQUE","not_unique", + "not unique (select * from crash_me where a = 2)",1,0], ["UNIQUE","unique","unique (select * from crash_me)",1,0], ); @@ -1207,7 +1176,8 @@ if ($limits{'functions'} eq 'yes') "select $tmp $end_query",[], undef(),4); } $prompt="Need to cast NULL for arithmetic"; - add_log("Need_cast_for_null"," Check if numeric_null ($numeric_null) is 'NULL'"); + add_log("Need_cast_for_null", + " Check if numeric_null ($numeric_null) is 'NULL'"); save_config_data("Need_cast_for_null", ($numeric_null eq "NULL") ? "no" : "yes", $prompt); @@ -1232,7 +1202,8 @@ else $resultat = 'no' } else # Ok, now check if it really works { - $error=safe_query_l('func_extra_noround', [ "create table crash_me_nr (a int)", + $error=safe_query_l('func_extra_noround', + ["create table crash_me_nr (a int)", "insert into crash_me_nr values(noround(10.2))", "drop table crash_me_nr $drop_attr"]); if ($error eq 1) { @@ -1250,30 +1221,282 @@ check_parenthesis("func_sql_","SESSION_USER"); check_parenthesis("func_sql_","SYSTEM_USER"); check_parenthesis("func_sql_","USER"); + +if ($limits{'type_sql_date'} eq 'yes') +{ # + # Checking the format of date in result. + + safe_query("drop table crash_me_d $drop_attr"); + assert("create table crash_me_d (a date)"); + # find the example of date + my $dateexample; + if ($limits{'func_extra_sysdate'} eq 'yes') { + $dateexample=' sysdate() '; + } + elsif ($limits{'func_sql_current_date'} eq 'yes') { + $dateexample='CURRENT_DATE'; + } + elsif ($limits{'func_odbc_curdate'} eq 'yes') { + $dateexample='curdate()'; + } + elsif ($limits{'func_extra_getdate'} eq 'yes') { + $dateexample='getdate()'; + } + elsif ($limits{'func_odbc_now'} eq 'yes') { + $dateexample='now()'; + } else { + #try to guess + $dateexample="DATE '1963-08-16'"; + } ; + + my $key = 'date_format_inresult'; + my $prompt = "Date format in result"; + if (! safe_query_l('date_format_inresult', + "insert into crash_me_d values($dateexample) ")) + { + die "Cannot insert date ($dateexample):".$last_error; + }; + my $sth= $dbh->prepare("select a from crash_me_d"); + add_log('date_format_inresult',"< select a from crash_me_d"); + $sth->execute; + $_= $sth->fetchrow_array; + add_log('date_format_inresult',"> $_"); + safe_query_l($key,"delete from crash_me_d"); + if (/\d{4}-\d{2}-\d{2}/){ save_config_data($key,"iso",$prompt);} + elsif (/\d{2}-\d{2}-\d{2}/){ save_config_data($key,"short iso",$prompt);} + elsif (/\d{2}\.\d{2}\.\d{4}/){ save_config_data($key,"euro",$prompt);} + elsif (/\d{2}\.\d{2}\.\d{2}/){ save_config_data($key,"short euro",$prompt);} + elsif (/\d{2}\/\d{2}\/\d{4}/){ save_config_data($key,"usa",$prompt);} + elsif (/\d{2}\/\d{2}\/\d{2}/){ save_config_data($key,"short usa",$prompt);} + elsif (/\d*/){ save_config_data($key,"YYYYMMDD",$prompt);} + else { save_config_data($key,"unknown",$prompt);}; + $sth->finish; + + check_and_report("Supports YYYY-MM-DD (ISO) format","date_format_ISO", + [ "insert into crash_me_d(a) values ('1963-08-16')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + + check_and_report("Supports DATE 'YYYY-MM-DD' (ISO) format", + "date_format_ISO_with_date", + [ "insert into crash_me_d(a) values (DATE '1963-08-16')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + + check_and_report("Supports DD.MM.YYYY (EUR) format","date_format_EUR", + [ "insert into crash_me_d(a) values ('16.08.1963')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + check_and_report("Supports DATE 'DD.MM.YYYY' (EUR) format", + "date_format_EUR_with_date", + [ "insert into crash_me_d(a) values (DATE '16.08.1963')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + + check_and_report("Supports YYYYMMDD format", + "date_format_YYYYMMDD", + [ "insert into crash_me_d(a) values ('19630816')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + check_and_report("Supports DATE 'YYYYMMDD' format", + "date_format_YYYYMMDD_with_date", + [ "insert into crash_me_d(a) values (DATE '19630816')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + + check_and_report("Supports MM/DD/YYYY format", + "date_format_USA", + [ "insert into crash_me_d(a) values ('08/16/1963')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + check_and_report("Supports DATE 'MM/DD/YYYY' format", + "date_format_USA_with_date", + [ "insert into crash_me_d(a) values (DATE '08/16/1963')"], + "select a from crash_me_d", + ["delete from crash_me_d"], + make_date_r(1963,8,16),1); + + + + + check_and_report("Supports 0000-00-00 dates","date_zero", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values (".make_date(0,0,0).")"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + make_date_r(0,0,0),1); + + check_and_report("Supports 0001-01-01 dates","date_one", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values (".make_date(1,1,1).")"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + make_date_r(1,1,1),1); + + check_and_report("Supports 9999-12-31 dates","date_last", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values (".make_date(9999,12,31).")"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + make_date_r(9999,12,31),1); + + check_and_report("Supports 'infinity dates","date_infinity", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values ('infinity')"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + "infinity",1); + + if (!defined($limits{'date_with_YY'})) + { + check_and_report("Supports YY-MM-DD dates","date_with_YY", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values ('98-03-03')"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + make_date_r(1998,3,3),5); + if ($limits{'date_with_YY'} eq "yes") + { + undef($limits{'date_with_YY'}); + check_and_report("Supports YY-MM-DD 2000 compilant dates", + "date_with_YY", + ["create table crash_me2 (a date not null)", + "insert into crash_me2 values ('10-03-03')"], + "select a from crash_me2", + ["drop table crash_me2 $drop_attr"], + make_date_r(2010,3,3),5); + } + } + + # Test: WEEK() -{ - my $resultat="no"; - my $error; - print "WEEK:"; - save_incomplete('func_odbc_week','WEEK'); - $error = safe_query_result_l('func_odbc_week',"select week(DATE '1997-02-01') $end_query",5,0); - # actually this query must return 4 or 5 in the $last_result, - # $error can be 1 (not supported at all) , -1 ( probably USA weeks) - # and 0 - EURO weeks - if ($error == -1) { - if ($last_result == 4) { - $resultat = 'USA'; - } else { - $resultat='error'; - add_log('func_odbc_week'," must return 4 or 5, but $last_result"); - } - } elsif ($error == 0) { - $resultat = 'EURO'; - } - print " $resultat\n"; - save_config_data('func_odbc_week',$resultat,"WEEK $explain"); + { + my $resultat="no"; + my $error; + print "WEEK:"; + save_incomplete('func_odbc_week','WEEK'); + $error = safe_query_result_l('func_odbc_week', + "select week(".make_date(1997,2,1).") $end_query",5,0); + # actually this query must return 4 or 5 in the $last_result, + # $error can be 1 (not supported at all) , -1 ( probably USA weeks) + # and 0 - EURO weeks + if ($error == -1) { + if ($last_result == 4) { + $resultat = 'USA'; + } else { + $resultat='error'; + add_log('func_odbc_week', + " must return 4 or 5, but $last_result"); + } + } elsif ($error == 0) { + $resultat = 'EURO'; + } + print " $resultat\n"; + save_config_data('func_odbc_week',$resultat,"WEEK"); + } + + my $insert_query ='insert into crash_me_d values('. + make_date(1997,2,1).')'; + safe_query($insert_query); + + foreach $fn ( ( + ["DAYNAME","dayname","dayname(a)","",2], + ["MONTH","month","month(a)","",2], + ["MONTHNAME","monthname","monthname(a)","",2], + ["DAYOFMONTH","dayofmonth","dayofmonth(a)",1,0], + ["DAYOFWEEK","dayofweek","dayofweek(a)",7,0], + ["DAYOFYEAR","dayofyear","dayofyear(a)",32,0], + ["QUARTER","quarter","quarter(a)",1,0], + ["YEAR","year","year(a)",1997,0])) + { + $prompt='Function '.$fn->[0]; + $key='func_odbc_'.$fn->[1]; + add_log($key,"< ".$insert_query); + check_and_report($prompt,$key, + [],"select ".$fn->[2]." from crash_me_d",[], + $fn->[3],$fn->[4] + ); + + }; + safe_query(['delete from crash_me_d', + 'insert into crash_me_d values('.make_date(1963,8,16).')']); + foreach $fn (( + ["DATEADD","dateadd","dateadd(day,3,make_date(1997,11,30))",0,2], + ["MDY","mdy","mdy(7,1,1998)","make_date_r(1998,07,01)",0], # informix + ["DATEDIFF","datediff", + "datediff(month,'Oct 21 1997','Nov 30 1997')",0,2], + ["DATENAME","datename","datename(month,'Nov 30 1997')",0,2], + ["DATEPART","datepart","datepart(month,'July 20 1997')",0,2], + ["DATE_FORMAT","date_format", + "date_format('1997-01-02 03:04:05','M W D Y y m d h i s w')", 0,2], + ["FROM_DAYS","from_days", + "from_days(729024)","make_date_r(1996,1,1)",1], + ["FROM_UNIXTIME","from_unixtime","from_unixtime(0)",0,2], + ["MONTHS_BETWEEN","months_between", + "months_between(make_date(1997,2,2),make_date(1997,1,1))", + "1.03225806",0], # oracle number of months between 2 dates + ["PERIOD_ADD","period_add","period_add(9602,-12)",199502,0], + ["PERIOD_DIFF","period_diff","period_diff(199505,199404)",13,0], + ["WEEKDAY","weekday","weekday(make_date(1997,11,29))",5,0], + ["ADDDATE",'adddate', + "ADDDATE(make_date(2002,12,01),3)",'make_date_r(2002,12,04)',0], + ["SUBDATE",'subdate', + "SUBDATE(make_date(2002,12,04),3)",'make_date_r(2002,12,01)',0], + ["DATEDIFF (2 arg)",'datediff2arg', + "DATEDIFF(make_date(2002,12,04),make_date(2002,12,01))",'3',0], + ["WEEKOFYEAR",'weekofyear', + "WEEKOFYEAR(make_date(1963,08,16))",'33',0], +# table crash_me_d must contain record with 1963-08-16 (for CHAR) + ["CHAR (conversation date)",'char_date', + "CHAR(a,EUR)",'16.08.1963',0], + ["MAKEDATE",'makedate',"MAKEDATE(1963,228)" + ,'make_date_r(1963,08,16)',0], + ["TO_DAYS","to_days", + "to_days(make_date(1996,01,01))",729024,0], + ["ADD_MONTHS","add_months", + "add_months(make_date(1997,01,01),1)","make_date_r(1997,02,01)",0], + # oracle the date plus n months + ["LAST_DAY","last_day", + "last_day(make_date(1997,04,01))","make_date_r(1997,04,30)",0], + # oracle last day of month of date + ["DATE",'date',"date(make_date(1963,8,16))", + 'make_date_r(1963,8,16)',0], + ["DAY",'day',"DAY(make_date(2002,12,01))",1,0])) + { + $prompt='Function '.$fn->[0]; + $key='func_extra_'.$fn->[1]; + my $qry="select ".$fn->[2]." from crash_me_d"; + while( $qry =~ /^(.*)make_date\((\d+),(\d+),(\d+)\)(.*)$/) + { + my $dt= &make_date($2,$3,$4); + $qry=$1.$dt.$5; + }; + my $result=$fn->[3]; + while( $result =~ /^(.*)make_date_r\((\d+),(\d+),(\d+)\)(.*)$/) + { + my $dt= &make_date_r($2,$3,$4); + $result=$1.$dt.$5; + }; + check_and_report($prompt,$key, + [],$qry,[], + $result,$fn->[4] + ); + + } + + safe_query("drop table crash_me_d $drop_attr"); + } + + report("LIKE on numbers","like_with_number", "create table crash_q (a int,b int)", "insert into crash_q values(10,10)", @@ -1318,19 +1541,20 @@ if (defined($tmp)) if (!defined($limits{'multi_table_update'})) { if (check_and_report("Update with many tables","multi_table_update", - ["create table crash_q (a integer,b char(10))", - "insert into crash_q values(1,'c')", - "update crash_q left join crash_me on crash_q.a=crash_me.a set crash_q.b=crash_me.b"], - "select b from crash_q", - ["drop table crash_q $drop_attr"], - "a",1,undef(),2)) + ["create table crash_q (a integer,b char(10))", + "insert into crash_q values(1,'c')", + "update crash_q left join crash_me on crash_q.a=crash_me.a set crash_q.b=crash_me.b"], + "select b from crash_q", + ["drop table crash_q $drop_attr"], + "a",1,undef(),2)) { check_and_report("Update with many tables","multi_table_update", - ["create table crash_q (a integer,b char(10))", - "insert into crash_q values(1,'c')", - "update crash_q,crash_me set crash_q.b=crash_me.b where crash_q.a=crash_me.a"], - "select b from crash_q", - ["drop table crash_q $drop_attr"], + ["create table crash_q (a integer,b char(10))", + "insert into crash_q values(1,'c')", + "update crash_q,crash_me set crash_q.b=crash_me.b ". + "where crash_q.a=crash_me.a"], + "select b from crash_q", + ["drop table crash_q $drop_attr"], "a",1, 1); } @@ -1345,7 +1569,8 @@ report("DELETE FROM table1,table2...","multi_table_delete", check_and_report("Update with sub select","select_table_update", ["create table crash_q (a integer,b char(10))", "insert into crash_q values(1,'c')", - "update crash_q set b= (select b from crash_me where crash_q.a = crash_me.a)"], + "update crash_q set b= ". + "(select b from crash_me where crash_q.a = crash_me.a)"], "select b from crash_q", ["drop table crash_q $drop_attr"], "a",1); @@ -1615,25 +1840,31 @@ safe_query("drop table crash_q $drop_attr"); # test of different join types # -assert("create table crash_me2 (a integer not null,b char(10) not null, c1 integer)"); +assert("create table crash_me2 (a integer not null,b char(10) not null,". + " c1 integer)"); assert("insert into crash_me2 (a,b,c1) values (1,'b',1)"); assert("create table crash_me3 (a integer not null,b char(10) not null)"); assert("insert into crash_me3 (a,b) values (1,'b')"); report("inner join","inner_join", - "select crash_me.a from crash_me inner join crash_me2 ON crash_me.a=crash_me2.a"); + "select crash_me.a from crash_me inner join crash_me2 ON ". + "crash_me.a=crash_me2.a"); report("left outer join","left_outer_join", - "select crash_me.a from crash_me left join crash_me2 ON crash_me.a=crash_me2.a"); + "select crash_me.a from crash_me left join crash_me2 ON ". + "crash_me.a=crash_me2.a"); report("natural left outer join","natural_left_outer_join", "select c1 from crash_me natural left join crash_me2"); report("left outer join using","left_outer_join_using", "select c1 from crash_me left join crash_me2 using (a)"); report("left outer join odbc style","odbc_left_outer_join", - "select crash_me.a from { oj crash_me left outer join crash_me2 ON crash_me.a=crash_me2.a }"); + "select crash_me.a from { oj crash_me left outer join crash_me2 ON". + " crash_me.a=crash_me2.a }"); report("right outer join","right_outer_join", - "select crash_me.a from crash_me right join crash_me2 ON crash_me.a=crash_me2.a"); + "select crash_me.a from crash_me right join crash_me2 ON ". + "crash_me.a=crash_me2.a"); report("full outer join","full_outer_join", - "select crash_me.a from crash_me full join crash_me2 ON crash_me.a=crash_me2.a"); + "select crash_me.a from crash_me full join crash_me2 ON "." + crash_me.a=crash_me2.a"); report("cross join (same as from a,b)","cross_join", "select crash_me.a from crash_me cross join crash_me3"); report("natural join","natural_join", @@ -1687,7 +1918,8 @@ assert("drop table crash_me3 $drop_attr"); # >ALL | ANY | SOME - EXISTS - UNIQUE if (report("subqueries","subqueries", - "select a from crash_me where crash_me.a in (select max(a) from crash_me)")) + "select a from crash_me where crash_me.a in ". + "(select max(a) from crash_me)")) { $tmp=new query_repeat([],"select a from crash_me","","", " where a in (select a from crash_me",")", @@ -1765,7 +1997,8 @@ report("views","views", # 1) check if foreign keys are supported safe_query_l('foreign_key',create_table("crash_me_qf",["a integer not null"], ["primary key (a)"])); - $error = safe_query_l('foreign_key', create_table("crash_me_qf2",["a integer not null", + $error = safe_query_l('foreign_key', + create_table("crash_me_qf2",["a integer not null", "foreign key (a) references crash_me_qf (a)"], [])); if ($error eq 1) # OK -- syntax is supported @@ -1773,7 +2006,8 @@ report("views","views", $resultat = 'error'; # now check if foreign key really works safe_query_l('foreign_key', "insert into crash_me_qf values (1)"); - if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1) { + if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1) + { $resultat = 'syntax only'; } else { $resultat = 'yes'; @@ -1782,13 +2016,15 @@ report("views","views", } else { $resultat = "no"; } - safe_query_l('foreign_key', "drop table crash_me_qf2 $drop_attr","drop table crash_me_qf $drop_attr"); + safe_query_l('foreign_key', + "drop table crash_me_qf2 $drop_attr","drop table crash_me_qf $drop_attr"); print "$resultat\n"; save_config_data('foreign_key',$resultat,"foreign keys"); } report("Create SCHEMA","create_schema", - "create schema crash_schema create table crash_q (a int) create table crash_q2(b int)", + "create schema crash_schema create table crash_q (a int) ". + "create table crash_q2(b int)", "drop schema crash_schema cascade"); if ($limits{'foreign_key'} eq 'yes') @@ -1796,7 +2032,10 @@ if ($limits{'foreign_key'} eq 'yes') if ($limits{'create_schema'} eq 'yes') { report("Circular foreign keys","foreign_key_circular", - "create schema crash_schema create table crash_q (a int primary key, b int, foreign key (b) references crash_q2(a)) create table crash_q2(a int, b int, primary key(a), foreign key (b) references crash_q(a))", + "create schema crash_schema create table crash_q ". + "(a int primary key, b int, foreign key (b) references ". + "crash_q2(a)) create table crash_q2(a int, b int, ". + "primary key(a), foreign key (b) references crash_q(a))", "drop schema crash_schema cascade"); } } @@ -1824,35 +2063,47 @@ report("NULL constraint (SyBase style)","constraint_null", report("Triggers (ANSI SQL)","psm_trigger", "create table crash_q (a int ,b int)", - "create trigger crash_trigger after insert on crash_q referencing new table as new_a when (localtime > time '18:00:00') begin atomic end", + "create trigger crash_trigger after insert on crash_q referencing ". + "new table as new_a when (localtime > time '18:00:00') ". + "begin atomic end", "insert into crash_q values(1,2)", "drop trigger crash_trigger", "drop table crash_q $drop_attr"); report("PSM procedures (ANSI SQL)","psm_procedures", "create table crash_q (a int,b int)", - "create procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end", + "create procedure crash_proc(in a1 int, in b1 int) language ". + "sql modifies sql data begin declare c1 int; set c1 = a1 + b1;". + " insert into crash_q(a,b) values (a1,c1); end", "call crash_proc(1,10)", "drop procedure crash_proc", "drop table crash_q $drop_attr"); report("PSM modules (ANSI SQL)","psm_modules", "create table crash_q (a int,b int)", - "create module crash_m declare procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end; declare procedure crash_proc2(INOUT a int, in b int) contains sql set a = b + 10; end module", + "create module crash_m declare procedure ". + "crash_proc(in a1 int, in b1 int) language sql modifies sql ". + "data begin declare c1 int; set c1 = a1 + b1; ". + "insert into crash_q(a,b) values (a1,c1); end; ". + "declare procedure crash_proc2(INOUT a int, in b int) ". + "contains sql set a = b + 10; end module", "call crash_proc(1,10)", "drop module crash_m cascade", "drop table crash_q cascade $drop_attr"); report("PSM functions (ANSI SQL)","psm_functions", "create table crash_q (a int)", - "create function crash_func(in a1 int, in b1 int) returns int language sql deterministic contains sql begin return a1 * b1; end", + "create function crash_func(in a1 int, in b1 int) returns int". + " language sql deterministic contains sql ". + " begin return a1 * b1; end", "insert into crash_q values(crash_func(2,4))", "select a,crash_func(a,2) from crash_q", "drop function crash_func cascade", "drop table crash_q $drop_attr"); report("Domains (ANSI SQL)","domains", - "create domain crash_d as varchar(10) default 'Empty' check (value <> 'abcd')", + "create domain crash_d as varchar(10) default 'Empty' ". + "check (value <> 'abcd')", "create table crash_q(a crash_d, b int)", "insert into crash_q(a,b) values('xyz',10)", "insert into crash_q(b) values(10)", @@ -2028,28 +2279,31 @@ if ($limits{'unique_in_create'} eq 'yes') $max_keys,0)); find_limit("index parts","max_index_parts", - new query_table("create table crash_q ($key_definitions,unique (q0", + new query_table("create table crash_q ". + "($key_definitions,unique (q0", ",q%d","))", - ["insert into crash_q ($key_fields) values ($key_values)"], - "select q0 from crash_q",1, - "drop table crash_q $drop_attr", - $max_keys,1)); + ["insert into crash_q ($key_fields) values ($key_values)"], + "select q0 from crash_q",1, + "drop table crash_q $drop_attr", + $max_keys,1)); find_limit("max index part length","max_index_part_length", - new query_many(["create table crash_q (q char(%d) not null,unique(q))", - "insert into crash_q (q) values ('%s')"], - "select q from crash_q","%s", - ["drop table crash_q $drop_attr"], - $limits{'max_char_size'},0)); + new query_many(["create table crash_q (q char(%d) not null,". + "unique(q))", + "insert into crash_q (q) values ('%s')"], + "select q from crash_q","%s", + ["drop table crash_q $drop_attr"], + $limits{'max_char_size'},0)); if ($limits{'type_sql_varchar(1_arg)'} eq 'yes') { find_limit("index varchar part length","max_index_varchar_part_length", - new query_many(["create table crash_q (q varchar(%d) not null,unique(q))", - "insert into crash_q (q) values ('%s')"], - "select q from crash_q","%s", - ["drop table crash_q $drop_attr"], - $limits{'max_varchar_size'},0)); + new query_many(["create table crash_q (q varchar(%d) not null,". + "unique(q))", + "insert into crash_q (q) values ('%s')"], + "select q from crash_q","%s", + ["drop table crash_q $drop_attr"], + $limits{'max_varchar_size'},0)); } } @@ -2059,7 +2313,9 @@ if ($limits{'create_index'} ne 'no') if ($limits{'create_index'} eq 'ignored' || $limits{'unique_in_create'} eq 'yes') { # This should be true - add_log('max_index'," max_unique_index=$limits{'max_unique_index'} ,so max_index must be same"); + add_log('max_index', + " max_unique_index=$limits{'max_unique_index'} ,". + "so max_index must be same"); save_config_data('max_index',$limits{'max_unique_index'},"max index"); print "indexes: $limits{'max_index'}\n"; } @@ -2070,7 +2326,8 @@ if ($limits{'create_index'} ne 'no') safe_query_l('max_index',"create table crash_q ($key_definitions)"); for ($i=1; $i <= min($limits{'max_columns'},$max_keys) ; $i++) { - last if (!safe_query_l('max_index',"create index crash_q$i on crash_q (q$i)")); + last if (!safe_query_l('max_index', + "create index crash_q$i on crash_q (q$i)")); } save_config_data('max_index',$i == $max_keys ? $max_keys : $i, "max index"); @@ -2086,10 +2343,12 @@ if ($limits{'create_index'} ne 'no') print "indexs: $limits{'max_index'}\n"; if (!defined($limits{'max_unique_index'})) { - safe_query_l('max_unique_index',"create table crash_q ($key_definitions)"); + safe_query_l('max_unique_index', + "create table crash_q ($key_definitions)"); for ($i=0; $i < min($limits{'max_columns'},$max_keys) ; $i++) { - last if (!safe_query_l('max_unique_index',"create unique index crash_q$i on crash_q (q$i)")); + last if (!safe_query_l('max_unique_index', + "create unique index crash_q$i on crash_q (q$i)")); } save_config_data('max_unique_index',$i == $max_keys ? $max_keys : $i, "max unique index"); @@ -2105,7 +2364,8 @@ if ($limits{'create_index'} ne 'no') print "unique indexes: $limits{'max_unique_index'}\n"; if (!defined($limits{'max_index_parts'})) { - safe_query_l('max_index_parts',"create table crash_q ($key_definitions)"); + safe_query_l('max_index_parts', + "create table crash_q ($key_definitions)"); $end_drop=$end_drop_keyword; $end_drop =~ s/%i/crash_q1%d/; $end_drop =~ s/%t/crash_q/; @@ -2186,23 +2446,29 @@ if (!defined($limits{$key})) { print "$prompt="; save_incomplete($key,$prompt); - if (!safe_query_l($key,$server->create("crash_me_a",["a decimal(10,2)","b decimal(10,2)"]))) + if (!safe_query_l($key,$server->create("crash_me_a", + ["a decimal(10,2)","b decimal(10,2)"]))) { print DBI->errstr(); die "Can't create table 'crash_me_a' $DBI::errstr\n"; }; - if (!safe_query_l($key,["insert into crash_me_a (a,b) values (11.4,18.9)"])) + if (!safe_query_l($key, + ["insert into crash_me_a (a,b) values (11.4,18.9)"])) { die "Can't insert into table 'crash_me_a' a record: $DBI::errstr\n"; }; $arithmetic_safe = 'no'; $arithmetic_safe = 'yes' - if ( (safe_query_result_l($key,'select count(*) from crash_me_a where a+b=30.3',1,0) == 0) - and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0) - and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0) - and (safe_query_result_l($key,'select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0) ); + if ( (safe_query_result_l($key, + 'select count(*) from crash_me_a where a+b=30.3',1,0) == 0) + and (safe_query_result_l($key, + 'select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0) + and (safe_query_result_l($key, + 'select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0) + and (safe_query_result_l($key, + 'select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0)); save_config_data($key,$arithmetic_safe,$prompt); print "$arithmetic_safe\n"; assert("drop table crash_me_a $drop_attr"); @@ -2263,6 +2529,9 @@ if (!defined($limits{$key})) assert("drop table crash_me_n $drop_attr"); + + + # # End of test # @@ -2361,6 +2630,46 @@ sub check_constraint { print "$res\n"; } +sub make_date_r { + my $year=shift; + my $month=shift; + my $day=shift; + $_ = $limits{'date_format_inresult'}; + return sprintf "%02d-%02d-%02d", ($year%100),$month,$day if (/^short iso$/); + return sprintf "%04d-%02d-%02d", $year,$month,$day if (/^iso/); + return sprintf "%02d.%02d.%02d", $day,$month,($year%100) if (/^short euro/); + return sprintf "%02d.%02d.%04d", $day,$month,$year if (/^euro/); + return sprintf "%02d/%02d/%02d", $month,$day,($year%100) if (/^short usa/); + return sprintf "%02d/%02d/%04d", $month,$day,$year if (/^usa/); + return sprintf "%04d%02d%02d", $year,$month,$day if (/^YYYYMMDD/); + return "UNKNOWN FORMAT"; +} + + +sub make_date { + my $year=shift; + my $month=shift; + my $day=shift; + return sprintf "'%04d-%02d-%02d'", $year,$month,$day + if ($limits{'date_format_ISO'} eq yes); + return sprintf "DATE '%04d-%02d-%02d'", $year,$month,$day + if ($limits{'date_format_ISO_with_date'} eq yes); + return sprintf "'%02d.%02d.%04d'", $day,$month,$year + if ($limits{'date_format_EUR'} eq 'yes'); + return sprintf "DATE '%02d.%02d.%04d'", $day,$month,$year + if ($limits{'date_format_EUR_with_date'} eq 'yes'); + return sprintf "'%02d/%02d/%04d'", $month,$day,$year + if ($limits{'date_format_USA'} eq 'yes'); + return sprintf "DATE '%02d/%02d/%04d'", $month,$day,$year + if ($limits{'date_format_USA_with_date'} eq 'yes'); + return sprintf "'%04d%02d%02d'", $year,$month,$day + if ($limits{'date_format_YYYYMMDD'} eq 'yes'); + return sprintf "DATE '%04d%02d%02d'", $year,$month,$day + if ($limits{'date_format_YYYYMMDD_with_date'} eq 'yes'); + return "UNKNOWN FORMAT"; +} + + sub usage { print <{LongReadLen}= 16000000; # Set max retrieval buffer return $dbh; } - print "Error: $DBI::errstr; $server->{'data_source'} - '$opt_user' - '$opt_password'\n"; + print "Error: $DBI::errstr; $server->{'data_source'} ". + " - '$opt_user' - '$opt_password'\n"; print "I got the above error when connecting to $opt_server\n"; if (defined($object) && defined($object->{'limit'})) { - print "This check was done with limit: $object->{'limit'}.\nNext check will be done with a smaller limit!\n"; + print "This check was done with limit: $object->{'limit'}.". + "\nNext check will be done with a smaller limit!\n"; $object=undef(); } save_config_data('crash_me_safe','no',"crash me safe"); @@ -2692,7 +3005,8 @@ sub print_query # # Do one or many queries. Return 1 if all was ok -# Note that all rows are executed (to ensure that we execute drop table commands) +# Note that all rows are executed +# (to ensure that we execute drop table commands) # sub safe_query_l { @@ -2716,7 +3030,8 @@ sub safe_query } foreach $query (@$queries) { - printf "query1: %-80.80s ...(%d - %d)\n",$query,length($query),$retry_limit if ($opt_log_all_queries); + printf "query1: %-80.80s ...(%d - %d)\n",$query, + length($query),$retry_limit if ($opt_log_all_queries); print LOG "$query;\n" if ($opt_log); $safe_query_log .= "< $query\n"; if (length($query) > $query_size) @@ -2983,7 +3298,6 @@ sub check_reserved_words "create table crash_me10 ($keyword int not null)", "drop table crash_me10 $drop_attr" ); - print "$prompt: ",$limits{$config},"\n"; } } @@ -3367,7 +3681,8 @@ sub safe_query_result (abs($row->[0]) + abs($answer))) > 0.01) { $result=-1; - $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; + $safe_query_result_log .= + "We expected '$answer' but got '$last_result' \n"; } } elsif ($result_type == 1) # Compare where end space may differ @@ -3376,7 +3691,8 @@ sub safe_query_result if ($row->[0] ne $answer) { $result=-1; - $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; + $safe_query_result_log .= + "We expected '$answer' but got '$last_result' \n"; } ; } elsif ($result_type == 3) # This should be a exact match @@ -3384,7 +3700,8 @@ sub safe_query_result if ($row->[0] ne $answer) { $result= -1; - $safe_query_result_log .= "we expected '$answer' but got '$last_result' \n"; + $safe_query_result_log .= + "We expected '$answer' but got '$last_result' \n"; }; } elsif ($result_type == 4) # If results should be NULL @@ -3392,7 +3709,8 @@ sub safe_query_result if (defined($row->[0])) { $result= -1; - $safe_query_result_log .= "We expected NULL but got '$last_result' \n"; + $safe_query_result_log .= + "We expected NULL but got '$last_result' \n"; }; } elsif ($result_type == 5) # Result should have given prefix @@ -3401,14 +3719,16 @@ sub safe_query_result substr($row->[0],1,length($answer)) ne $answer) { $result= -1 ; - $safe_query_result_log .= "result must have prefix '$answer', but '$last_result' \n"; + $safe_query_result_log .= + "Result must have prefix '$answer', but '$last_result' \n"; }; } elsif ($result_type == 6) # Exact match but ignore errors { if ($row->[0] ne $answer) { $result= 1; - $safe_query_result_log .= "We expected '$answer' but got '$last_result' \n"; + $safe_query_result_log .= + "We expected '$answer' but got '$last_result' \n"; } ; } elsif ($result_type == 7) # Compare against array of numbers @@ -3459,8 +3779,9 @@ sub safe_query_result # # Find limit using binary search. This is a weighed binary search that -# will prefere lower limits to get the server to crash as few times as possible -# +# will prefere lower limits to get the server to crash as +# few times as possible + sub find_limit() { @@ -3505,7 +3826,8 @@ sub find_limit() if (!limit_query($query,1)) # This must work { - print "\nMaybe fatal error: Can't check '$prompt' for limit=1\nerror: $last_error\n"; + print "\nMaybe fatal error: Can't check '$prompt' for limit=1\n". + "error: $last_error\n"; return "error"; } @@ -3648,11 +3970,10 @@ sub save_config_data my $last_line_was_empty=0; foreach $line (split /\n/, $log{$key}) { - print CONFIG_FILE " ###$line\n" - unless ( ($last_line_was_empty eq 1) + print CONFIG_FILE " ###$line\n" + unless ( ($last_line_was_empty eq 1) && ($line =~ /^\s+$/) ); $last_line_was_empty= ($line =~ /^\s+$/)?1:0; - }; if (($opt_restart && $limits{'operating_system'} =~ /windows/i) || @@ -3684,7 +4005,8 @@ sub save_all_config_data select STDOUT; delete $limits{'restart'}; - print CONFIG_FILE "#This file is automaticly generated by crash-me $version\n\n"; + print CONFIG_FILE + "#This file is automaticly generated by crash-me $version\n\n"; foreach $key (sort keys %limits) { $tmp="$key=$limits{$key}"; @@ -3694,11 +4016,9 @@ sub save_all_config_data my $last_line_was_empty=0; foreach $line (split /\n/, $log{$key}) { - print CONFIG_FILE " ###$line\n" - unless ( ($last_line_was_empty eq 1) - && ($line =~ /^\s+$/) ); - $last_line_was_empty= ($line =~ /^\s+$/)?1:0; - + print CONFIG_FILE " ###$line\n" unless + ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/)); + $last_line_was_empty= ($line =~ /^\s*$/)?1:0; }; } close CONFIG_FILE; @@ -4267,7 +4587,8 @@ sub query $self->{'limit'}=$limit; $res=$parts=$values=""; - $size=main::min($main::limits{'max_index_part_length'},$main::limits{'max_char_size'}); + $size=main::min($main::limits{'max_index_part_length'}, + $main::limits{'max_char_size'}); $size=1 if ($size == 0); # Avoid infinite loop errors for ($length=$i=0; $length + $size <= $limit ; $length+=$size, $i++) { From 3522a78600194e51613a44c95d48cb7299bbb0a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Dec 2002 14:08:25 +0500 Subject: [PATCH 42/61] server-cfg.sh: Corrected some typo. sql-bench/server-cfg.sh: Corrected some typo. --- sql-bench/server-cfg.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index 31b8628ad79..589ce519a86 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -3467,7 +3467,7 @@ sub version && $row[0] =~ /([\d\.]+)/) { $version=$row[0]; - $verson =~ s/KERNEL/SAP DB/i; + $version =~ s/KERNEL/SAP DB/i; } $sth->finish; $dbh->disconnect; @@ -3528,7 +3528,6 @@ sub create }else{ my @fields = split(' ',$ind); my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]"; - print "$query \n"; push(@index,$query); } } From 05ef8a612a8a94a0bf64801867b805675192f049 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Dec 2002 20:58:07 +0200 Subject: [PATCH 43/61] ha_innobase.cc: Better error message to help users who created tables with < 3.23.54 where MySQL implicitly added a PRIMARY KEY definition sql/ha_innobase.cc: Better error message to help users who created tables with < 3.23.54 where MySQL implicitly added a PRIMARY KEY definition --- sql/ha_innobase.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 489c2fafd9b..c5b529a3881 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -1030,7 +1030,14 @@ how you can resolve the problem.\n", if (primary_key != MAX_KEY) { fprintf(stderr, "InnoDB: Error: table %s has no primary key in InnoDB\n" - "InnoDB: data dictionary, but has one in MySQL!\n", name); + "InnoDB: data dictionary, but has one in MySQL!\n" + "InnoDB: If you created the table with a MySQL\n" + "InnoDB: version < 3.23.54 and did not define a primary\n" + "InnoDB: key, but defined a unique key with all non-NULL\n" + "InnoDB: columns, then MySQL internally treats that key\n" + "InnoDB: as the primary key. You can fix this error by\n" + "InnoDB: dump + DROP + CREATE + reimport of the table.\n", + name); } ((row_prebuilt_t*)innobase_prebuilt) From 63c9b06a62c80cb8889ad753d73bcd0c759c0632 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Dec 2002 12:56:00 +0100 Subject: [PATCH 44/61] - tagged ChangeSet 1.1477 as MySQL 4.0.6 - bumped up version number in configure.in to 4.0.7-gamma configure.in: - bumped up version number in configure.in to 4.0.7-gamma --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 8652bb13154..70c6ae08a30 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.6-gamma) +AM_INIT_AUTOMAKE(mysql, 4.0.7-gamma) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 791e9fb37ea10f3e91e56e15c869906d90313c06 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Dec 2002 14:58:27 +0200 Subject: [PATCH 45/61] Changed thd variables max_join_size and select_limit to type ha_rows. This fixed some optimization problems when using -DBIG_TABLES Portabilty fixes for OpenUnix and HPUX Added C and C++ version numbers to mysqlbug Docs/mysqld_error.txt: Added new error message acinclude.m4: Fix for configure problem on OpenUnix configure.in: Fix for OpenUnix Added C and C++ versions to mysqlbug mysql-test/r/variables.result: Update of max_join_size handling mysql-test/t/variables.test: Update of max_join_size handling mysys/Makefile.am: Removed duplicate row mysys/my_alloc.c: Safety fixes (not fatal) scripts/Makefile.am: Added C and C++ compiler versions to mysqlbug scripts/mysqlbug.sh: Added C and C++ compiler versions to mysqlbug sql/item_func.cc: Fixed that user variables that changes are not threated as constants. sql/item_func.h: Fixed that user variables that changes are not threated as constants. sql/mysqld.cc: Changed thd variables max_join_size and select_limit to type ha_rows sql/repl_failsafe.cc: Removed not needed cast sql/set_var.cc: Changed thd variables max_join_size and select_limit to type ha_rows sql/set_var.h: Changed thd variables max_join_size and select_limit to type ha_rows sql/slave.cc: Removed not needed cast sql/sql_class.h: Changed thd variables max_join_size and select_limit to type ha_rows sql/sql_parse.cc: Removed not needed cast Fixed security problem with mysql_drop_db() sql/sql_show.cc: Changed thd variables max_join_size and select_limit to type ha_rows sql/structs.h: Changed thd variables max_join_size and select_limit to type ha_rows --- Docs/mysqld_error.txt | 26 +++++++++++-- acinclude.m4 | 9 +++-- configure.in | 8 +++- mysql-test/r/variables.result | 4 +- mysql-test/t/variables.test | 3 ++ mysys/Makefile.am | 1 - mysys/my_alloc.c | 4 +- scripts/Makefile.am | 2 + scripts/mysqlbug.sh | 2 + sql/item_func.cc | 7 +++- sql/item_func.h | 7 ++-- sql/mysqld.cc | 16 +++++--- sql/repl_failsafe.cc | 2 +- sql/set_var.cc | 69 ++++++++++++++++++++++++++++++----- sql/set_var.h | 18 +++++++++ sql/slave.cc | 2 +- sql/sql_class.h | 4 +- sql/sql_parse.cc | 6 ++- sql/sql_show.cc | 3 ++ sql/structs.h | 2 +- 20 files changed, 157 insertions(+), 38 deletions(-) diff --git a/Docs/mysqld_error.txt b/Docs/mysqld_error.txt index db663e3d1f5..aeb3a12c263 100644 --- a/Docs/mysqld_error.txt +++ b/Docs/mysqld_error.txt @@ -300,7 +300,7 @@ #define ER_NOT_ALLOWED_COMMAND 1148 "The used command is not allowed with this MySQL version", #define ER_SYNTAX_ERROR 1149 -"You have an error in your SQL syntax", +"You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use", #define ER_DELAYED_CANT_CHANGE_LOCK 1150 "Delayed insert thread couldn't get requested lock for table %-.64s", #define ER_TOO_MANY_DELAYED_THREADS 1151 @@ -358,7 +358,7 @@ #define ER_CHECK_NO_SUCH_TABLE 1177 "Can't open table", #define ER_CHECK_NOT_IMPLEMENTED 1178 -"The handler for the table doesn't support check/repair", +"The handler for the table doesn't support %s", #define ER_CANT_DO_THIS_DURING_AN_TRANSACTION 1179 "You are not allowed to execute this command in a transaction", #define ER_ERROR_DURING_COMMIT 1180 @@ -454,4 +454,24 @@ #define ER_DUP_ARGUMENT 1225 "Option '%s' used twice in statement", #define ER_USER_LIMIT_REACHED 1226 -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227 +"Access denied. You need the %-.128s privilege for this operation", +#define ER_LOCAL_VARIABLE 1228 +"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL", +#define ER_GLOBAL_VARIABLE 1229 +"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL", +#define ER_NO_DEFAULT 1230 +"Variable '%-.64s' doesn't have a default value", +#define ER_WRONG_VALUE_FOR_VAR 1231 +"Variable '%-.64s' can't be set to the value of '%-.64s'", +#define ER_WRONG_TYPE_FOR_VAR 1232 +"Wrong argument type to variable '%-.64s'", +#define ER_VAR_CANT_BE_READ 1233 +"Variable '%-.64s' can only be set, not read", +#define ER_CANT_USE_OPTION_HERE 1234 +"Wrong usage/placement of '%s'", +#define 1235 +"This version of MySQL doesn't yet support '%s'", +#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 +"Got fatal error %d: '%-.128s' from master when reading data from binary log", diff --git a/acinclude.m4 b/acinclude.m4 index fda4f4bf7d5..7436b5136a5 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1211,7 +1211,9 @@ changequote(, )dnl hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) changequote([, ])dnl if test "$GCC" = yes; then - ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__ + case `$CC --version 2>/dev/null` in + 2.95.*) ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__ ;; + esac fi ;; # IRIX 6.2 and later require cc -n32. @@ -1326,7 +1328,7 @@ AC_DEFUN(MYSQL_SYS_LARGEFILE, # Local version of _AC_PROG_CXX_EXIT_DECLARATION that does not -# include #stdlib.h as this breaks things on Solaris +# include #stdlib.h as default as this breaks things on Solaris # (Conflicts with pthreads and big file handling) m4_define([_AC_PROG_CXX_EXIT_DECLARATION], @@ -1336,7 +1338,8 @@ m4_define([_AC_PROG_CXX_EXIT_DECLARATION], 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ - 'void exit (int);' + 'void exit (int);' \ + '#include ' do _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include $ac_declaration], diff --git a/configure.in b/configure.in index 8652bb13154..82eeea20ba4 100644 --- a/configure.in +++ b/configure.in @@ -135,13 +135,19 @@ if test $? -eq "0" then AC_MSG_CHECKING("C Compiler version"); AC_MSG_RESULT("$CC $CC_VERSION") +else +CC_VERSION="" fi CXX_VERSION=`$CXX --version` if test $? -eq "0" then AC_MSG_CHECKING("C++ compiler version"); AC_MSG_RESULT("$CXX $CXX_VERSION") +else +CXX_VERSION="" fi +AC_SUBST(CXX_VERSION) +AC_SUBST(CC_VERSION) # Fix for sgi gcc / sgiCC which tries to emulate gcc if test "$CC" = "sgicc" @@ -1228,7 +1234,7 @@ then # CC="$CC -Kthread -DOpenUNIX8"; # CXX="$CXX -Kthread -DOpenUNIX8"; CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; - CXX="$CXX -Kthread -DUNIXWARE_7"; + CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK" fi AC_MSG_RESULT("yes") else diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f8ac13477a9..ed477a8519b 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -50,7 +50,7 @@ Variable_name Value max_join_size 100 show global variables like 'max_join_size'; Variable_name Value -max_join_size 4294967295 +max_join_size HA_POS_ERROR set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; Variable_name Value @@ -62,7 +62,7 @@ max_join_size 2000 set GLOBAL max_join_size=DEFAULT; show global variables like 'max_join_size'; Variable_name Value -max_join_size 4294967295 +max_join_size HA_POS_ERROR set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; @@session.max_join_size @@global.max_join_size diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index e21fbd975e6..5863cb97d57 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -34,12 +34,15 @@ drop table t1; set max_join_size=100; show variables like 'max_join_size'; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show global variables like 'max_join_size'; set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; set max_join_size=DEFAULT; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show variables like 'max_join_size'; set GLOBAL max_join_size=DEFAULT; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show global variables like 'max_join_size'; set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 6047debcaf5..67bc8feadaa 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -64,7 +64,6 @@ EXTRA_PROGRAMS = DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ @DEFS@ diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 1ab86476e41..4d3b0604984 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -25,12 +25,13 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { - mem_root->free= mem_root->used= 0; + mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; + #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { @@ -137,6 +138,7 @@ static inline void mark_blocks_free(MEM_ROOT* root) /* Now everything is set; Indicate that nothing is used anymore */ root->used= 0; + root->first_block_usage= 0; } diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 7ecd00f5b39..8f17d8519b8 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -100,6 +100,8 @@ SUFFIXES = .sh -e 's!@''CC''@!@CC@!'\ -e 's!@''CXX''@!@CXX@!'\ -e 's!@''GXX''@!@GXX@!'\ + -e 's!@''CC_VERSION''@!@CC_VERSION@!'\ + -e 's!@''CXX_VERSION''@!@CXX_VERSION@!'\ -e 's!@''PERL''@!@PERL@!' \ -e 's!@''ASFLAGS''@!@SAVE_ASFLAGS@!'\ -e 's!@''CFLAGS''@!@SAVE_CFLAGS@!'\ diff --git a/scripts/mysqlbug.sh b/scripts/mysqlbug.sh index 8dbc931b7f6..49ac08d0013 100644 --- a/scripts/mysqlbug.sh +++ b/scripts/mysqlbug.sh @@ -231,6 +231,8 @@ ${ORGANIZATION- $ORGANIZATION_C} >Class: $CLASS_C >Release: mysql-${VERSION} ($COMPILATION_COMMENT) `test -n "$MYSQL_SERVER" && echo ">Server: $MYSQL_SERVER"` +>C compiler: @CC_VERSION@ +>C++ compiler: @CXX_VERSION@ >Environment: $ENVIRONMENT_C `test -n "$SYSTEM" && echo "System: $SYSTEM"` diff --git a/sql/item_func.cc b/sql/item_func.cc index c3b1190a4b6..20d7bffce21 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2038,11 +2038,14 @@ void Item_func_get_user_var::fix_length_and_dec() maybe_null=1; decimals=NOT_FIXED_DEC; max_length=MAX_BLOB_WIDTH; - if ((var_entry= get_variable(&thd->user_vars, name, 0))) - const_var_flag= thd->query_id != var_entry->update_query_id; + var_entry= get_variable(&thd->user_vars, name, 0); } +bool Item_func_get_user_var::const_item() const +{ return var_entry && current_thd->query_id != var_entry->update_query_id; } + + enum Item_result Item_func_get_user_var::result_type() const { user_var_entry *entry; diff --git a/sql/item_func.h b/sql/item_func.h index 501dcdadc3f..31310ab564e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -902,11 +902,10 @@ class Item_func_get_user_var :public Item_func { LEX_STRING name; user_var_entry *var_entry; - bool const_var_flag; public: Item_func_get_user_var(LEX_STRING a): - Item_func(), name(a), const_var_flag(1) {} + Item_func(), name(a) {} user_var_entry *get_entry(); double val(); longlong val_int(); @@ -915,9 +914,9 @@ public: void print(String *str); enum Item_result result_type() const; const char *func_name() const { return "get_user_var"; } - bool const_item() const { return const_var_flag; } + bool const_item() const; table_map used_tables() const - { return const_var_flag ? 0 : RAND_TABLE_BIT; } + { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const; unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c09255d5dae..61ae07c01e7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -242,6 +242,12 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO; #endif bool opt_large_files= sizeof(my_off_t) > 4; +#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES) +#define GET_HA_ROWS GET_ULL +#else +#define GET_HA_ROWS GET_ULONG +#endif + /* Variables to store startup options @@ -3562,7 +3568,7 @@ struct my_option my_long_options[] = {"max_join_size", OPT_MAX_JOIN_SIZE, "Joins that are probably going to read more than max_join_size records return an error.", (gptr*) &global_system_variables.max_join_size, - (gptr*) &max_system_variables.max_join_size, 0, GET_ULONG, REQUIRED_ARG, + (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, {"max_sort_length", OPT_MAX_SORT_LENGTH, "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).", @@ -3949,10 +3955,10 @@ static void set_options(void) /* Set default values for some variables */ global_system_variables.table_type=DB_TYPE_MYISAM; global_system_variables.tx_isolation=ISO_REPEATABLE_READ; - global_system_variables.select_limit= (ulong) HA_POS_ERROR; - max_system_variables.select_limit= (ulong) HA_POS_ERROR; - global_system_variables.max_join_size= (ulong) HA_POS_ERROR; - max_system_variables.max_join_size= (ulong) HA_POS_ERROR; + global_system_variables.select_limit= HA_POS_ERROR; + max_system_variables.select_limit= HA_POS_ERROR; + global_system_variables.max_join_size= HA_POS_ERROR; + max_system_variables.max_join_size= HA_POS_ERROR; #ifdef __WIN__ /* Allow Win32 users to move MySQL anywhere */ diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 4ebb2f5b476..471fd62ecb2 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -82,7 +82,7 @@ static int init_failsafe_rpl_thread(THD* thd) #endif thd->mem_root.free=thd->mem_root.used=0; - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == HA_POS_ERROR) thd->options|= OPTION_BIG_SELECTS; thd->proc_info="Thread initialized"; diff --git a/sql/set_var.cc b/sql/set_var.cc index 28222740c14..8e0baa234da 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -149,11 +149,11 @@ sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads", &max_insert_delayed_threads); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); -sys_var_thd_ulong sys_max_join_size("max_join_size", +sys_var_thd_ha_rows sys_max_join_size("max_join_size", &SV::max_join_size, fix_max_join_size); #ifndef TO_BE_DELETED /* Alias for max_join_size */ -sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size", +sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif @@ -275,7 +275,7 @@ static sys_var_thd_bit sys_unique_checks("unique_checks", /* Local state variables */ -static sys_var_thd_ulong sys_select_limit("sql_select_limit", +static sys_var_thd_ha_rows sys_select_limit("sql_select_limit", &SV::select_limit); static sys_var_timestamp sys_timestamp("timestamp"); static sys_var_last_insert_id sys_last_insert_id("last_insert_id"); @@ -576,7 +576,7 @@ static void fix_max_join_size(THD *thd, enum_var_type type) { if (type != OPT_GLOBAL) { - if (thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == HA_POS_ERROR) thd->options|= OPTION_BIG_SELECTS; else thd->options&= ~OPTION_BIG_SELECTS; @@ -723,12 +723,7 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var) if (option_limits) tmp= (ulong) getopt_ull_limit_value(tmp, option_limits); if (var->type == OPT_GLOBAL) - { - /* Lock is needed to make things safe on 32 bit systems */ - pthread_mutex_lock(&LOCK_global_system_variables); global_system_variables.*offset= (ulong) tmp; - pthread_mutex_unlock(&LOCK_global_system_variables); - } else thd->variables.*offset= (ulong) tmp; return 0; @@ -755,10 +750,60 @@ byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type) } +bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) +{ + ulonglong tmp= var->value->val_int(); + + /* Don't use bigger value than given with --maximum-variable-name=.. */ + if ((ha_rows) tmp > max_system_variables.*offset) + tmp= max_system_variables.*offset; + + if (option_limits) + tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits); + if (var->type == OPT_GLOBAL) + { + /* Lock is needed to make things safe on 32 bit systems */ + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.*offset= (ha_rows) tmp; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= (ha_rows) tmp; + return 0; +} + + +void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + { + /* We will not come here if option_limits is not set */ + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.*offset= (ha_rows) option_limits->def_value; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= global_system_variables.*offset; +} + + +byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + return (byte*) &(global_system_variables.*offset); + return (byte*) &(thd->variables.*offset); +} + + bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) + { + /* Lock is needed to make things safe on 32 bit systems */ + pthread_mutex_lock(&LOCK_global_system_variables); global_system_variables.*offset= var->value->val_int(); + pthread_mutex_unlock(&LOCK_global_system_variables); + } else thd->variables.*offset= var->value->val_int(); return 0; @@ -768,7 +813,11 @@ bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); global_system_variables.*offset= (ulong) option_limits->def_value; + pthread_mutex_unlock(&LOCK_global_system_variables); + } else thd->variables.*offset= global_system_variables.*offset; } @@ -871,6 +920,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type)); case SHOW_LONGLONG: return new Item_int(*(longlong*) value_ptr(thd, var_type)); + case SHOW_HA_ROWS: + return new Item_int((longlong) *(ha_rows*) value_ptr(thd, var_type)); case SHOW_MY_BOOL: return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1); case SHOW_CHAR: diff --git a/sql/set_var.h b/sql/set_var.h index 3edd0373db9..c74f1e827bd 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -211,6 +211,24 @@ public: }; +class sys_var_thd_ha_rows :public sys_var_thd +{ +public: + ha_rows SV::*offset; + sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg) + :sys_var_thd(name_arg), offset(offset_arg) + {} + sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg, + sys_after_update_func func) + :sys_var_thd(name_arg,func), offset(offset_arg) + {} + bool update(THD *thd, set_var *var); + void set_default(THD *thd, enum_var_type type); + SHOW_TYPE type() { return SHOW_HA_ROWS; } + byte *value_ptr(THD *thd, enum_var_type type); +}; + + class sys_var_thd_ulonglong :public sys_var_thd { public: diff --git a/sql/slave.cc b/sql/slave.cc index a4e0b029bbf..d254221e726 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1548,7 +1548,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); #endif - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; if (thd_type == SLAVE_THD_SQL) diff --git a/sql/sql_class.h b/sql/sql_class.h index 241b7d0f87a..8c4a7b83ebf 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -284,13 +284,14 @@ struct system_variables { ulonglong myisam_max_extra_sort_file_size; ulonglong myisam_max_sort_file_size; + ha_rows select_limit; + ha_rows max_join_size; ulong bulk_insert_buff_size; ulong join_buff_size; ulong long_query_time; ulong max_allowed_packet; ulong max_heap_table_size; ulong max_sort_length; - ulong max_join_size; ulong max_tmp_tables; ulong myisam_sort_buff_size; ulong net_buffer_length; @@ -302,7 +303,6 @@ struct system_variables ulong query_cache_type; ulong read_buff_size; ulong read_rnd_buff_size; - ulong select_limit; ulong sortbuff_size; ulong tmp_table_size; ulong tx_isolation; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ea9c331af8f..d9f2b9ca70d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -678,7 +678,7 @@ pthread_handler_decl(handle_one_connection,arg) goto end_thread; } - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) net->compress=1; // Use compression @@ -754,7 +754,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) #endif - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; thd->proc_info=0; @@ -1096,6 +1096,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } if (lower_case_table_names) casedn_str(db); + if (check_access(thd,DROP_ACL,db,0,1)) + break; if (thd->locked_tables || thd->active_transaction()) { send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 02f4655c655..a11abf75506 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1184,6 +1184,9 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, case SHOW_LONGLONG: net_store_data(&packet2,(longlong) *(longlong*) value); break; + case SHOW_HA_ROWS: + net_store_data(&packet2,(longlong) *(ha_rows*) value); + break; case SHOW_BOOL: net_store_data(&packet2,(ulong) *(bool*) value ? "ON" : "OFF"); break; diff --git a/sql/structs.h b/sql/structs.h index bd058a08e46..be50c8fc24d 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -129,7 +129,7 @@ enum SHOW_TYPE SHOW_UNDEF, SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION, - SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, + SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS, #ifdef HAVE_OPENSSL SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD, SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE, From 313b296b2e0b5436d1c2ac8bbfa367e2168173d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Dec 2002 18:39:53 +0100 Subject: [PATCH 46/61] removed chroot() bugfix, now --chroot in 3.23 is broken again :(( --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a5fc7eabe46..bd17f7339a4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -886,7 +886,8 @@ static void set_root(const char *path) sql_perror("chroot"); unireg_abort(1); } - my_setwd("/", MYF(0)); +// my_setwd("/", MYF(0)); + sql_print_error("Warning: --chroot option doesn't provide 100%% closed chroot jail in MySQL 3.23. Upgrade to 4.0"); #endif } From 35f6e920c5a0a991bbaae0107405230985cb7c81 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Dec 2002 20:55:51 +0200 Subject: [PATCH 47/61] btr0sea.c: Remove an assertion which can fail in a race of 3 threads innobase/btr/btr0sea.c: Remove an assertion which can fail in a race of 3 threads --- innobase/btr/btr0sea.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index a798f28b4ab..421aafba1c5 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -453,8 +453,6 @@ btr_search_info_update_slow( } if (build_index) { - ut_a(block->n_fields + block->n_bytes > 0); - btr_search_build_page_hash_index(block->frame, block->n_fields, block->n_bytes, @@ -1028,7 +1026,10 @@ btr_search_build_page_hash_index( return; } - ut_a(n_fields + n_bytes > 0); + if (n_fields + n_bytes == 0) { + + return; + } /* Calculate and cache fold values and corresponding records into an array for fast insertion to the hash index */ From 23362b5cae7acbe00b64980802e8e5e7f9480f7d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Dec 2002 03:50:09 +0200 Subject: [PATCH 48/61] errmsg.txt: More descriptive foreign key error messages sql/share/english/errmsg.txt: More descriptive foreign key error messages --- sql/share/english/errmsg.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 105cf90ca7d..93a1b66816a 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -217,8 +217,8 @@ "Deadlock found when trying to get lock; Try restarting transaction", "The used table type doesn't support FULLTEXT indexes", "Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"Cannot add or update a child row: a foreign key constraint fails", +"Cannot delete or update a parent row: a foreign key constraint fails", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", "Error when executing command %s: %-.128s", From 5f1b9717c53f19ef4f7a5206f59a7678a025dbe2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Dec 2002 10:45:06 +0200 Subject: [PATCH 49/61] Optimization of CASE bug fix --- sql/item_cmpfunc.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0d10b17ad87..c3381eb76ea 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -685,10 +685,9 @@ String *Item_func_case::val_str(String *str) null_value=1; return 0; } + null_value= 0; if (!(res=item->val_str(str))) - null_value=1; - else - null_value=item->null_value; + null_value= 1; return res; } From b69d8f4a6f4a78f1ee61936ec440fa8ebb111319 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Dec 2002 01:54:29 +0200 Subject: [PATCH 50/61] Many files: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE sql_select.cc: Remove superfluous prints to .err log when a locking SELECT fails to a deadlock or a lock wait timeout sql/sql_select.cc: Remove superfluous prints to .err log when a locking SELECT fails to a deadlock or a lock wait timeout innobase/btr/btr0sea.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/dict/dict0dict.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/fsp/fsp0fsp.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/ibuf/ibuf0ibuf.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/buf0buf.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/db0err.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/dict0mem.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/mem0mem.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/row0mysql.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/row0upd.h: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/include/mem0mem.ic: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/mem/mem0pool.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/row/row0ins.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/row/row0mysql.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/row/row0sel.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/row/row0upd.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/srv/srv0start.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE innobase/ut/ut0ut.c: Merge InnoDB-4.0.7. Support for ON UPDATE CASCADE --- innobase/btr/btr0sea.c | 92 ++++++++++--- innobase/dict/dict0dict.c | 136 +++++++++++++++---- innobase/fsp/fsp0fsp.c | 16 +-- innobase/ibuf/ibuf0ibuf.c | 13 +- innobase/include/buf0buf.h | 7 +- innobase/include/db0err.h | 5 +- innobase/include/dict0mem.h | 7 + innobase/include/mem0mem.h | 14 +- innobase/include/mem0mem.ic | 7 +- innobase/include/row0mysql.h | 10 +- innobase/include/row0upd.h | 5 +- innobase/mem/mem0pool.c | 52 +++++--- innobase/row/row0ins.c | 245 ++++++++++++++++++++++++++++++++--- innobase/row/row0mysql.c | 68 ++++++++-- innobase/row/row0sel.c | 17 ++- innobase/row/row0upd.c | 88 ++++++++++++- innobase/srv/srv0start.c | 13 +- innobase/ut/ut0ut.c | 4 +- sql/sql_select.cc | 37 ++++-- 19 files changed, 689 insertions(+), 147 deletions(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 31f001ee769..de3fe6e196e 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -19,6 +19,9 @@ Created 2/17/1996 Heikki Tuuri #include "btr0btr.h" #include "ha0ha.h" +ulint btr_search_this_is_zero = 0; /* A dummy variable to fool the + compiler */ + ulint btr_search_n_succ = 0; ulint btr_search_n_hash_fail = 0; @@ -56,16 +59,20 @@ before hash index building is started */ /************************************************************************ Builds a hash index on a page with the given parameters. If the page already -has a hash index with different parameters, the old hash index is removed. */ +has a hash index with different parameters, the old hash index is removed. +If index is non-NULL, this function checks if n_fields and n_bytes are +sensible values, and does not build a hash index if not. */ static void btr_search_build_page_hash_index( /*=============================*/ - page_t* page, /* in: index page, s- or x-latched */ - ulint n_fields, /* in: hash this many full fields */ - ulint n_bytes, /* in: hash this many bytes from the next + dict_index_t* index, /* in: index for which to build, or NULL if + not known */ + page_t* page, /* in: index page, s- or x-latched */ + ulint n_fields,/* in: hash this many full fields */ + ulint n_bytes,/* in: hash this many bytes from the next field */ - ulint side); /* in: hash for searches from this side */ + ulint side); /* in: hash for searches from this side */ /********************************************************************* This function should be called before reserving any btr search mutex, if @@ -173,7 +180,9 @@ btr_search_info_create( } /************************************************************************* -Updates the search info of an index about hash successes. */ +Updates the search info of an index about hash successes. NOTE that info +is NOT protected by any semaphore, to save CPU time! Do not assume its fields +are consistent. */ static void btr_search_info_update_hash( @@ -295,7 +304,9 @@ set_new_recomm: } /************************************************************************* -Updates the block search info on hash successes. */ +Updates the block search info on hash successes. NOTE that info and +block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any +semaphore, to save CPU time! Do not assume the fields are consistent. */ static ibool btr_search_update_block_hash_info( @@ -425,12 +436,19 @@ btr_search_info_update_slow( { buf_block_t* block; ibool build_index; - + ulint* params; + ulint* params2; + ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED) && !rw_lock_own(&btr_search_latch, RW_LOCK_EX)); block = buf_block_align(btr_cur_get_rec(cursor)); + /* NOTE that the following two function calls do NOT protect + info or block->n_fields etc. with any semaphore, to save CPU time! + We cannot assume the fields are consistent when we return from + those functions! */ + btr_search_info_update_hash(info, cursor); build_index = btr_search_update_block_hash_info(info, block, cursor); @@ -439,7 +457,7 @@ btr_search_info_update_slow( btr_search_check_free_space_in_heap(); } - + if (cursor->flag == BTR_CUR_HASH_FAIL) { /* Update the hash node reference, if appropriate */ @@ -453,10 +471,30 @@ btr_search_info_update_slow( } if (build_index) { - btr_search_build_page_hash_index(block->frame, - block->n_fields, - block->n_bytes, - block->side); + /* Note that since we did not protect block->n_fields etc. + with any semaphore, the values can be inconsistent. We have + to check inside the function call that they make sense. We + also malloc an array and store the values there to make sure + the compiler does not let the function call parameters change + inside the called function. It might be that the compiler + would optimize the call just to pass pointers to block. */ + + params = mem_alloc(3 * sizeof(ulint)); + params[0] = block->n_fields; + params[1] = block->n_bytes; + params[2] = block->side; + + /* Make sure the compiler cannot deduce the values and do + optimizations */ + + params2 = params + btr_search_this_is_zero; + + btr_search_build_page_hash_index(cursor->index, + block->frame, + params2[0], + params2[1], + params2[2]); + mem_free(params); } } @@ -974,16 +1012,20 @@ btr_search_drop_page_hash_when_freed( /************************************************************************ Builds a hash index on a page with the given parameters. If the page already -has a hash index with different parameters, the old hash index is removed. */ +has a hash index with different parameters, the old hash index is removed. +If index is non-NULL, this function checks if n_fields and n_bytes are +sensible values, and does not build a hash index if not. */ static void btr_search_build_page_hash_index( /*=============================*/ - page_t* page, /* in: index page, s- or x-latched */ - ulint n_fields, /* in: hash this many full fields */ - ulint n_bytes, /* in: hash this many bytes from the next + dict_index_t* index, /* in: index for which to build, or NULL if + not known */ + page_t* page, /* in: index page, s- or x-latched */ + ulint n_fields,/* in: hash this many full fields */ + ulint n_bytes,/* in: hash this many bytes from the next field */ - ulint side) /* in: hash for searches from this side */ + ulint side) /* in: hash for searches from this side */ { hash_table_t* table; buf_block_t* block; @@ -1026,9 +1068,17 @@ btr_search_build_page_hash_index( return; } + /* Check that the values for hash index build are sensible */ + if (n_fields + n_bytes == 0) { - return; + return; + } + + if (index && (dict_index_get_n_unique_in_tree(index) < n_fields + || (dict_index_get_n_unique_in_tree(index) == n_fields + && n_bytes > 0))) { + return; } /* Calculate and cache fold values and corresponding records into @@ -1187,8 +1237,8 @@ btr_search_move_or_delete_hash_entries( ut_a(n_fields + n_bytes > 0); - btr_search_build_page_hash_index(new_page, n_fields, n_bytes, - side); + btr_search_build_page_hash_index(NULL, new_page, n_fields, + n_bytes, side); ut_a(n_fields == block->curr_n_fields); ut_a(n_bytes == block->curr_n_bytes); ut_a(side == block->curr_side); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 563ca2521a4..c70e848c5c8 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1145,23 +1145,25 @@ dict_index_add_to_cache( } /* Check that the same column does not appear twice in the index. - InnoDB assumes this in its algorithms, e.g., update of an index - entry */ + InnoDB assumes this in its algorithms, e.g., update of an index + entry */ for (i = 0; i < dict_index_get_n_fields(index); i++) { - for (j = 0; j < i; j++) { - if (dict_index_get_nth_field(index, j)->col - == dict_index_get_nth_field(index, i)->col) { + for (j = 0; j < i; j++) { + if (dict_index_get_nth_field(index, j)->col + == dict_index_get_nth_field(index, i)->col) { - fprintf(stderr, -"InnoDB: Error: column %s appears twice in index %s of table %s\n" + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: column %s appears twice in index %s of table %s\n" "InnoDB: This is not allowed in InnoDB.\n" "InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n", - dict_index_get_nth_field(index, i)->col->name, - index->name, table->name); - } - } + dict_index_get_nth_field(index, i)->col->name, + index->name, table->name); + } + } } /* Build the cache internal representation of the index, @@ -2233,6 +2235,9 @@ dict_create_foreign_constraints( ulint error; ulint i; ulint j; + ibool is_on_delete; + ulint n_on_deletes; + ulint n_on_updates; dict_col_t* columns[500]; char* column_names[500]; ulint column_name_lens[500]; @@ -2392,6 +2397,12 @@ col_loop2: return(DB_CANNOT_ADD_CONSTRAINT); } + n_on_deletes = 0; + n_on_updates = 0; + +scan_on_conditions: + /* Loop here as long as we can find ON ... conditions */ + ptr = dict_accept(ptr, "ON", &success); if (!success) { @@ -2402,23 +2413,58 @@ col_loop2: ptr = dict_accept(ptr, "DELETE", &success); if (!success) { - dict_foreign_free(foreign); + ptr = dict_accept(ptr, "UPDATE", &success); + + if (!success) { + + dict_foreign_free(foreign); - return(DB_CANNOT_ADD_CONSTRAINT); + return(DB_CANNOT_ADD_CONSTRAINT); + } + + is_on_delete = FALSE; + n_on_updates++; + } else { + is_on_delete = TRUE; + n_on_deletes++; } ptr = dict_accept(ptr, "RESTRICT", &success); if (success) { - goto try_find_index; + goto scan_on_conditions; } ptr = dict_accept(ptr, "CASCADE", &success); if (success) { - foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE; + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_CASCADE; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_CASCADE; + } - goto try_find_index; + goto scan_on_conditions; + } + + ptr = dict_accept(ptr, "NO", &success); + + if (success) { + ptr = dict_accept(ptr, "ACTION", &success); + + if (!success) { + dict_foreign_free(foreign); + + return(DB_CANNOT_ADD_CONSTRAINT); + } + + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_NO_ACTION; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_NO_ACTION; + } + + goto scan_on_conditions; } ptr = dict_accept(ptr, "SET", &success); @@ -2451,20 +2497,23 @@ col_loop2: } } - foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL; + if (is_on_delete) { + foreign->type |= DICT_FOREIGN_ON_DELETE_SET_NULL; + } else { + foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL; + } + goto scan_on_conditions; + try_find_index: - /* We check that there are no superfluous words like 'ON UPDATE ...' - which we do not support yet. */ - - ptr = dict_accept(ptr, (char *) "ON", &success); - - if (success) { + if (n_on_deletes > 1 || n_on_updates > 1) { + /* It is an error to define more than 1 action */ + dict_foreign_free(foreign); return(DB_CANNOT_ADD_CONSTRAINT); } - + /* Try to find an index which contains the columns as the first fields and in the right order, and the types are the same as in foreign->foreign_index */ @@ -3286,7 +3335,8 @@ dict_print_info_on_foreign_keys_in_create_format( /*=============================================*/ char* buf, /* in: auxiliary buffer */ char* str, /* in/out: pointer to a string */ - ulint len, /* in: space in str available for info */ + ulint len, /* in: str has to be a buffer at least + len + 5000 bytes */ dict_table_t* table) /* in: table */ { @@ -3356,14 +3406,30 @@ dict_print_info_on_foreign_keys_in_create_format( buf2 += sprintf(buf2, ")"); - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { + if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) { buf2 += sprintf(buf2, " ON DELETE CASCADE"); } - if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { + if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) { buf2 += sprintf(buf2, " ON DELETE SET NULL"); } + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + buf2 += sprintf(buf2, " ON DELETE NO ACTION"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + buf2 += sprintf(buf2, " ON UPDATE CASCADE"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + buf2 += sprintf(buf2, " ON UPDATE SET NULL"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } no_space: @@ -3455,6 +3521,22 @@ dict_print_info_on_foreign_keys( buf2 += sprintf(buf2, " ON DELETE SET NULL"); } + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + buf2 += sprintf(buf2, " ON DELETE NO ACTION"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) { + buf2 += sprintf(buf2, " ON UPDATE CASCADE"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) { + buf2 += sprintf(buf2, " ON UPDATE SET NULL"); + } + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + buf2 += sprintf(buf2, " ON UPDATE NO ACTION"); + } + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } no_space: diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index ff586819d4a..ee48288b875 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -2479,20 +2479,20 @@ try_again: n_free = n_free_list_ext + n_free_up; if (alloc_type == FSP_NORMAL) { - /* We reserve 1 extent + 4 % of the space size to undo logs - and 1 extent + 1 % to cleaning operations; NOTE: this source + /* We reserve 1 extent + 0.5 % of the space size to undo logs + and 1 extent + 0.5 % to cleaning operations; NOTE: this source code is duplicated in the function below! */ - reserve = 2 + ((size / FSP_EXTENT_SIZE) * 5) / 100; + reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; if (n_free <= reserve + n_ext) { goto try_to_extend; } } else if (alloc_type == FSP_UNDO) { - /* We reserve 1 % of the space size to cleaning operations */ + /* We reserve 0.5 % of the space size to cleaning operations */ - reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 100; + reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200; if (n_free <= reserve + n_ext) { @@ -2572,11 +2572,11 @@ fsp_get_available_space_in_free_extents( n_free = n_free_list_ext + n_free_up; - /* We reserve 1 extent + 4 % of the space size to undo logs - and 1 extent + 1 % to cleaning operations; NOTE: this source + /* We reserve 1 extent + 0.5 % of the space size to undo logs + and 1 extent + 0.5 % to cleaning operations; NOTE: this source code is duplicated in the function above! */ - reserve = 2 + ((size / FSP_EXTENT_SIZE) * 5) / 100; + reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; if (reserve > n_free) { return(0); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 143b3bfa584..668e9419c24 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -2657,10 +2657,7 @@ reset_bit: new_bits, &mtr); } } - - ibuf_data->n_merges++; - ibuf_data->n_merged_recs += n_inserts; - + #ifdef UNIV_IBUF_DEBUG /* printf("Ibuf merge %lu records volume %lu to page no %lu\n", n_inserts, volume, page_no); */ @@ -2670,6 +2667,14 @@ reset_bit: mem_heap_free(heap); + /* Protect our statistics keeping from race conditions */ + mutex_enter(&ibuf_mutex); + + ibuf_data->n_merges++; + ibuf_data->n_merged_recs += n_inserts; + + mutex_exit(&ibuf_mutex); + ibuf_exit(); #ifdef UNIV_IBUF_DEBUG ut_a(ibuf_count_get(space, page_no) == 0); diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index f76c437bd1d..395f88a2c7c 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -728,8 +728,8 @@ struct buf_block_struct{ bufferfixed, or (2) the thread has an x-latch on the block */ - /* 5. Hash search fields: NOTE that these fields are protected by - btr_search_mutex */ + /* 5. Hash search fields: NOTE that the first 4 fields are NOT + protected by any semaphore! */ ulint n_hash_helps; /* counter which controls building of a new hash index for the page */ @@ -742,6 +742,9 @@ struct buf_block_struct{ whether the leftmost record of several records with the same prefix should be indexed in the hash index */ + + /* The following 4 fields are protected by btr_search_latch: */ + ibool is_hashed; /* TRUE if hash index has already been built on this page; note that it does not guarantee that the index is diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index ae4b0fe4cc5..c67c09bad27 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -42,8 +42,9 @@ Created 5/24/1996 Heikki Tuuri #define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint to a table failed */ #define DB_CORRUPTION 39 /* data structure corruption noticed */ -#define DB_COL_APPEARS_TWICE_IN_INDEX 40 - +#define DB_COL_APPEARS_TWICE_IN_INDEX 40 /* InnoDB cannot handle an index + where same column appears twice */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 22293389bae..0798541cfe0 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -280,8 +280,15 @@ struct dict_foreign_struct{ table */ }; +/* The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that +a foreign key constraint is enforced, therefore RESTRICT just means no flag */ #define DICT_FOREIGN_ON_DELETE_CASCADE 1 #define DICT_FOREIGN_ON_DELETE_SET_NULL 2 +#define DICT_FOREIGN_ON_UPDATE_CASCADE 4 +#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8 +#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 +#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 + #define DICT_INDEX_MAGIC_N 76789786 diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index bfd25f5bdbe..9ab3b2cd754 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -127,16 +127,18 @@ mem_heap_create_func( ulint line /* in: line where created */ ); /********************************************************************* -NOTE: Use the corresponding macro instead of this function. -Frees the space occupied by a memory heap. */ +NOTE: Use the corresponding macro instead of this function. Frees the space +occupied by a memory heap. In the debug version erases the heap memory +blocks. */ UNIV_INLINE void mem_heap_free_func( /*===============*/ - mem_heap_t* heap, /* in, own: heap to be freed */ - char* file_name, /* in: file name where freed */ - ulint line /* in: line where freed */ -); + mem_heap_t* heap, /* in, own: heap to be freed */ + char* file_name __attribute__((unused)), + /* in: file name where freed */ + ulint line __attribute__((unused))); + /* in: line where freed */ /******************************************************************* Allocates n bytes of memory from a memory heap. */ UNIV_INLINE diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index a7abb93d91d..1ff8c66e80a 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -440,9 +440,10 @@ void mem_heap_free_func( /*===============*/ mem_heap_t* heap, /* in, own: heap to be freed */ - char* file_name, /* in: file name where freed */ - ulint line /* in: line where freed */ - ) + char* file_name __attribute__((unused)), + /* in: file name where freed */ + ulint line __attribute__((unused))) + /* in: line where freed */ { mem_block_t* block; mem_block_t* prev_block; diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 44b470fe7ea..25d2ab77007 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -492,7 +492,11 @@ struct row_prebuilt_struct { fetch many rows from the same cursor: it saves CPU time to fetch them in a batch; we reserve mysql_row_len - bytes for each such row */ + bytes for each such row; these + pointers point 4 bytes past the + allocated mem buf start, because + there is a 4 byte magic number at the + start and at the end */ ulint fetch_cache_first;/* position of the first not yet fetched row in fetch_cache */ ulint n_fetch_cached; /* number of not yet fetched rows @@ -501,8 +505,12 @@ struct row_prebuilt_struct { to this heap */ mem_heap_t* old_vers_heap; /* memory heap where a previous version is built in consistent read */ + ulint magic_n2; /* this should be the same as + magic_n */ }; +#define ROW_PREBUILT_FETCH_MAGIC_N 465765687 + #define ROW_MYSQL_WHOLE_ROW 0 #define ROW_MYSQL_REC_FIELDS 1 #define ROW_MYSQL_NO_TEMPLATE 2 diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 9a3e2463267..273ec6074eb 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -312,8 +312,11 @@ struct upd_node_struct{ ibool in_mysql_interface; /* TRUE if the update node was created for the MySQL interface */ + dict_foreign_t* foreign;/* NULL or pointer to a foreign key + constraint if this update node is used in + doing an ON DELETE or ON UPDATE operation */ upd_node_t* cascade_node;/* NULL or an update node template which - is used to implement ON DELETE CASCADE + is used to implement ON DELETE/UPDATE CASCADE or ... SET NULL for foreign keys */ mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade node is created */ diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index 61cf1e50ce9..1c32a4d02a6 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -15,6 +15,7 @@ Created 5/12/1997 Heikki Tuuri #include "ut0mem.h" #include "ut0lst.h" #include "ut0byte.h" +#include "mem0mem.h" /* We would like to use also the buffer frames to allocate memory. This would be desirable, because then the memory consumption of the database @@ -251,7 +252,6 @@ mem_pool_fill_free_list( mem_area_t* area; mem_area_t* area2; ibool ret; - char err_buf[500]; ut_ad(mutex_own(&(pool->mutex))); @@ -300,11 +300,8 @@ mem_pool_fill_free_list( } if (UT_LIST_GET_LEN(pool->free_list[i + 1]) == 0) { - ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100); - fprintf(stderr, -"InnoDB: Error: Removing element from mem pool free list %lu\n" -"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n", - i + 1, err_buf); + mem_analyze_corruption((byte*)area); + ut_a(0); } @@ -340,7 +337,6 @@ mem_area_alloc( mem_area_t* area; ulint n; ibool ret; - char err_buf[500]; n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE)); @@ -364,20 +360,22 @@ mem_area_alloc( } if (!mem_area_get_free(area)) { - ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100); fprintf(stderr, "InnoDB: Error: Removing element from mem pool free list %lu though the\n" -"InnoDB: element is not marked free! Dump of 100 bytes around element:\n%s\n", - n, err_buf); +"InnoDB: element is not marked free!\n", + n); + + mem_analyze_corruption((byte*)area); ut_a(0); } if (UT_LIST_GET_LEN(pool->free_list[n]) == 0) { - ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100); fprintf(stderr, "InnoDB: Error: Removing element from mem pool free list %lu\n" -"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n", - n, err_buf); +"InnoDB: though the list length is 0!\n", + n); + mem_analyze_corruption((byte*)area); + ut_a(0); } @@ -451,7 +449,6 @@ mem_area_free( void* new_ptr; ulint size; ulint n; - char err_buf[500]; if (mem_out_of_mem_err_msg_count > 0) { /* It may be that the area was really allocated from the @@ -468,18 +465,25 @@ mem_area_free( area = (mem_area_t*) (((byte*)ptr) - MEM_AREA_EXTRA_SIZE); - if (mem_area_get_free(area)) { - ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100); + if (mem_area_get_free(area)) { fprintf(stderr, "InnoDB: Error: Freeing element to mem pool free list though the\n" -"InnoDB: element is marked free! Dump of 100 bytes around element:\n%s\n", - err_buf); +"InnoDB: element is marked free!\n"); + + mem_analyze_corruption((byte*)area); ut_a(0); } size = mem_area_get_size(area); - ut_ad(size != 0); + if (size == 0) { + fprintf(stderr, +"InnoDB: Error: Mem area size is 0. Possibly a memory overrun of the\n" +"InnoDB: previous allocated area!\n"); + + mem_analyze_corruption((byte*)area); + ut_a(0); + } #ifdef UNIV_LIGHT_MEM_DEBUG if (((byte*)area) + size < pool->buf + pool->size) { @@ -488,7 +492,15 @@ mem_area_free( next_size = mem_area_get_size( (mem_area_t*)(((byte*)area) + size)); - ut_a(ut_2_power_up(next_size) == next_size); + if (ut_2_power_up(next_size) != next_size) { + fprintf(stderr, +"InnoDB: Error: Memory area size %lu, next area size %lu not a power of 2!\n" +"InnoDB: Possibly a memory overrun of the buffer being freed here.\n", + size, next_size); + mem_analyze_corruption((byte*)area); + + ut_a(0); + } } #endif buddy = mem_area_get_buddy(area, size, pool); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index d0a5cfec604..990ef99b2a4 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -322,13 +322,129 @@ row_ins_clust_index_entry_by_modify( } /************************************************************************* -Either deletes or sets the referencing columns SQL NULL in a child row. -Used in ON DELETE ... clause for foreign keys when a parent row is -deleted. */ +Returns TRUE if in a cascaded update/delete an ancestor node of node +updates table. */ +static +ibool +row_ins_cascade_ancestor_updates_table( +/*===================================*/ + /* out: TRUE if an ancestor updates table */ + que_node_t* node, /* in: node in a query graph */ + dict_table_t* table) /* in: table */ +{ + que_node_t* parent; + upd_node_t* upd_node; + + parent = que_node_get_parent(node); + + while (que_node_get_type(parent) == QUE_NODE_UPDATE) { + + upd_node = parent; + + if (upd_node->table == table) { + + return(TRUE); + } + + parent = que_node_get_parent(parent); + + ut_a(parent); + } + + return(FALSE); +} + +/********************************************************************** +Calculates the update vector node->cascade->update for a child table in +a cascaded update. */ static ulint -row_ins_foreign_delete_or_set_null( -/*===============================*/ +row_ins_cascade_calc_update_vec( +/*============================*/ + /* out: number of fields in the + calculated update vector; the value + can also be 0 if no foreign key + fields changed */ + upd_node_t* node, /* in: update node of the parent + table */ + dict_foreign_t* foreign) /* in: foreign key constraint whose + type is != 0 */ +{ + upd_node_t* cascade = node->cascade_node; + dict_table_t* table = foreign->foreign_table; + dict_index_t* index = foreign->foreign_index; + upd_t* update; + upd_field_t* ufield; + dict_table_t* parent_table; + dict_index_t* parent_index; + upd_t* parent_update; + upd_field_t* parent_ufield; + ulint n_fields_updated; + ulint parent_field_no; + ulint i; + ulint j; + + ut_a(node && foreign && cascade && table && index); + + /* Calculate the appropriate update vector which will set the fields + in the child index record to the same value as the referenced index + record will get in the update. */ + + parent_table = node->table; + ut_a(parent_table == foreign->referenced_table); + parent_index = foreign->referenced_index; + parent_update = node->update; + + update = cascade->update; + + update->info_bits = 0; + update->n_fields = foreign->n_fields; + + n_fields_updated = 0; + + for (i = 0; i < foreign->n_fields; i++) { + + parent_field_no = dict_table_get_nth_col_pos( + parent_table, + dict_index_get_nth_col_no( + parent_index, i)); + + for (j = 0; j < parent_update->n_fields; j++) { + parent_ufield = parent_update->fields + j; + + if (parent_ufield->field_no == parent_field_no) { + + /* A field in the parent index record is + updated. Let us make the update vector + field for the child table. */ + + ufield = update->fields + n_fields_updated; + + ufield->field_no = + dict_table_get_nth_col_pos(table, + dict_index_get_nth_col_no(index, i)); + ufield->exp = NULL; + ufield->new_val = parent_ufield->new_val; + ufield->extern_storage = FALSE; + + n_fields_updated++; + } + } + } + + update->n_fields = n_fields_updated; + + return(n_fields_updated); +} + +/************************************************************************* +Perform referential actions or checks when a parent row is deleted or updated +and the constraint had an ON DELETE or ON UPDATE condition which was not +RESTRICT. */ +static +ulint +row_ins_foreign_check_on_constraint( +/*================================*/ /* out: DB_SUCCESS, DB_LOCK_WAIT, or error code */ que_thr_t* thr, /* in: query thread whose run_node @@ -378,15 +494,34 @@ row_ins_foreign_delete_or_set_null( ut_strlen(table->name) + 1); node = thr->run_node; - ut_a(que_node_get_type(node) == QUE_NODE_UPDATE); + if (node->is_delete && 0 == (foreign->type & + (DICT_FOREIGN_ON_DELETE_CASCADE + | DICT_FOREIGN_ON_DELETE_SET_NULL))) { - if (!node->is_delete) { - /* According to SQL-92 an UPDATE with respect to FOREIGN - KEY constraints is not semantically equivalent to a - DELETE + INSERT. Therefore we do not perform any action - here and consequently the child rows would be left - orphaned if we would let the UPDATE happen. Thus we return - an error. */ + /* No action is defined: return a foreign key error if + NO ACTION is not specified */ + + if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) { + + return(DB_SUCCESS); + } + + return(DB_ROW_IS_REFERENCED); + } + + if (!node->is_delete && 0 == (foreign->type & + (DICT_FOREIGN_ON_UPDATE_CASCADE + | DICT_FOREIGN_ON_UPDATE_SET_NULL))) { + + /* This is an UPDATE */ + + /* No action is defined: return a foreign key error if + NO ACTION is not specified */ + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) { + + return(DB_SUCCESS); + } return(DB_ROW_IS_REFERENCED); } @@ -411,7 +546,10 @@ row_ins_foreign_delete_or_set_null( cascade->table = table; - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE ) { + cascade->foreign = foreign; + + if (node->is_delete + && (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)) { cascade->is_delete = TRUE; } else { cascade->is_delete = FALSE; @@ -425,8 +563,30 @@ row_ins_foreign_delete_or_set_null( } } + /* We do not allow cyclic cascaded updating of the same + table. Check that we are not updating the same table which + is already being modified in this cascade chain. We have to + check this because the modification of the indexes of a + 'parent' table may still be incomplete, and we must avoid + seeing the indexes of the parent table in an inconsistent + state! In this way we also prevent possible infinite + update loops caused by cyclic cascaded updates. */ + + if (!cascade->is_delete + && row_ins_cascade_ancestor_updates_table(cascade, table)) { + + /* We do not know if this would break foreign key + constraints, but play safe and return an error */ + + err = DB_ROW_IS_REFERENCED; + + goto nonstandard_exit_func; + } + index = btr_pcur_get_btr_cur(pcur)->index; + ut_a(index == foreign->foreign_index); + rec = btr_pcur_get_rec(pcur); if (index->type & DICT_CLUSTERED) { @@ -520,7 +680,11 @@ row_ins_foreign_delete_or_set_null( goto nonstandard_exit_func; } - if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { + if ((node->is_delete + && (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)) + || (!node->is_delete + && (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL))) { + /* Build the appropriate update vector which sets foreign->n_fields first fields in rec to SQL NULL */ @@ -540,6 +704,26 @@ row_ins_foreign_delete_or_set_null( } } + if (!node->is_delete + && (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) { + + /* Build the appropriate update vector which sets changing + foreign->n_fields first fields in rec to new values */ + + row_ins_cascade_calc_update_vec(node, foreign); + + if (cascade->update->n_fields == 0) { + + /* The update does not change any columns referred + to in this foreign key constraint: no need to do + anything */ + + err = DB_SUCCESS; + + goto nonstandard_exit_func; + } + } + /* Store pcur position and initialize or store the cascade node pcur stored position */ @@ -629,6 +813,7 @@ row_ins_check_foreign_constraint( dtuple_t* entry, /* in: index entry for index */ que_thr_t* thr) /* in: query thread */ { + upd_node_t* upd_node; dict_table_t* check_table; dict_index_t* check_index; ulint n_fields_cmp; @@ -665,6 +850,30 @@ run_again: } } + if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) { + upd_node = thr->run_node; + + if (!(upd_node->is_delete) && upd_node->foreign == foreign) { + /* If a cascaded update is done as defined by a + foreign key constraint, do not check that + constraint for the child row. In ON UPDATE CASCADE + the update of the parent row is only half done when + we come here: if we would check the constraint here + for the child row it would fail. + + A QUESTION remains: if in the child table there are + several constraints which refer to the same parent + table, we should merge all updates to the child as + one update? And the updates can be contradictory! + Currently we just perform the update associated + with each foreign key constraint, one after + another, and the user has problems predicting in + which order they are performed. */ + + return(DB_SUCCESS); + } + } + if (check_ref) { check_table = foreign->referenced_table; check_index = foreign->referenced_index; @@ -774,8 +983,12 @@ run_again: break; } else if (foreign->type != 0) { + /* There is an ON UPDATE or ON DELETE + condition: check them in a separate + function */ + err = - row_ins_foreign_delete_or_set_null( + row_ins_foreign_check_on_constraint( thr, foreign, &pcur, &mtr); if (err != DB_SUCCESS) { diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 9ce86b5d487..ba56b3071cd 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -313,6 +313,7 @@ row_create_prebuilt( prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t)); prebuilt->magic_n = ROW_PREBUILT_ALLOCATED; + prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED; prebuilt->table = table; @@ -378,11 +379,12 @@ row_prebuilt_free( { ulint i; - if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) { + if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED + || prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED) { fprintf(stderr, - "InnoDB: Error: trying to free a corrupt\n" - "InnoDB: table handle. Magic n %lu, table name %s\n", - prebuilt->magic_n, prebuilt->table->name); +"InnoDB: Error: trying to free a corrupt\n" +"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name %s\n", + prebuilt->magic_n, prebuilt->magic_n2, prebuilt->table->name); mem_analyze_corruption((byte*)prebuilt); @@ -390,6 +392,7 @@ row_prebuilt_free( } prebuilt->magic_n = ROW_PREBUILT_FREED; + prebuilt->magic_n2 = ROW_PREBUILT_FREED; btr_pcur_free_for_mysql(prebuilt->pcur); btr_pcur_free_for_mysql(prebuilt->clust_pcur); @@ -420,7 +423,23 @@ row_prebuilt_free( for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) { if (prebuilt->fetch_cache[i] != NULL) { - mem_free(prebuilt->fetch_cache[i]); + + if ((ROW_PREBUILT_FETCH_MAGIC_N != + mach_read_from_4((prebuilt->fetch_cache[i]) - 4)) + || (ROW_PREBUILT_FETCH_MAGIC_N != + mach_read_from_4((prebuilt->fetch_cache[i]) + + prebuilt->mysql_row_len))) { + fprintf(stderr, + "InnoDB: Error: trying to free a corrupt\n" + "InnoDB: fetch buffer.\n"); + + mem_analyze_corruption( + prebuilt->fetch_cache[i]); + + ut_a(0); + } + + mem_free((prebuilt->fetch_cache[i]) - 4); } } @@ -1435,7 +1454,7 @@ int row_create_index_for_mysql( /*=======================*/ /* out: error number or DB_SUCCESS */ - dict_index_t* index, /* in: index defintion */ + dict_index_t* index, /* in: index definition */ trx_t* trx) /* in: transaction handle */ { ind_node_t* node; @@ -1444,7 +1463,9 @@ row_create_index_for_mysql( ulint namelen; ulint keywordlen; ulint err; - + ulint i; + ulint j; + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1465,6 +1486,31 @@ row_create_index_for_mysql( return(DB_SUCCESS); } + /* Check that the same column does not appear twice in the index. + InnoDB assumes this in its algorithms, e.g., update of an index + entry */ + + for (i = 0; i < dict_index_get_n_fields(index); i++) { + for (j = 0; j < i; j++) { + if (0 == ut_strcmp( + dict_index_get_nth_field(index, j)->name, + dict_index_get_nth_field(index, i)->name)) { + + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: column %s appears twice in index %s of table %s\n" +"InnoDB: This is not allowed in InnoDB.\n", + dict_index_get_nth_field(index, i)->name, + index->name, index->table_name); + + err = DB_COL_APPEARS_TWICE_IN_INDEX; + + goto error_handling; + } + } + } + heap = mem_heap_create(512); trx->dict_operation = TRUE; @@ -1477,11 +1523,13 @@ row_create_index_for_mysql( SESS_COMM_EXECUTE, 0)); que_run_threads(thr); - err = trx->error_state; + err = trx->error_state; + que_graph_free((que_t*) que_node_get_parent(thr)); + +error_handling: if (err != DB_SUCCESS) { /* We have special error handling here */ - ut_a(err == DB_OUT_OF_FILE_SPACE); trx->error_state = DB_SUCCESS; @@ -1491,8 +1539,6 @@ row_create_index_for_mysql( trx->error_state = DB_SUCCESS; } - - que_graph_free((que_t*) que_node_get_parent(thr)); trx->op_info = (char *) ""; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index a3744089258..ea5b3020c08 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2415,6 +2415,7 @@ row_sel_push_cache_row_for_mysql( row_prebuilt_t* prebuilt, /* in: prebuilt struct */ rec_t* rec) /* in: record to push */ { + byte* buf; ulint i; ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); @@ -2424,8 +2425,18 @@ row_sel_push_cache_row_for_mysql( /* Allocate memory for the fetch cache */ for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) { - prebuilt->fetch_cache[i] = mem_alloc( - prebuilt->mysql_row_len); + + /* A user has reported memory corruption in these + buffers in Linux. Put magic numbers there to help + to track a possible bug. */ + + buf = mem_alloc(prebuilt->mysql_row_len + 8); + + prebuilt->fetch_cache[i] = buf + 4; + + mach_write_to_4(buf, ROW_PREBUILT_FETCH_MAGIC_N); + mach_write_to_4(buf + 4 + prebuilt->mysql_row_len, + ROW_PREBUILT_FETCH_MAGIC_N); } } @@ -2437,7 +2448,7 @@ row_sel_push_cache_row_for_mysql( prebuilt->n_fetch_cached++; } - + /************************************************************************* Tries to do a shortcut to fetch a clustered index record with a unique key, using the hash index if possible (not always). We assume that the search diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 1231c94da63..64569bf3f96 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -71,6 +71,20 @@ the x-latch freed? The most efficient way for performing a searched delete is obviously to keep the x-latch for several steps of query graph execution. */ +/*************************************************************** +Checks if an update vector changes some of the first fields of an index +record. */ +static +ibool +row_upd_changes_first_fields( +/*=========================*/ + /* out: TRUE if changes */ + dtuple_t* entry, /* in: old value of index entry */ + dict_index_t* index, /* in: index of entry */ + upd_t* update, /* in: update vector for the row */ + ulint n); /* in: how many first fields to check */ + + /************************************************************************* Checks if index currently is mentioned as a referenced index in a foreign key constraint. */ @@ -132,6 +146,7 @@ ulint row_upd_check_references_constraints( /*=================================*/ /* out: DB_SUCCESS or an error code */ + upd_node_t* node, /* in: row update node */ btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the cursor position is lost in this function! */ dict_table_t* table, /* in: table in question */ @@ -173,7 +188,16 @@ row_upd_check_references_constraints( foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign) { - if (foreign->referenced_index == index) { + /* Note that we may have an update which updates the index + record, but does NOT update the first fields which are + referenced in a foreign key constraint. Then the update does + NOT break the constraint. */ + + if (foreign->referenced_index == index + && (node->is_delete + || row_upd_changes_first_fields(entry, index, + node->update, foreign->n_fields))) { + if (foreign->foreign_table == NULL) { dict_table_get(foreign->foreign_table_name, trx); @@ -189,10 +213,9 @@ row_upd_check_references_constraints( } /* NOTE that if the thread ends up waiting for a lock - we will release dict_operation_lock - temporarily! But the counter on the table - protects 'foreign' from being dropped while the check - is running. */ + we will release dict_operation_lock temporarily! + But the counter on the table protects 'foreign' from + being dropped while the check is running. */ err = row_ins_check_foreign_constraint(FALSE, foreign, table, index, entry, thr); @@ -255,6 +278,7 @@ upd_node_create( node->index = NULL; node->update = NULL; + node->foreign = NULL; node->cascade_heap = NULL; node->cascade_node = NULL; @@ -953,6 +977,53 @@ row_upd_changes_some_index_ord_field_binary( return(FALSE); } +/*************************************************************** +Checks if an update vector changes some of the first fields of an index +record. */ +static +ibool +row_upd_changes_first_fields( +/*=========================*/ + /* out: TRUE if changes */ + dtuple_t* entry, /* in: index entry */ + dict_index_t* index, /* in: index of entry */ + upd_t* update, /* in: update vector for the row */ + ulint n) /* in: how many first fields to check */ +{ + upd_field_t* upd_field; + dict_field_t* ind_field; + dict_col_t* col; + ulint n_upd_fields; + ulint col_pos; + ulint i, j; + + ut_a(update && index); + ut_a(n <= dict_index_get_n_fields(index)); + + n_upd_fields = upd_get_n_fields(update); + + for (i = 0; i < n; i++) { + + ind_field = dict_index_get_nth_field(index, i); + col = dict_field_get_col(ind_field); + col_pos = dict_col_get_clust_pos(col); + + for (j = 0; j < n_upd_fields; j++) { + + upd_field = upd_get_nth_field(update, j); + + if (col_pos == upd_field->field_no + && cmp_dfield_dfield( + dtuple_get_nth_field(entry, i), + &(upd_field->new_val))) { + return(TRUE); + } + } + } + + return(FALSE); +} + /************************************************************************* Copies the column values from a record. */ UNIV_INLINE @@ -1106,9 +1177,11 @@ row_upd_sec_index_entry( err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE, thr, &mtr); if (err == DB_SUCCESS && check_ref) { + /* NOTE that the following call loses the position of pcur ! */ err = row_upd_check_references_constraints( + node, &pcur, index->table, index, thr, &mtr); if (err != DB_SUCCESS) { @@ -1224,7 +1297,7 @@ row_upd_clust_rec_by_insert( if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ - err = row_upd_check_references_constraints( + err = row_upd_check_references_constraints(node, pcur, table, index, thr, mtr); if (err != DB_SUCCESS) { @@ -1392,7 +1465,8 @@ row_upd_del_mark_clust_rec( if (err == DB_SUCCESS && check_ref) { /* NOTE that the following call loses the position of pcur ! */ - err = row_upd_check_references_constraints(pcur, index->table, + err = row_upd_check_references_constraints(node, + pcur, index->table, index, thr, mtr); if (err != DB_SUCCESS) { mtr_commit(mtr); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index d6e8a8dcb4a..ec674b69256 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -529,6 +529,9 @@ open_or_create_log_file( new database */ ibool* log_file_created, /* out: TRUE if new log file created */ + ibool log_file_has_been_opened,/* in: TRUE if a log file has been + opened before: then it is an error + to try to create another log file */ ulint k, /* in: log group number */ ulint i) /* in: log file number in group */ { @@ -581,12 +584,17 @@ open_or_create_log_file( } } else { *log_file_created = TRUE; - + ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Log file %s did not exist: new to be created\n", name); + if (log_file_has_been_opened) { + + return(DB_ERROR); + } + fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n", name, srv_log_file_size >> (20 - UNIV_PAGE_SIZE_SHIFT)); @@ -1160,7 +1168,8 @@ innobase_start_or_create_for_mysql(void) for (i = 0; i < srv_n_log_files; i++) { err = open_or_create_log_file(create_new_db, - &log_file_created, k, i); + &log_file_created, + log_opened, k, i); if (err != DB_SUCCESS) { return((int) err); diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index c77cbe9cdcf..ff5d11d84ed 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -262,7 +262,7 @@ ut_print_buf( data = buf; for (i = 0; i < len; i++) { - if (isprint((char)(*data))) { + if (isprint((int)(*data))) { printf("%c", (char)*data); } data++; @@ -302,7 +302,7 @@ ut_sprintf_buf( data = buf; for (i = 0; i < len; i++) { - if (isprint((char)(*data))) { + if (isprint((int)(*data))) { n += sprintf(str + n, "%c", (char)*data); } else { n += sprintf(str + n, "."); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1e70064b4a1..28aa21e94ce 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4709,7 +4709,10 @@ join_read_const(JOIN_TAB *tab) empty_record(table); if (error != HA_ERR_KEY_NOT_FOUND) { - sql_print_error("read_const: Got error %d when reading table %s", + /* Locking reads can legally return also these errors, do not + print them to the .err log */ + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_const: Got error %d when reading table %s", error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -4772,7 +4775,8 @@ join_read_always_key(JOIN_TAB *tab) { if (error != HA_ERR_KEY_NOT_FOUND) { - sql_print_error("read_const: Got error %d when reading table %s",error, + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_const: Got error %d when reading table %s",error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -4801,7 +4805,8 @@ join_read_last_key(JOIN_TAB *tab) { if (error != HA_ERR_KEY_NOT_FOUND) { - sql_print_error("read_const: Got error %d when reading table %s",error, + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_const: Got error %d when reading table %s",error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -4833,7 +4838,8 @@ join_read_next_same(READ_RECORD *info) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("read_next: Got error %d when reading table %s",error, + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_next: Got error %d when reading table %s",error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -4855,7 +4861,8 @@ join_read_prev_same(READ_RECORD *info) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("read_next: Got error %d when reading table %s",error, + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_next: Got error %d when reading table %s",error, table->path); table->file->print_error(error,MYF(0)); error= 1; @@ -4926,7 +4933,8 @@ join_read_first(JOIN_TAB *tab) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { - sql_print_error("read_first_with_key: Got error %d when reading table", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_first_with_key: Got error %d when reading table", error); table->file->print_error(error,MYF(0)); return 1; @@ -4945,7 +4953,9 @@ join_read_next(READ_RECORD *info) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("read_next_with_key: Got error %d when reading table %s", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error( + "read_next_with_key: Got error %d when reading table %s", error, info->table->path); info->file->print_error(error,MYF(0)); return 1; @@ -4977,7 +4987,8 @@ join_read_last(JOIN_TAB *tab) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("read_last_with_key: Got error %d when reading table", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("read_last_with_key: Got error %d when reading table", error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -4996,7 +5007,9 @@ join_read_prev(READ_RECORD *info) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("read_prev_with_key: Got error %d when reading table: %s", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error( + "read_prev_with_key: Got error %d when reading table: %s", error,info->table->path); info->file->print_error(error,MYF(0)); return 1; @@ -5024,7 +5037,8 @@ join_ft_read_first(JOIN_TAB *tab) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("ft_read_first: Got error %d when reading table %s", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("ft_read_first: Got error %d when reading table %s", error, table->path); table->file->print_error(error,MYF(0)); return 1; @@ -5042,7 +5056,8 @@ join_ft_read_next(READ_RECORD *info) { if (error != HA_ERR_END_OF_FILE) { - sql_print_error("ft_read_next: Got error %d when reading table %s", + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + sql_print_error("ft_read_next: Got error %d when reading table %s", error, info->table->path); info->file->print_error(error,MYF(0)); return 1; From f0a3a93741724884b80f0eede0dac4074a24a25c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Dec 2002 13:33:55 +0100 Subject: [PATCH 51/61] - fix CC_VERSION and CXX_VERSION for compilers that return multiple lines of output for "--version" (e.g. gcc 3.x) --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index f35b9fa7da9..6dd838bb5f2 100644 --- a/configure.in +++ b/configure.in @@ -130,7 +130,7 @@ AC_PROG_CXX AC_PROG_CPP # Print version of CC and CXX compiler (if they support --version) -CC_VERSION=`$CC --version` +CC_VERSION=`$CC --version | sed 1q` if test $? -eq "0" then AC_MSG_CHECKING("C Compiler version"); @@ -138,7 +138,7 @@ then else CC_VERSION="" fi -CXX_VERSION=`$CXX --version` +CXX_VERSION=`$CXX --version | sed 1q` if test $? -eq "0" then AC_MSG_CHECKING("C++ compiler version"); From 8753e655d93f7616220132f13b8ea426e4f4cea7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Dec 2002 14:33:11 +0200 Subject: [PATCH 52/61] fix for an error in the merge from 3.23 --- mysql-test/r/case.result | 5 +++++ mysql-test/t/case.test | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 183e2692d7a..e5fc7218c50 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -63,7 +63,12 @@ nothing 2 one 1 two 1 drop table t1; +drop table if exists t1; +create table t1 (row int not null, col int not null, val varchar(255) not null); +insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); +select max(case col when 1 then val else null end) as color from t1 group by row; color orange yellow green +drop table if exists t1; diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index f2b8d42e07c..b5a1a60f15b 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -30,8 +30,8 @@ insert into t1 values(1),(2),(3),(4); select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase; select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase; drop table t1; -drop table if exists t; +drop table if exists t1; create table t1 (row int not null, col int not null, val varchar(255) not null); insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); select max(case col when 1 then val else null end) as color from t1 group by row; -drop table if exists t; +drop table if exists t1; From a7f0745dfac90b6f832e40a71c55c2312151aec0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Dec 2002 16:25:03 +0100 Subject: [PATCH 53/61] - bumped up version number to 4.0.8-gamma - tagged ChangeSet 1.1484 as mysql-4.0.7 configure.in: - bumped up version number to 4.0.8-gamma --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 6dd838bb5f2..195cf6be4e1 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.7-gamma) +AM_INIT_AUTOMAKE(mysql, 4.0.8-gamma) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 868ed1135fb1501e69f58a4792fb04e822cf754a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2002 15:24:40 +0200 Subject: [PATCH 54/61] Update of test results --- mysql-test/r/case.result | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 183e2692d7a..661ffa99f2c 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -63,7 +63,12 @@ nothing 2 one 1 two 1 drop table t1; +drop table if exists t; +create table t1 (row int not null, col int not null, val varchar(255) not null); +insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); +select max(case col when 1 then val else null end) as color from t1 group by row; color orange yellow green +drop table if exists t; From ad22d0cbacd59f7dcac4ccc121486c614e609b93 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2002 15:55:22 +0200 Subject: [PATCH 55/61] Test cleanup mysql-test/r/case.result: Removed unnecessary drop commands mysql-test/t/case.test: Removed unnecessary drop commands --- mysql-test/r/case.result | 3 +-- mysql-test/t/case.test | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 661ffa99f2c..4c16b375400 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -63,7 +63,6 @@ nothing 2 one 1 two 1 drop table t1; -drop table if exists t; create table t1 (row int not null, col int not null, val varchar(255) not null); insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); select max(case col when 1 then val else null end) as color from t1 group by row; @@ -71,4 +70,4 @@ color orange yellow green -drop table if exists t; +drop table t1; diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index b5a1a60f15b..3ba3a292c77 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -30,8 +30,12 @@ insert into t1 values(1),(2),(3),(4); select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase; select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase; drop table t1; -drop table if exists t1; + +# +# Test MAX(CASE ... ) that can return null +# + create table t1 (row int not null, col int not null, val varchar(255) not null); insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small'); select max(case col when 1 then val else null end) as color from t1 group by row; -drop table if exists t1; +drop table t1; From f1696d4f5f001d59204f19b2ef3fa921c9336a0f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2002 18:26:37 +0200 Subject: [PATCH 56/61] Cut hostnames at HOSTNAME_LENGTH to avoid theoretical hostname overruns Changed long packat handling to check for packets of length 0xffffff. This does however break packet handling for older clients. If you are using packets >= 16M then you need to upgrade client and server after this patch. Docs/internals.texi: Updated documentation for 4.1 protocol sql/ha_innodb.cc: Optimization of checking command sql/item.h: Removed automatic set of length for Item_string sql/item_create.cc: Optimized create of create_func_current_user() sql/net_serv.cc: Fixed wrong max packet length sql/sql_acl.cc: Safety fix. sql/sql_parse.cc: Cut hostnames at HOSTNAME_LENGTH to avoid theoretical hostname overruns --- Docs/internals.texi | 83 +++++++++++++++++++++++---------------------- sql/ha_innodb.cc | 9 ++--- sql/item.h | 2 -- sql/item_create.cc | 12 ++++--- sql/net_serv.cc | 2 +- sql/sql_acl.cc | 2 +- sql/sql_parse.cc | 2 ++ 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Docs/internals.texi b/Docs/internals.texi index 18bdc8d8b4c..6719bd4a6fa 100644 --- a/Docs/internals.texi +++ b/Docs/internals.texi @@ -1585,7 +1585,7 @@ fe 00 . . @node 4.1 protocol changes,,, @section Changes to 4.0 protocol in 4.1 -All basic package handling is identical to 4.0. When communication +All basic packet handling is identical to 4.0. When communication with an old 4.0 or 3.x client we will use the old protocol. The new things that we support with 4.1 are: @@ -1596,7 +1596,7 @@ Warnings @item Prepared statements @item -Binary protocol (will be much faster than the current protocol that +Binary protocol (will be faster than the current protocol that converts everything to strings) @end itemize @@ -1617,15 +1617,15 @@ results will sent as binary (low-byte-first). @end itemize -@node 4.1 field package,,, -@section 4.1 field description package +@node 4.1 field packet,,, +@section 4.1 field description packet -The field description package is sent as a response to a query that -contains a result set. It can be distinguished from a ok package by -the fact that the first byte can't be 0 for a field package. -@xref {4.1 ok package}. +The field description packet is sent as a response to a query that +contains a result set. It can be distinguished from a ok packet by +the fact that the first byte can't be 0 for a field packet. +@xref {4.1 ok packet}. -The header package has the following structure: +The header packet has the following structure: @multitable @columnfractions .10 .90 @item Size @tab Comment @@ -1634,7 +1634,7 @@ The header package has the following structure: uses this to send the number of rows in the table) @end multitable -This package is always followed by a field description set. +This packet is always followed by a field description set. @xref{4.1 field desc}. @node 4.1 field desc,,, @@ -1655,17 +1655,17 @@ The field description result set contains the meta info for a result set. @end multitable -@node 4.1 ok package,,, -@section 4.1 ok package +@node 4.1 ok packet,,, +@section 4.1 ok packet -The ok package is the first that is sent as an response for a query +The ok packet is the first that is sent as an response for a query that didn't return a result set. -The ok package has the following structure: +The ok packet has the following structure: @multitable @columnfractions .10 .90 @item Size @tab Comment -@item 1 @tab 0 ; Marker for ok package +@item 1 @tab 0 ; Marker for ok packet @item 1-9 @tab Affected rows @item 1-9 @tab Last insert id (0 if one wasn't used) @item 2 @tab Server status; Can be used by client to check if we are inside an transaction @@ -1681,10 +1681,10 @@ The message is optional. For example for multi line INSERT it contains a string for how many rows was inserted / deleted. -@node 4.1 end package,,, -@section 4.1 end package +@node 4.1 end packet,,, +@section 4.1 end packet -The end package is sent as the last package for +The end packet is sent as the last packet for @itemize @bullet @item @@ -1695,41 +1695,42 @@ End of parameter type information End of result set @end itemize -The end package has the following structure: +The end packet has the following structure: @multitable @columnfractions .10 .90 @item Size @tab Comment -@item 1 @tab 254 ; Marker for EOF package +@item 1 @tab 254 ; Marker for EOF packet @item 2 @tab Warning count @item 2 @tab Status flags (For flags like SERVER_STATUS_MORE_RESULTS) @end multitable -Note that a normal package may start with byte 254, which means +Note that a normal packet may start with byte 254, which means 'length stored in 9 bytes'. One can different between these cases by checking the packet length < 9 bytes (in which case it's and end packet). -@node 4.1 error package -@section 4.1 error package. +@node 4.1 error packet +@section 4.1 error packet. -The error package is sent when something goes wrong. -The error package has the following structure: +The error packet is sent when something goes wrong. +The error packet has the following structure: @multitable @columnfractions .10 .90 @item Size @tab Comment -@item 1 @tab 255 Error package marker +@item 1 @tab 255 Error packet marker +@item 2 @tab Error code @item 1-255 @tab Null terminated error message @end multitable -The client/server protocol is designed in such a way that a package -can only start with 255 if it's an error package. +The client/server protocol is designed in such a way that a packet +can only start with 255 if it's an error packet. @node 4.1 prep init,,, -@section 4.1 prepared statement init package +@section 4.1 prepared statement init packet -This is the return package when one sends a query with the COM_PREPARE +This is the return packet when one sends a query with the COM_PREPARE command. @multitable @columnfractions .10 .90 @@ -1755,8 +1756,8 @@ Note that the above is not yet in 4.1 but will be added this month. As MySQL can have a parameter 'anywhere' it will in many cases not be able to provide the optimal information for all parameters. -If number of columns, in the header package, is not 0 then the -prepared statement will contain a result set. In this case the package +If number of columns, in the header packet, is not 0 then the +prepared statement will contain a result set. In this case the packet is followed by a field description result set. @xref{4.1 field descr}. @@ -1768,22 +1769,22 @@ value. One can call mysql_send_long_data() multiple times for the same parameter; The server will concatenate the results to a one big string. -The server will not require an end package for the string. +The server will not require an end packet for the string. mysql_send_long_data() is responsible updating a flag that all data has been sent. (Ie; That the last call to mysql_send_long_data() has the 'last_data' flag set). -This package is sent from client -> server: +This packet is sent from client -> server: @multitable @columnfractions .10 .90 @item Size @tab Comment @item 4 @tab Statement handler @item 2 @tab Parameter number @item 2 @tab Type of parameter (not used at this point) -@item # @tab data (Rest of package) +@item # @tab data (Rest of packet) @end itemize -The server will NOT send an @code{ok} or @code{error} package in +The server will NOT send an @code{ok} or @code{error} packet in responce for this. If there is any errors (like to big string), one will get the error when calling execute. @@ -1791,9 +1792,9 @@ will get the error when calling execute. @section 4.1 execute On execute we send all parameters to the server in a COM_EXECUTE -package. +packet. -The package contains the following information: +The packet contains the following information: @multitable @columnfractions .30 .70 @item Size @tab Comment @@ -1822,7 +1823,7 @@ The parameters are stored the following ways: @item string @tab 1-9 + # @tab Packed string length + string @end multitable -The result for this will be either an ok package or a binary result +The result for this will be either an ok packet or a binary result set. @node 4.1 binary result,,, @@ -1836,11 +1837,11 @@ For each result row: @item null bit map with first two bits set to 01 (bit 0,1 value 1) @item -parameter data, repeated for each not null parameter. +parameter data, repeated for each not null result column. @end itemize The idea with the reserving two bits in the null map is that we can -use standard error (first byte 255) and ok packages (first byte 0) +use standard error (first byte 255) and ok packets (first byte 0) to end a result sets. Except that the null-bit-map is shifted two steps, the server is diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index dd718f02ba9..b34de8cb831 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1907,12 +1907,9 @@ ha_innobase::write_row( the counter here. */ skip_auto_inc_decr = FALSE; - - if (error == DB_DUPLICATE_KEY) { - ut_a(user_thd->query); - dict_accept(user_thd->query, "REPLACE", - &skip_auto_inc_decr); - } + if (error == DB_DUPLICATE_KEY && + user_thd->lex.sql_command == SQLCOM_REPLACE) + skip_auto_inc_decr= TRUE; if (!skip_auto_inc_decr && incremented_auto_inc_counter && prebuilt->trx->auto_inc_lock) { diff --git a/sql/item.h b/sql/item.h index 05b906a66a6..67dcc8ad7b8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -267,8 +267,6 @@ public: } Item_string(const char *name_par,const char *str,uint length) { - if (!length) - length=strlen(str); str_value.set(str,length); max_length=length; name=(char*) name_par; diff --git a/sql/item_create.cc b/sql/item_create.cc index 1f0bad8eda3..c6fca1c01e1 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -294,10 +294,12 @@ Item *create_func_pow(Item* a, Item *b) Item *create_func_current_user() { THD *thd=current_thd; - Item_string *res=new Item_string("CURRENT_USER()", thd->priv_user, 0); - res->append("@", 1); - res->append((char *)thd->host_or_ip, 0); - return res; + char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + uint length; + + length= (uint) (strxmov(buff, thd->priv_user, "@", thd->host_or_ip, NullS) - + buff); + return new Item_string("CURRENT_USER()", thd->memdup(buff, length), length); } Item *create_func_quarter(Item* a) @@ -403,7 +405,7 @@ Item *create_func_ucase(Item* a) Item *create_func_version(void) { - return new Item_string("VERSION()",server_version, 0); + return new Item_string("VERSION()",server_version, strlen(server_version)); } Item *create_func_weekday(Item* a) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 122793b07a7..ac73a4ca15a 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -73,7 +73,7 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; #include "thr_alarm.h" #define TEST_BLOCKING 8 -#define MAX_THREE_BYTES 255L*255L*255L +#define MAX_THREE_BYTES (256L*256L*256L-1) static int net_write_buff(NET *net,const char *packet,ulong len); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 673bc441b6b..1f8f25e5fb8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1870,7 +1870,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ulong rights, ulong col_rights, bool revoke_grant) { - char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH]; + char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; int old_row_exists = 1; int error=0; ulong store_table_rights, store_col_rights; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d9f2b9ca70d..7caf75b6639 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -496,6 +496,7 @@ check_connections(THD *thd) { vio_in_addr(net->vio,&thd->remote.sin_addr); thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); + thd->host[strnlen(thd->host, HOSTNAME_LENGTH)]= 0; if (connect_errors > max_connect_errors) return(ER_HOST_IS_BLOCKED); } @@ -512,6 +513,7 @@ check_connections(THD *thd) thd->ip=0; bzero((char*) &thd->remote,sizeof(struct sockaddr)); } + /* Ensure that wrong hostnames doesn't cause buffer overflows */ vio_keepalive(net->vio, TRUE); ulong pkt_len=0; From ae2a2981a57c7cd607114f8b17212154e0e32e2c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Dec 2002 02:17:16 +0500 Subject: [PATCH 57/61] 1) Add option (--verbose) that allows user switch on/off new logging in crash-me 2) Add new test: no_id_between, that indicates if NOT ID BETWEEN interprets as ID NOT BETWEEN sql-bench/crash-me.sh: 1) Add option (--verbose) that allows user switch on/off new logging in crash-me 2) Add new test: no_id_between, that indicates if NOT ID BETWEEN interprets as ID NOT BETWEEN --- sql-bench/crash-me.sh | 50 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index adea23c5884..ea18431f8da 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -48,7 +48,7 @@ require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n"; $opt_server="mysql"; $opt_host="localhost"; $opt_database="test"; $opt_dir="limits"; -$opt_user=$opt_password=""; +$opt_user=$opt_password="";$opt_verbose=""; $opt_debug=$opt_help=$opt_Information=$opt_restart=$opt_force=$opt_quick=0; $opt_log_all_queries=$opt_fix_limit_file=$opt_batch_mode=0; $opt_db_start_cmd=""; # the db server start command @@ -67,8 +67,8 @@ $retry_limit=3; GetOptions("Information","help","server=s","debug","user=s","password=s", "database=s","restart","force","quick","log-all-queries","comment=s", "host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s", -"batch-mode","config-file=s","log-queries-to-file=s","check-server") - || usage(); +"batch-mode","config-file=s","log-queries-to-file=s","check-server", +"verbose!" => \$opt_verbose) || usage(); usage() if ($opt_help || $opt_Information); $opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0); @@ -1375,7 +1375,6 @@ if ($limits{'type_sql_date'} eq 'yes') } } - # Test: WEEK() { my $resultat="no"; @@ -1496,6 +1495,36 @@ if ($limits{'type_sql_date'} eq 'yes') } +# NOT id BETWEEN a and b +if ($limits{'func_where_not_between'} eq 'yes') +{ + my $resultat = 'error'; + my $err; + my $key='not_id_between'; + my $prompt='NOT ID BETWEEN interprets as ID NOT BETWEEN'; + print "$prompt:"; + save_incomplete($key,$prompt); + safe_query_l($key,["create table crash_me_b (i int)", + "insert into crash_me_b values(2)", + "insert into crash_me_b values(5)"]); + $err =safe_query_result_l($key, + "select i from crash_me_b where not i between 1 and 3", + 5,0); + if ($err eq 1) { + if (not defined($last_result)) { + $resultat='no'; + }; + }; + if ( $err eq 0) { + $resultat = 'yes'; + }; + safe_query_l($key,["drop table crash_me_b"]); + save_config_data($key,$resultat,$prompt); + print "$resultat\n"; +}; + + + report("LIKE on numbers","like_with_number", "create table crash_q (a int,b int)", @@ -2740,7 +2769,7 @@ $0 takes the following options: --password='password' Password for the current user. - + --restart Save states during each limit tests. This will make it possible to continue by restarting with the same options if there is some bug in the DBI or @@ -2766,6 +2795,10 @@ $0 takes the following options: --sleep='time in seconds' (Default $opt_sleep) Wait this long before restarting server. +--verbose +--noverbose + Log into the result file queries performed for determination parameter value + EOF exit(0); } @@ -3615,6 +3648,11 @@ sub safe_query_result_l{ sub safe_query_result { +# result type can be +# 8 (must be empty), 2 (Any value), 0 (number) +# 1 (char, endspaces can differ), 3 (exact char), 4 (NULL) +# 5 (char with prefix), 6 (exact, errors are ignored) +# 7 (array of numbers) my ($query,$answer,$result_type)=@_; my ($sth,$row,$result,$retry); undef($last_result); @@ -3990,7 +4028,7 @@ sub add_log { my $key = shift; my $line = shift; - $log{$key} .= $line . "\n"; + $log{$key} .= $line . "\n" if ($opt_verbose);; } sub save_all_config_data From bc1718c915e62b8612804c35cb71f4d7756a2115 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Dec 2002 10:17:35 +0200 Subject: [PATCH 58/61] ha_innodb.cc: Fix bug: could not switch trx isolation back to REPEATABLE READ after switching it to some other level sql/ha_innodb.cc: Fix bug: could not switch trx isolation back to REPEATABLE READ after switching it to some other level --- sql/ha_innodb.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index dd718f02ba9..3ab7de5d3bb 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3812,8 +3812,8 @@ innobase_map_isolation_level( enum_tx_isolation iso) /* in: MySQL isolation level code */ { switch(iso) { - case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED); case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ); + case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED); case ISO_SERIALIZABLE: return(TRX_ISO_SERIALIZABLE); case ISO_READ_UNCOMMITTED: return(TRX_ISO_READ_UNCOMMITTED); default: ut_a(0); return(0); @@ -3868,11 +3868,9 @@ ha_innobase::external_lock( trx->n_mysql_tables_in_use++; prebuilt->mysql_has_locked = TRUE; - if (thd->variables.tx_isolation != ISO_REPEATABLE_READ) { - trx->isolation_level = innobase_map_isolation_level( + trx->isolation_level = innobase_map_isolation_level( (enum_tx_isolation) thd->variables.tx_isolation); - } if (trx->isolation_level == TRX_ISO_SERIALIZABLE && prebuilt->select_lock_type == LOCK_NONE) { From 0b34c533729ef20d73a3a9954933e8a867ac7923 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Jan 2003 14:29:26 +0200 Subject: [PATCH 59/61] Small optimization of sending big blocks. Updated Italian error messages sql/net_serv.cc: Small optimization of sending big blocks. Some small formating changes sql/share/italian/errmsg.txt: Updated error messages (by Cristian Giussani) --- sql/net_serv.cc | 25 ++++++++++++++++++------ sql/share/italian/errmsg.txt | 38 ++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index ac73a4ca15a..0d4cf9b9444 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -285,6 +285,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) /* Caching the data in a local buffer before sending it. One can force the buffer to be flushed with 'net_flush'. + */ static int @@ -292,15 +293,24 @@ net_write_buff(NET *net,const char *packet,ulong len) { ulong left_length=(ulong) (net->buff_end - net->write_pos); - while (len > left_length) + if (len > left_length) { memcpy((char*) net->write_pos,packet,left_length); if (net_real_write(net,(char*) net->buff,net->max_packet)) return 1; net->write_pos=net->buff; packet+=left_length; - len-=left_length; - left_length=net->max_packet; + len-= left_length; + left_length= net->max_packet; + + /* Send out rest of the blocks as full sized blocks */ + while (len > left_length) + { + if (net_real_write(net, packet, left_length)) + return 1; + packet+= left_length; + len-= left_length; + } } memcpy((char*) net->write_pos,packet,len); net->write_pos+=len; @@ -633,7 +643,10 @@ my_real_read(NET *net, ulong *complen) #ifdef HAVE_COMPRESS if (net->compress) { - /* complen is > 0 if package is really compressed */ + /* + If the packet is compressed then complen > 0 and contains the + number of bytes in the uncompressed packet + */ *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE])); } #endif @@ -704,7 +717,7 @@ my_net_read(NET *net) { net->where_b += len; total_length += len; - len = my_real_read (net,&complen); + len = my_real_read(net,&complen); } while (len == MAX_THREE_BYTES); if (len != packet_error) len+= total_length; @@ -732,7 +745,7 @@ my_net_read(NET *net) } else { - /* reuse buffer, as there is noting in it that we need */ + /* reuse buffer, as there is nothing in it that we need */ buf_length=start_of_packet=first_packet_offset=0; } for (;;) diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 4dd7b02de4e..cc26818aa41 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -219,22 +219,22 @@ "Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)", "Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto", "Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto", -"Error connecting to master: %-.128s", -"Error running query on master: %-.128s", -"Error when executing command %s: %-.128s", -"Wrong usage of %s and %s", -"The used SELECT statements have a different number of columns", -"Can't execute the query because you have a conflicting read lock", -"Mixing of transactional and non-transactional tables is disabled", -"Option '%s' used twice in statement", -"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", -"Access denied. You need the %-.128s privilege for this operation", -"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL", -"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL", -"Variable '%-.64s' doesn't have a default value", -"Variable '%-.64s' can't be set to the value of '%-.64s'", -"Wrong argument type to variable '%-.64s'", -"Variable '%-.64s' can only be set, not read", -"Wrong usage/placement of '%s'", -"This version of MySQL doesn't yet support '%s'", -"Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Errore durante la connessione al master: %-.128s", +"Errore eseguendo una query sul master: %-.128s", +"Errore durante l'esecuzione del comando %s: %-.128s", +"Uso errato di %s e %s", +"La SELECT utilizzata ha un numero di colonne differente", +"Impossibile eseguire la query perche' c'e' un conflitto con in lock di lettura", +"E' disabilitata la possibilita' di mischiare tabelle transazionali e non-transazionali", +"L'opzione '%s' e' stata usata due volte nel comando", +"L'utente '%-.64s' ha ecceduto la risorsa '%s' (valore corrente: %ld)", +"Accesso non consentito. Serve il privilegio %-.128s per questa operazione", +"La variabile '%-.64s' e' una variabile locale ( LOCAL ) e non puo' essere cambiata usando SET GLOBAL", +"La variabile '%-.64s' e' una variabile globale ( GLOBAL ) e deve essere cambiata usando SET GLOBAL", +"La variabile '%-.64s' non ha un valore di default", +"Alla variabile '%-.64s' non puo' essere assegato il valore '%-.64s'", +"Tipo di valore errato per la variabile '%-.64s'", +"Alla variabile '%-.64s' e' di sola scrittura quindi puo' essere solo assegnato un valore, non letto", +"Uso/posizione di '%s' sbagliato", +"Questa versione di MySQL non supporta ancora '%s'", +"Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario", From 41dc1eaa4f79e0398d652ad4c89638acb4655d80 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Jan 2003 16:21:22 +0200 Subject: [PATCH 60/61] Fixing some bugs in client - server protocol and adding a feature that connection does not close in the case when client sends a buffer larger then max_allowed_packet. --- sql/net_serv.cc | 21 ++++++++++++++++++--- sql/sql_parse.cc | 6 ++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 122793b07a7..d01b28863b9 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -469,6 +469,7 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) ALARM alarm_buff; uint retry_count=0; my_bool old_mode; + uint32 old=remain; if (!thr_alarm_in_use(&alarmed)) { @@ -490,6 +491,12 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) return; } remain -= (uint32) length; + if (!remain && old==MAX_THREE_BYTES && + (length=vio_read(net->vio,(char*) net->buff,NET_HEADER_SIZE))) + { + old=remain= uint3korr(net->buff); + net->pkt_nr++; + } statistic_add(bytes_received,length,&LOCK_bytes_received); } } @@ -647,11 +654,19 @@ my_real_read(NET *net, ulong *complen) { if (net_realloc(net,helping)) { +#ifdef MYSQL_SERVER #ifndef NO_ALARM - if (i == 1) - my_net_skip_rest(net, (uint32) len, &alarmed); + if (net->compress) + { + len= packet_error; + goto end; + } + my_net_skip_rest(net, (uint32) len, &alarmed); + len=0; +#endif +#else + len= packet_error; /* Return error */ #endif - len= packet_error; /* Return error */ goto end; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d9f2b9ca70d..1e690df20dd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -884,6 +884,12 @@ bool do_command(THD *thd) vio_description(net->vio) )); return TRUE; } + else if (!packet_length) + { + send_error(net,net->last_errno,NullS); + net->error=0; + DBUG_RETURN(FALSE); + } else { packet=(char*) net->read_pos; From e229fe9801cc9fb7e3783cf708bc7cb695606c64 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Jan 2003 15:37:20 +0200 Subject: [PATCH 61/61] Added support for DROP TEMPORARY TABLE Removed mysql_warnings() API function. Post merge fixes. client/mysqltest.c: Don't use mysql_warnings(). include/mysql.h: Removed mysql_warnings() API function libmysql/libmysql.c: Removed mysql_warnings() API function mysql-test/r/rpl_log_pos.result: Updated results mysql-test/t/connect.test: Removed empty lines mysql-test/t/rpl_log_pos.test: Update to new syntax sql/item.h: Fix after merge sql/item_create.cc: Fix after merge sql/mysql_priv.h: Added support for DROP TEMPORARY TABLE sql/sql_db.cc: Added support for DROP TEMPORARY TABLE sql/sql_parse.cc: SHOW WARNINGS now shows notes, warnings and errors. Support for DROP TEMPORARY TABLE Post merge fixes sql/sql_repl.cc: Post merge fixes sql/sql_table.cc: Added support for DROP TEMPORARY TABLE --- client/mysqltest.c | 11 ++++-- include/mysql.h | 1 - libmysql/libmysql.c | 12 ------ mysql-test/r/rpl_log_pos.result | 6 +-- mysql-test/t/connect.test | 2 - mysql-test/t/rpl_log_pos.test | 8 ++-- sql/item.h | 3 +- sql/item_create.cc | 3 +- sql/mysql_priv.h | 7 ++-- sql/sql_db.cc | 2 +- sql/sql_parse.cc | 29 +++++++++------ sql/sql_repl.cc | 8 ++-- sql/sql_table.cc | 66 +++++++++++++++++++++------------ 13 files changed, 89 insertions(+), 69 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 9d724404edc..6a637c0533c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2207,10 +2207,15 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) /* Add all warnings to the result */ if (!disable_result_log && mysql_warning_count(mysql)) { - MYSQL_RES *warn_res= mysql_warnings(mysql); + MYSQL_RES *warn_res=0; + uint count= mysql_warning_count(mysql); + if (!mysql_real_query(mysql, "SHOW WARNINGS", 13)) + { + warn_res=mysql_store_result(mysql); + } if (!warn_res) - verbose_msg("Warning count is %d but didn't get any warnings\n", - mysql_warning_count(mysql)); + verbose_msg("Warning count is %u but didn't get any warnings\n", + count); else { dynstr_append_mem(ds, "Warnings:\n", 10); diff --git a/include/mysql.h b/include/mysql.h index 063d7227351..f9b8c1ecbb3 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -381,7 +381,6 @@ MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql); MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); -MYSQL_RES * STDCALL mysql_warnings(MYSQL *mysql); int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg); void STDCALL mysql_free_result(MYSQL_RES *result); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 8314b3bc24e..8cf59281719 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3515,18 +3515,6 @@ uint STDCALL mysql_thread_safe(void) #endif } -MYSQL_RES *STDCALL mysql_warnings(MYSQL *mysql) -{ - uint warning_count; - DBUG_ENTER("mysql_warnings"); - /* Save warning count as mysql_real_query may change this */ - warning_count= mysql->warning_count; - if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) - DBUG_RETURN(0); - mysql->warning_count= warning_count; - DBUG_RETURN(mysql_store_result(mysql)); -} - /**************************************************************************** Some support functions ****************************************************************************/ diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index 4ba3736604e..fa38e42ae73 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -10,9 +10,9 @@ master-bin.000001 79 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space 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 127 -slave stop; +stop slave; change master to master_log_pos=73; -slave start; +start slave; stop slave; change master to master_log_pos=73; show slave status; @@ -35,7 +35,7 @@ create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); insert into t1 values (1),(2),(3); -slave stop; +stop slave; change master to master_log_pos=79; start slave; select * from t1; diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index 0bc5ca3914f..192d3eaf3e0 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -63,5 +63,3 @@ show tables; #--error 1045 #connect (con1,localhost,test,zorro,); #--error 1045 - - diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index 03c86137ae0..bc1349a959a 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -6,9 +6,9 @@ show master status; sync_slave_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; -slave stop; +stop slave; change master to master_log_pos=73; -slave start; +start slave; sleep 5; stop slave; @@ -19,7 +19,7 @@ start slave; sleep 5; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; -slave stop; +stop slave; change master to master_log_pos=173; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT start slave; @@ -34,7 +34,7 @@ create table t1 (n int); insert into t1 values (1),(2),(3); save_master_pos; connection slave; -slave stop; +stop slave; change master to master_log_pos=79; start slave; sync_with_master; diff --git a/sql/item.h b/sql/item.h index 1ea76731fd3..89867a8cdbd 100644 --- a/sql/item.h +++ b/sql/item.h @@ -381,7 +381,8 @@ public: name=(char*) str_value.ptr(); decimals=NOT_FIXED_DEC; } - Item_string(const char *name_par,const char *str,uint length,CHARSET_INFO *cs) + Item_string(const char *name_par,const char *str,uint length, + CHARSET_INFO *cs) { str_value.set(str,length,cs); max_length=length; diff --git a/sql/item_create.cc b/sql/item_create.cc index f277061394a..0dba7f6e3ae 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -311,7 +311,8 @@ Item *create_func_current_user() length= (uint) (strxmov(buff, thd->priv_user, "@", thd->host_or_ip, NullS) - buff); - return new Item_string("CURRENT_USER()", thd->memdup(buff, length), length); + return new Item_string("CURRENT_USER()", thd->memdup(buff, length), length, + default_charset_info); } Item *create_func_quarter(Item* a) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cf0cefd76da..3d5adf24e03 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -323,11 +323,12 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags); -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); +int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary); int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool log_query); + bool drop_temporary, bool log_query); int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables, - bool if_exists, + bool if_exists, bool drop_temporary, bool log_query); int quick_rm_table(enum db_type base,const char *db, const char *table_name); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 311bf29aee7..7ff4caf356c 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -468,7 +468,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, my_dirend(dirp); if (thd->killed || - (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 1))) + (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 0, 1))) DBUG_RETURN(-1); /* diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6f8c53cede0..85658a93791 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -963,7 +963,7 @@ bool do_command(THD *thd) } else if (!packet_length) { - send_error(net,net->last_errno,NullS); + send_error(thd,net->last_errno,NullS); net->error=0; DBUG_RETURN(FALSE); } @@ -1629,7 +1629,9 @@ mysql_execute_command(THD *thd) { res= mysqld_show_warnings(thd, (ulong) ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) | - (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN))); + (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) | + (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR) + )); break; } case SQLCOM_SHOW_ERRORS: @@ -1883,7 +1885,7 @@ mysql_execute_command(THD *thd) */ if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); break; } { @@ -2293,12 +2295,17 @@ mysql_execute_command(THD *thd) } case SQLCOM_DROP_TABLE: { - if (check_table_access(thd,DROP_ACL,tables)) - goto error; /* purecov: inspected */ - if (end_active_trans(thd)) - res= -1; - else - res = mysql_rm_table(thd,tables,lex->drop_if_exists); + if (!lex->drop_temporary) + { + if (check_table_access(thd,DROP_ACL,tables)) + goto error; /* purecov: inspected */ + if (end_active_trans(thd)) + { + res= -1; + break; + } + } + res= mysql_rm_table(thd,tables,lex->drop_if_exists, lex->drop_temporary); } break; case SQLCOM_DROP_INDEX: @@ -3777,9 +3784,9 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) if (thd && !error_already_sent) { if (result) - send_error(&thd->net,0); + send_error(thd,0); else - send_ok(&thd->net); + send_ok(thd); } return result; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index c3c9d508bf6..5bdc15c2bf0 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -757,7 +757,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi) err: unlock_slave_threads(mi); if (thd && error) - send_error(&thd->net, sql_errno, errmsg); + send_error(thd, sql_errno, errmsg); DBUG_RETURN(error); } @@ -802,7 +802,7 @@ int change_master(THD* thd, MASTER_INFO* mi) init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { - net_printf(&thd,ER_SLAVE_MUST_STOP); + net_printf(thd,ER_SLAVE_MUST_STOP); unlock_slave_threads(mi); DBUG_RETURN(1); } @@ -874,7 +874,7 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - net_printf(&thd, 0, "Failed purging old relay logs: %s",errmsg); + net_printf(thd, 0, "Failed purging old relay logs: %s",errmsg); unlock_slave_threads(mi); DBUG_RETURN(1); } @@ -908,7 +908,7 @@ int change_master(THD* thd, MASTER_INFO* mi) unlock_slave_threads(mi); thd->proc_info = 0; - send_ok(&thd); + send_ok(thd); DBUG_RETURN(0); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1ab84531e40..4848c374932 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -46,7 +46,8 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, ** This will wait for all users to free the table before dropping it *****************************************************************************/ -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) +int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary) { int error; DBUG_ENTER("mysql_rm_table"); @@ -57,7 +58,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) thd->mysys_var->current_cond= &COND_refresh; VOID(pthread_mutex_lock(&LOCK_open)); - if (global_read_lock) + if (!drop_temporary && global_read_lock) { if (thd->global_read_lock) { @@ -72,7 +73,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) } } - error=mysql_rm_table_part2(thd,tables,if_exists,0); + error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary, 0); err: pthread_mutex_unlock(&LOCK_open); @@ -91,14 +92,15 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables, bool if_exists, - bool dont_log_query) + bool drop_temporary, bool dont_log_query) { int error; thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_cond= &COND_refresh; VOID(pthread_mutex_lock(&LOCK_open)); - error=mysql_rm_table_part2(thd,tables, if_exists, dont_log_query); + error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary, + dont_log_query); pthread_mutex_unlock(&LOCK_open); VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh @@ -111,6 +113,17 @@ int mysql_rm_table_part2_with_lock(THD *thd, } /* + Execute the drop of a normal or temporary table + + SYNOPSIS + mysql_rm_table_part2() + thd Thread handler + tables Tables to drop + if_exists If set, don't give an error if table doesn't exists. + In this case we give an warning of level 'NOTE' + drop_temporary Only drop temporary tables + dont_log_query Don't log the query + TODO: When logging to the binary log, we should log tmp_tables and transactional tables as separate statements if we @@ -120,10 +133,15 @@ int mysql_rm_table_part2_with_lock(THD *thd, The current code only writes DROP statements that only uses temporary tables to the cache binary log. This should be ok on most cases, but not all. + + RETURN + 0 ok + 1 Error + -1 Thread was killed */ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool dont_log_query) + bool drop_temporary, bool dont_log_query) { TABLE_LIST *table; char path[FN_REFLEN]; @@ -142,26 +160,28 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, continue; // removed temporary table } - abort_locked_tables(thd,db,table->real_name); - while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed) - { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; - } - drop_locked_tables(thd,db,table->real_name); - if (thd->killed) - DBUG_RETURN(-1); - - /* remove form file and isam files */ - strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext, - NullS); - (void) unpack_filename(path,path); error=0; + if (!drop_temporary) + { + abort_locked_tables(thd,db,table->real_name); + while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed) + { + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; + } + drop_locked_tables(thd,db,table->real_name); + if (thd->killed) + DBUG_RETURN(-1); - table_type=get_table_type(path); + /* remove form file and isam files */ + strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext, + NullS); + (void) unpack_filename(path,path); - if (access(path,F_OK)) + table_type=get_table_type(path); + } + if (drop_temporary || access(path,F_OK)) { if (if_exists) store_warning(thd, ER_BAD_TABLE_ERROR, table->real_name);