diff --git a/include/my_sys.h b/include/my_sys.h index 18d6115c75a..03a0ae70d6a 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -203,7 +203,6 @@ extern int (*fatal_error_handler_hook)(uint my_err, const char *str, /* charsets */ extern CHARSET_INFO *default_charset_info; -extern CHARSET_INFO *system_charset_info; extern CHARSET_INFO *all_charsets[256]; extern CHARSET_INFO compiled_charsets[]; diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index 4489b25ec2b..b847798586d 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -294,10 +294,10 @@ ha_print_info( { hash_cell_t* cell; /* ha_node_t* node; */ - ulint nodes = 0; +/* ulint nodes = 0; */ ulint cells = 0; - ulint len = 0; - ulint max_len = 0; +/* ulint len = 0; */ +/* ulint max_len = 0; */ ulint n_bufs; ulint i; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 136b7272c1d..0780b97890f 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -262,7 +262,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0' -) TYPE=HEAP +) TYPE=HEAP CHARSET=latin1 drop table t1; SET SESSION table_type="gemini"; SELECT @@table_type; @@ -273,6 +273,6 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0' -) TYPE=MyISAM +) TYPE=MyISAM CHARSET=latin1 SET SESSION table_type=default; drop table t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index df33af0709c..52b6fc307ae 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -140,13 +140,13 @@ id parent_id level 1015 102 2 explain select level from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 12 Using where; Using index +1 SIMPLE t1 ref level level 1 const # Using where; Using index explain select level,id from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 12 Using where; Using index +1 SIMPLE t1 ref level level 1 const # Using where; Using index explain select level,id,parent_id from t1 where level=1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref level level 1 const 12 Using where +1 SIMPLE t1 ref level level 1 const # Using where select level,id from t1 where level=1; level id 1 1002 @@ -168,9 +168,9 @@ Table Op Msg_type Msg_text test.t1 optimize error The handler for the table doesn't support optimize show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 id A 87 NULL NULL BTREE -t1 1 parent_id 1 parent_id A 43 NULL NULL BTREE -t1 1 level 1 level A 6 NULL NULL BTREE +t1 0 PRIMARY 1 id A # NULL NULL BTREE +t1 1 parent_id 1 parent_id A # NULL NULL BTREE +t1 1 level 1 level A # NULL NULL BTREE drop table t1; CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, diff --git a/mysql-test/r/rpl_relayspace.result b/mysql-test/r/rpl_relayspace.result index 5e552ef7400..610419980b5 100644 --- a/mysql-test/r/rpl_relayspace.result +++ b/mysql-test/r/rpl_relayspace.result @@ -1,9 +1,9 @@ -slave stop; +stop slave; 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; -slave start; +start slave; stop slave; create table t1 (a int); reset slave; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index bfaeee78f8e..4d1a620d67f 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -22,6 +22,8 @@ drop table t1; # # A bit bigger test +# The 'replace_result' statements are needed because the cardinality calculated +# by innodb is not always the same between runs # CREATE TABLE t1 ( @@ -43,12 +45,16 @@ update ignore t1 set id=id+1; # This will change all rows select * from t1; update ignore t1 set id=1023 where id=1010; select * from t1 where parent_id=102; +--replace_result 12 # 6 # explain select level from t1 where level=1; +--replace_result 12 # 6 # explain select level,id from t1 where level=1; +--replace_result 12 # 6 # 5 # explain select level,id,parent_id from t1 where level=1; select level,id from t1 where level=1; select level,id,parent_id from t1 where level=1; optimize table t1; +--replace_result 87 # 50 # 48 # 43 # 25 # 24 # 6 # 3 # show keys from t1; drop table t1; diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 3b4d19b7eed..88f561e0e6d 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -58,10 +58,9 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \ EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ - mysqlbug \ - fill_help_tables.sql + mysqlbug -pkgdata_DATA = make_binary_distribution +pkgdata_DATA = fill_help_tables.sql # mysqlbug should be distributed built so that people can report build # failures with it. @@ -81,8 +80,8 @@ CLEANFILES = @server_scripts@ \ mysqlhotcopy \ mysqldumpslow \ mysqld_multi \ - fill_help_tables \ - fill_help_tables.sql + fill_help_tables \ + fill_help_tables.sql SUPERCLEANFILES = mysqlbug @@ -103,6 +102,7 @@ SUFFIXES = .sh -e 's!@''libexecdir''@!$(libexecdir)!g' \ -e 's!@''pkglibdir''@!$(pkglibdir)!g' \ -e 's!@''pkgincludedir''@!$(pkgincludedir)!g' \ + -e 's!@''pkgdatadir''@!$(pkgdatadir)!g' \ -e 's!@''CC''@!@CC@!'\ -e 's!@''CXX''@!@CXX@!'\ -e 's!@''GXX''@!@GXX@!'\ @@ -137,7 +137,12 @@ SUFFIXES = .sh # Don't update the files from bitkeeper %::SCCS/s.% -all: fill_help_tables.sql make_win_src_distribution +all: fill_help_tables.sql make_win_src_distribution make_binary_distribution + +# The following rule is here to ensure that build will continue +# even if we don't have perl installed. In this case the help tables +# will be empty fill_help_tables.sql: fill_help_tables ../Docs/manual.texi - ./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql + -./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql + echo "" >> fill_help_tables.sql diff --git a/scripts/fill_help_tables.sh b/scripts/fill_help_tables.sh index 52dfa018d6e..e21b0ff2bb0 100644 --- a/scripts/fill_help_tables.sh +++ b/scripts/fill_help_tables.sh @@ -111,12 +111,12 @@ sub flush_all $example= prepare_example($example); if ($func_name ne "" && $text ne "" && !($func_name =~ /[abcdefghikjlmnopqrstuvwxyz]/)){ - print "INSERT INTO help_topic (name,description,example) VALUES ("; + print "INSERT IGNORE INTO help_topic (name,description,example) VALUES ("; print "'$func_name',"; print "'$text',"; print "'$example'"; print ");\n"; - print "INSERT INTO help_relation (help_category_id,help_topic_id) VALUES (\@cur_category,LAST_INSERT_ID());\n"; + print "INSERT IGNORE INTO help_relation (help_category_id,help_topic_id) VALUES (\@cur_category,LAST_INSERT_ID());\n"; } $func_name= ""; @@ -131,11 +131,11 @@ sub new_category $category= prepare_text($category); - print "INSERT INTO help_category (name) VALUES (\'$category\');\n"; + print "INSERT IGNORE INTO help_category (name) VALUES (\'$category\');\n"; print "SET \@cur_category=LAST_INSERT_ID();\n"; } -#print "INSERT INTO db (Host,DB,User,Select_priv) VALUES ('%','mysql_help','','Y');\n"; +#print "INSERT IGNORE INTO db (Host,DB,User,Select_priv) VALUES ('%','mysql_help','','Y');\n"; #print "CREATE DATABASE mysql_help;\n"; print "USE mysql;\n"; @@ -236,4 +236,3 @@ print "DELETE help_category "; print "FROM help_category "; print "LEFT JOIN help_relation ON help_category.help_category_id=help_relation.help_category_id "; print "WHERE help_relation.help_category_id is null;" - diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 2fff531c4c8..5ed76cefdb4 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -160,6 +160,7 @@ if [ $BASE_SYSTEM != "netware" ] ; then fi $CP support-files/* $BASE/support-files +$CP scripts/fill_help_tables.sql $BASE/support-files if [ $BASE_SYSTEM = "netware" ] ; then rm -f $BASE/support-files/magic \ @@ -183,14 +184,14 @@ do done $CP mysql-test/include/*.inc $BASE/mysql-test/include -$CP mysql-test/std_data/*.dat mysql-test/std_data/*.001 $BASE/mysql-test/std_data +$CP mysql-test/std_data/*.dat mysql-test/std_data/*.*001 $BASE/mysql-test/std_data $CP mysql-test/std_data/des_key_file $BASE/mysql-test/std_data $CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t $CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r if [ $BASE_SYSTEM != "netware" ] ; then $CP scripts/* $BASE/bin - $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 \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ \@pkgdatadir\@ ./support-files < $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 \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server $BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/mysqld_safe mv $BASE/support-files/binary-configure $BASE/configure diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 7249a095195..1a969895f7f 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (C) 2002 MySQL AB +# Copyright (C) 2002-2003 MySQL AB # For a more info consult the file COPYRIGHT distributed with this file. # This scripts creates the privilege tables db, host, user, tables_priv, @@ -43,6 +43,7 @@ parse_arguments() { --basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --ldata=*|--datadir=*) ldata=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; + --verbose) verbose=1 ;; *) if test -n "$pick_args" then @@ -76,6 +77,8 @@ execdir= bindir= basedir= force=0 +verbose=0 +fill_help_tables="" parse_arguments `$print_defaults $defaults mysqld mysql_install_db` parse_arguments PICK-ARGS-FROM-ARGV "$@" @@ -85,17 +88,37 @@ then basedir=@prefix@ bindir=@bindir@ execdir=@libexecdir@ + pkgdatadir=@pkgdatadir@ else bindir="$basedir/bin" -if test -x "$basedir/libexec/mysqld" -then - execdir="$basedir/libexec" -elif test -x "@libexecdir@/mysqld" -then - execdir="@libexecdir@" -else - execdir="$basedir/bin" + if test -x "$basedir/libexec/mysqld" + then + execdir="$basedir/libexec" + elif test -x "@libexecdir@/mysqld" + then + execdir="@libexecdir@" + else + execdir="$basedir/bin" + fi + + # find fill_help_tables.sh + for i in $basedir/support-files $basedir/share $basedir/share/mysql $basedir/scripts @pkgdatadir@ + do + if test -f $i/fill_help_tables.sql + then + pkgdatadir=$i + fi + done fi + +if test -f $pkgdatadir/fill_help_tables.sql +then + fill_help_tables=$pkgdatadir/fill_help_tables.sql +else + if test $verbose -eq 1 + then + echo "Could not find help file 'fill_help_tables.sql'". + fi fi mdata=$ldata/mysql @@ -160,8 +183,9 @@ c_t="" c_c="" # Check for old tables if test ! -f $mdata/db.frm then - echo "Preparing db table" - + if test $verbose -eq 1 ; then + echo "Preparing db table" + fi # mysqld --bootstrap wants one command/line c_d="$c_d CREATE TABLE db (" c_d="$c_d Host char(60) binary DEFAULT '' NOT NULL," @@ -190,7 +214,9 @@ fi if test ! -f $mdata/host.frm then - echo "Preparing host table" + if test $verbose -eq 1 ; then + echo "Preparing host table" + fi c_h="$c_h CREATE TABLE host (" c_h="$c_h Host char(60) binary DEFAULT '' NOT NULL," @@ -214,7 +240,9 @@ fi if test ! -f $mdata/user.frm then - echo "Preparing user table" + if test $verbose -eq 1 ; then + echo "Preparing user table" + fi c_u="$c_u CREATE TABLE user (" c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL," @@ -256,7 +284,8 @@ then REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - INSERT INTO user (host,user) values ('localhost','');" + INSERT INTO user (host,user) values ('localhost',''); +" if test "$windows" -eq 0 then @@ -270,7 +299,9 @@ fi if test ! -f $mdata/func.frm then - echo "Preparing func table" + if test $verbose -eq 1 ; then + echo "Preparing func table" + fi c_f="$c_f CREATE TABLE func (" c_f="$c_f name char(64) binary DEFAULT '' NOT NULL," @@ -284,7 +315,9 @@ fi if test ! -f $mdata/tables_priv.frm then - echo "Preparing tables_priv table" + if test $verbose -eq 1 ; then + echo "Preparing tables_priv table" + fi c_t="$c_t CREATE TABLE tables_priv (" c_t="$c_t Host char(60) binary DEFAULT '' NOT NULL," @@ -303,7 +336,9 @@ fi if test ! -f $mdata/columns_priv.frm then - echo "Preparing columns_priv table" + if test $verbose -eq 1 ; then + echo "Preparing columns_priv table" + fi c_c="$c_c CREATE TABLE columns_priv (" c_c="$c_c Host char(60) binary DEFAULT '' NOT NULL," @@ -318,7 +353,7 @@ then c_c="$c_c comment='Column privileges';" fi -echo "Installing all prepared tables" +echo "Installing privilege tables" if ( cat << END_OF_DATA use mysql; @@ -337,7 +372,10 @@ $i_f $c_t $c_c END_OF_DATA - cat fill_help_tables.sql + if test -n "$fill_help_tables" + then + cat $fill_help_tables + fi ) | eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \ --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args" then @@ -377,7 +415,6 @@ then echo "The latest information about MySQL is available on the web at" echo "http://www.mysql.com" echo "Support MySQL by buying support/licenses at https://order.mysql.com" - echo exit 0 else echo "Installation of grant tables failed!" diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 126d0628f79..7e8dab5daed 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1049,7 +1049,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, &recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF), &keydef, table_arg->keys*sizeof(MI_KEYDEF), &keyseg, - ((table_arg->key_parts + table_arg->keys) * sizeof(HA_KEYSEG)), + ((table_arg->key_parts + table_arg->keys) * + sizeof(HA_KEYSEG)), 0))) DBUG_RETURN(1); @@ -1107,7 +1108,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, keydef[i].seg[j].null_bit=0; keydef[i].seg[j].null_pos=0; } - if ((field->type() == FIELD_TYPE_BLOB) || (field->type() == FIELD_TYPE_GEOMETRY)) + if (field->type() == FIELD_TYPE_BLOB || + field->type() == FIELD_TYPE_GEOMETRY) { keydef[i].seg[j].flag|=HA_BLOB_PART; /* save number of bytes used to pack length */ diff --git a/sql/item.cc b/sql/item.cc index e39dec8592c..dc410ca2ee0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -93,20 +93,23 @@ bool Item::check_cols(uint c) void Item::set_name(const char *str,uint length, CHARSET_INFO *cs) { if (!length) - length= str ? strlen(str) : 0; - while (length && !my_isgraph(cs,*str)) - { // Fix problem with yacc - length--; - str++; - } - if (!my_charset_same(cs, system_charset_info)) - { - String tmp; - tmp.copy(str, length, cs, system_charset_info); - name=sql_strmake(tmp.ptr(),min(tmp.length(),MAX_FIELD_WIDTH)); - } + name= (char*) str; // Empty string, used by AS else - name=sql_strmake(str,min(length,MAX_FIELD_WIDTH)); + { + while (length && !my_isgraph(cs,*str)) + { // Fix problem with yacc + length--; + str++; + } + if (length && !my_charset_same(cs, system_charset_info)) + { + String tmp; + tmp.copy(str, length, cs, system_charset_info); + name=sql_strmake(tmp.ptr(),min(tmp.length(),MAX_FIELD_WIDTH)); + } + else + name=sql_strmake(str,min(length,MAX_FIELD_WIDTH)); + } } /* @@ -196,10 +199,17 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, { if (cs1 != cs2) { - CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); - if (!bin) - return 1; - set_charset(bin, COER_NOCOLL); + if (co1 == COER_EXPLICIT) + { + return 1; + } + else + { + CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); + if (!bin) + return 1; + set_charset(bin, COER_NOCOLL); + } } else set_charset(cs2, co2); @@ -984,6 +994,7 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length) str+=2; } *ptr=0; // Keep purify happy + coercibility= COER_COERCIBLE; } longlong Item_varbinary::val_int() diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index da63e3bbf4b..4d2aaf5a0f2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -111,7 +111,21 @@ bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, if (cs1 == cs2) cmp_charset= cs1; else - return 1; + { + if (co1 == COER_COERCIBLE) + { + CHARSET_INFO *c= get_charset_by_csname(cs1->csname,MY_CS_PRIMARY,MYF(0)); + if (c) + { + cmp_charset= c; + return 0; + } + else + return 1; + } + else + return 1; + } } return 0; } @@ -636,6 +650,9 @@ Item_func_ifnull::fix_length_and_dec() args[1]->result_type())) != REAL_RESULT) decimals= 0; + if (set_charset(args[0]->charset(),args[0]->coercibility, + args[1]->charset(),args[1]->coercibility)) + my_error(ER_WRONG_ARGUMENTS,MYF(0),func_name()); } @@ -676,11 +693,13 @@ Item_func_ifnull::val_str(String *str) if (!args[0]->null_value) { null_value=0; + res->set_charset(charset()); return res; } res=args[1]->val_str(str); if ((null_value=args[1]->null_value)) return 0; + res->set_charset(charset()); return res; } @@ -709,8 +728,12 @@ Item_func_if::fix_length_and_dec() else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) { cached_result_type = STRING_RESULT; - set_charset((args[1]->binary() || args[2]->binary()) ? - &my_charset_bin : args[1]->charset()); + if (set_charset(args[1]->charset(), args[1]->coercibility, + args[2]->charset(), args[2]->coercibility)) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),func_name()); + return; + } } else { @@ -746,6 +769,7 @@ Item_func_if::val_str(String *str) { Item *arg= args[0]->val_int() ? args[1] : args[2]; String *res=arg->val_str(str); + res->set_charset(charset()); null_value=arg->null_value; return res; } diff --git a/sql/item_create.cc b/sql/item_create.cc index b80327b657a..3bc6fa47e83 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -475,6 +475,12 @@ Item *create_func_is_free_lock(Item* a) return new Item_func_is_free_lock(a); } +Item *create_func_is_used_lock(Item* a) +{ + current_thd->lex.uncacheable(); + return new Item_func_is_used_lock(a); +} + Item *create_func_quote(Item* a) { return new Item_func_quote(a); diff --git a/sql/item_create.h b/sql/item_create.h index 14812c47cdc..0e2295b6d4f 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -100,6 +100,7 @@ Item *create_func_version(void); Item *create_func_weekday(Item* a); Item *create_load_file(Item* a); Item *create_func_is_free_lock(Item* a); +Item *create_func_is_used_lock(Item* a); Item *create_func_quote(Item* a); Item *create_func_geometry_from_text(Item *a); diff --git a/sql/item_func.cc b/sql/item_func.cc index 8cb63182705..5bbb6003e4f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -855,9 +855,13 @@ void Item_func_min_max::fix_length_and_dec() maybe_null=0; cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); if (i==0) - set_charset(args[i]->charset()); - else if (args[i]->charset() == &my_charset_bin) - set_charset(&my_charset_bin); + set_charset(args[i]->charset(), args[i]->coercibility); + else if (set_charset(charset(), coercibility, + args[i]->charset(), args[i]->coercibility)) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),func_name()); + break; + } } } @@ -909,6 +913,7 @@ String *Item_func_min_max::val_str(String *str) } } } + res->set_charset(charset()); return res; } case ROW_RESULT: @@ -1610,8 +1615,10 @@ public: bool locked; pthread_cond_t cond; pthread_t thread; + ulong thread_id; - ULL(const char *key_arg,uint length) :key_length(length),count(1),locked(1) + ULL(const char *key_arg,uint length, ulong id) + :key_length(length),count(1),locked(1), thread_id(id) { key=(char*) my_memdup((byte*) key_arg,length,MYF(0)); pthread_cond_init(&cond,NULL); @@ -1815,7 +1822,7 @@ longlong Item_func_get_lock::val_int() if (!(ull= ((ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(), res->length())))) { - ull=new ULL(res->ptr(),res->length()); + ull=new ULL(res->ptr(),res->length(), thd->thread_id); if (!ull || !ull->initialized()) { delete ull; @@ -2676,6 +2683,28 @@ longlong Item_func_is_free_lock::val_int() return 0; } +longlong Item_func_is_used_lock::val_int() +{ + String *res=args[0]->val_str(&value); + THD *thd=current_thd; + ULL *ull; + + null_value=1; + if (!res || !res->length()) + return 0; + + pthread_mutex_lock(&LOCK_user_locks); + ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(), + res->length()); + pthread_mutex_unlock(&LOCK_user_locks); + if (!ull || !ull->locked) + return 0; + + null_value=0; + return ull->thread_id; +} + + /************************************************************************** Spatial functions diff --git a/sql/item_func.h b/sql/item_func.h index 772b90fd38e..0429e650071 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1162,6 +1162,16 @@ public: void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} }; +class Item_func_is_used_lock :public Item_int_func +{ + String value; +public: + Item_func_is_used_lock(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "is_used_lock"; } + void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} +}; + /* For type casts */ enum Item_cast diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d04ed97393d..76d05cae009 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2041,6 +2041,7 @@ String *Item_func_conv_charset::val_str(String *str) void Item_func_conv_charset::fix_length_and_dec() { + set_charset(conv_charset); max_length = args[0]->max_length*conv_charset->mbmaxlen; set_charset(conv_charset, COER_IMPLICIT); } @@ -2114,25 +2115,6 @@ outp: } -bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables, Item **ref) -{ - char buff[STACK_BUFF_ALLOC]; // Max argument in function - used_tables_cache=0; - const_item_cache=1; - - if (thd && check_stack_overrun(thd,buff)) - return 0; // Fatal error if flag is set! - if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1)) - return 1; - maybe_null=args[0]->maybe_null; - const_item_cache=args[0]->const_item(); - set_charset(conv_charset); - fix_length_and_dec(); - fixed= 1; - return 0; -} - - void Item_func_conv_charset3::fix_length_and_dec() { max_length = args[0]->max_length; @@ -2147,24 +2129,11 @@ String *Item_func_set_collation::val_str(String *str) return str; } -bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, Item **ref) +void Item_func_set_collation::fix_length_and_dec() { CHARSET_INFO *set_collation; - String tmp, *str; const char *colname; - char buff[STACK_BUFF_ALLOC]; // Max argument in function - used_tables_cache=0; - const_item_cache=1; - - if (thd && check_stack_overrun(thd,buff)) - return 0; // Fatal error if flag is set! - if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1)) - return 1; - if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1)) - return 2; - maybe_null=args[0]->maybe_null || args[1]->maybe_null; - - str= args[1]->val_str(&tmp); + String tmp, *str= args[1]->val_str(&tmp); colname= str->c_ptr(); if (!strncmp(colname,"BINARY",6)) set_collation= get_charset_by_csname(args[0]->charset()->csname, @@ -2175,24 +2144,20 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, if (!set_collation) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), str->c_ptr()); - return 1; + return; } if (!my_charset_same(args[0]->charset(),set_collation)) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), set_collation->name,args[0]->charset()->csname); - return 1; + return; } set_charset(set_collation, COER_EXPLICIT); - with_sum_func= with_sum_func || args[0]->with_sum_func; - used_tables_cache=args[0]->used_tables(); - const_item_cache=args[0]->const_item(); - fix_length_and_dec(); - fixed= 1; - return 0; + max_length= args[0]->max_length; } + bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const { /* Assume we don't have rtti */ diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 84653a8315c..07b7eb2d165 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -577,7 +577,6 @@ class Item_func_conv_charset :public Item_str_func public: Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) { conv_charset=cs; } - bool fix_fields(THD *thd,struct st_table_list *tables,Item **ref); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } @@ -588,9 +587,7 @@ class Item_func_set_collation :public Item_str_func public: Item_func_set_collation(Item *a, Item *b) :Item_str_func(a,b) {}; String *val_str(String *); - bool fix_fields(THD *thd,struct st_table_list *tables, Item **ref); - void fix_length_and_dec() - { max_length = args[0]->max_length; } + void fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "set_collation"; } }; diff --git a/sql/lex.h b/sql/lex.h index 9156a2d35bb..3bc5820ee66 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -512,6 +512,7 @@ static SYMBOL sql_functions[] = { { "ISEMPTY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isempty)}, { "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)}, { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)}, + { "IS_USED_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)}, { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0}, { "ISSIMPLE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_issimple)}, { "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, diff --git a/sql/log_event.cc b/sql/log_event.cc index 68b897d30ae..5e3340b4cf7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -328,7 +328,7 @@ int Log_event::exec_event(struct st_relay_log_info* rli) ****************************************************************************/ void Log_event::pack_info(Protocol *protocol) { - protocol->store("",0); + protocol->store("", &my_charset_bin); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 61c5d308b4e..f68de23034a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -62,7 +62,9 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #endif #endif -#define files_charset_info system_charset_info +extern CHARSET_INFO *system_charset_info; +extern CHARSET_INFO *files_charset_info; +extern CHARSET_INFO *national_charset_info; /*************************************************************************** Configuration parameters diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2298ae7b9ea..ddaf8e538c6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -894,7 +894,7 @@ extern "C" void unireg_abort(int exit_code) DBUG_ENTER("unireg_abort"); if (exit_code) sql_print_error("Aborting\n"); - clean_up(1); /* purecov: inspected */ + clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); my_thread_end(); clean_up_mutexes(); @@ -4551,6 +4551,7 @@ static void set_options(void) sizeof(mysql_real_data_home)-1); /* Set default values for some variables */ + global_system_variables.convert_result_charset= TRUE; global_system_variables.table_type= DB_TYPE_MYISAM; global_system_variables.tx_isolation= ISO_REPEATABLE_READ; global_system_variables.select_limit= (ulonglong) HA_POS_ERROR; diff --git a/sql/protocol.cc b/sql/protocol.cc index af8f966a4b6..2d53d545066 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -703,11 +703,13 @@ bool Protocol_simple::store(const char *from, uint length, CHARSET_INFO *cs) field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); field_pos++; #endif - if (cs != this->thd->charset()) + if (!my_charset_same(cs, this->thd->charset()) && + (cs != &my_charset_bin) && + (this->thd->charset() != &my_charset_bin) && + (this->thd->variables.convert_result_charset)) { - String tmp; - tmp.copy(from, length, cs, this->thd->charset()); - return net_store_data(tmp.ptr(), tmp.length()); + convert.copy(from, length, cs, this->thd->charset()); + return net_store_data(convert.ptr(), convert.length()); } else return net_store_data(from, length); @@ -800,16 +802,18 @@ bool Protocol_simple::store(Field *field) field_pos++; #endif char buff[MAX_FIELD_WIDTH]; - String tmp1(buff,sizeof(buff), &my_charset_bin); - field->val_str(&tmp1,&tmp1); - if (field->charset() != this->thd->charset()) + String str(buff,sizeof(buff), &my_charset_bin); + field->val_str(&str,&str); + if (!my_charset_same(field->charset(), this->thd->charset()) && + (field->charset() != &my_charset_bin) && + (this->thd->charset() != &my_charset_bin) && + (this->thd->variables.convert_result_charset)) { - String tmp; - tmp.copy(tmp1.ptr(), tmp1.length(), tmp1.charset(), this->thd->charset()); - return net_store_data(tmp.ptr(), tmp.length()); + convert.copy(str.ptr(), str.length(), str.charset(), this->thd->charset()); + return net_store_data(convert.ptr(), convert.length()); } else - return net_store_data(tmp1.ptr(), tmp1.length()); + return net_store_data(str.ptr(), str.length()); } diff --git a/sql/protocol.h b/sql/protocol.h index 71ad5c1302b..418814a9623 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -30,6 +30,7 @@ class Protocol protected: THD *thd; String *packet; + String convert; uint field_pos; #ifndef DEBUG_OFF enum enum_field_types *field_types; @@ -44,6 +45,7 @@ protected: public: Protocol() {} Protocol(THD *thd) { init(thd); } + virtual ~Protocol() {} void init(THD* thd); bool send_fields(List *list, uint flag); bool send_records_num(List *list, ulonglong records); diff --git a/sql/set_var.cc b/sql/set_var.cc index cb49ad603d9..c4a4819689c 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -109,6 +109,8 @@ sys_var_bool_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", &connect_timeout); +sys_var_thd_bool sys_convert_result_charset("convert_result_charset", + &SV::convert_result_charset); sys_var_enum sys_delay_key_write("delay_key_write", &delay_key_write_options, &delay_key_write_typelib, @@ -337,6 +339,7 @@ sys_var *sys_variables[]= &sys_client_collation, &sys_concurrent_insert, &sys_connect_timeout, + &sys_convert_result_charset, &sys_default_week_format, &sys_delay_key_write, &sys_delayed_insert_limit, @@ -445,6 +448,7 @@ struct show_var_st init_vars[]= { {sys_client_collation.name, (char*) &sys_client_collation, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, + {sys_convert_result_charset.name, (char*) &sys_convert_result_charset, SHOW_SYS}, {"datadir", mysql_real_data_home, SHOW_CHAR}, {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, @@ -1455,7 +1459,6 @@ void set_var_init() (*var)->option_limits= find_option(my_long_options, (*var)->name); hash_insert(&system_variable_hash, (byte*) *var); } - /* Special cases Needed because MySQL can't find the limits for a variable it it has diff --git a/sql/sql_class.h b/sql/sql_class.h index b832bbffac8..8284a2b1ea3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -374,6 +374,7 @@ struct system_variables my_bool log_warnings; my_bool low_priority_updates; my_bool new_mode; + my_bool convert_result_charset; CHARSET_INFO *thd_charset; }; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 54a76319be7..ffa272713de 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -29,6 +29,9 @@ #endif CHARSET_INFO *system_charset_info= &my_charset_utf8; +CHARSET_INFO *files_charset_info= &my_charset_utf8; +CHARSET_INFO *national_charset_info= &my_charset_utf8; + extern gptr sql_alloc(unsigned size); extern void sql_element_free(void *ptr); static uint32 diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 428af27ed3f..af861875691 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1134,10 +1134,10 @@ type: $$=FIELD_TYPE_STRING; } | nchar '(' NUM ')' { Lex->length=$3.str; $$=FIELD_TYPE_STRING; - Lex->charset=&my_charset_utf8; } + Lex->charset=national_charset_info; } | nchar { Lex->length=(char*) "1"; $$=FIELD_TYPE_STRING; - Lex->charset=&my_charset_utf8; } + Lex->charset=national_charset_info; } | BINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=&my_charset_bin; $$=FIELD_TYPE_STRING; } @@ -1145,7 +1145,7 @@ type: $$=FIELD_TYPE_VAR_STRING; } | nvarchar '(' NUM ')' { Lex->length=$3.str; $$=FIELD_TYPE_VAR_STRING; - Lex->charset= &my_charset_utf8; } + Lex->charset=national_charset_info; } | VARBINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=&my_charset_bin; $$=FIELD_TYPE_VAR_STRING; } @@ -2023,11 +2023,6 @@ expr_expr: { $$= new Item_date_add_interval($1,$3,$4,0); } | expr '-' interval_expr interval { $$= new Item_date_add_interval($1,$3,$4,1); } - | expr COLLATE_SYM ident_or_text - { - $$= new Item_func_set_collation($1,new Item_string($3.str,$3.length, - YYTHD->variables.thd_charset)); - } ; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ @@ -2137,6 +2132,11 @@ interval_expr: simple_expr: simple_ident + | simple_expr COLLATE_SYM ident_or_text %prec NEG + { + $$= new Item_func_set_collation($1,new Item_string($3.str,$3.length, + YYTHD->variables.thd_charset)); + } | literal | param_marker | '@' ident_or_text SET_VAR expr @@ -3865,9 +3865,9 @@ text_literal: $$ = new Item_string($1.str,$1.length,cs); } | NCHAR_STRING - { $$= new Item_string($1.str,$1.length,&my_charset_utf8); } + { $$= new Item_string($1.str,$1.length,national_charset_info); } | UNDERSCORE_CHARSET TEXT_STRING - { $$ = new Item_string($2.str,$2.length,Lex->charset,Item::COER_IMPLICIT); } + { $$ = new Item_string($2.str,$2.length,Lex->charset); } | text_literal TEXT_STRING_db { ((Item_string*) $1)->append($2.str,$2.length); } ; @@ -3913,9 +3913,8 @@ literal: { Item *tmp= new Item_varbinary($2.str,$2.length); String *str= tmp ? tmp->val_str((String*) 0) : (String*) 0; - $$ = new Item_string(str ? str->ptr() : "", - str ? str->length() : 0, - Lex->charset,Item::COER_IMPLICIT); + $$ = new Item_string(str ? str->ptr() : "", str ? str->length() : 0, + Lex->charset); } | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } @@ -4340,18 +4339,18 @@ option_value: find_sys_var("tx_isolation"), new Item_int((int32) $4))); } - | charset opt_equal set_expr_or_default + | charset set_expr_or_default { THD *thd= YYTHD; LEX *lex= &thd->lex; - if (!$3) + if (!$2) { CHARSET_INFO *cl= thd->db_charset; - $3= new Item_string(cl->name, strlen(cl->name), &my_charset_latin1); + $2= new Item_string(cl->name, strlen(cl->name), &my_charset_latin1); } lex->var_list.push_back(new set_var(lex->option_type, find_sys_var("client_collation"), - $3)); + $2)); } | NAMES_SYM charset_name_or_default opt_collate { diff --git a/sql/table.cc b/sql/table.cc index b36171cab93..17bb15d3033 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -515,6 +515,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length+= HA_KEY_NULL_LENGTH; } if (field->type() == FIELD_TYPE_BLOB || + field->type() == FIELD_TYPE_GEOMETRY || field->real_type() == FIELD_TYPE_VAR_STRING) { if (field->type() == FIELD_TYPE_BLOB) @@ -531,7 +532,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (i == 0) field->key_start|= ((key_map) 1 << key); if (field->key_length() == key_part->length && - field->type() != FIELD_TYPE_BLOB) + !(field->flags & BLOB_FLAG)) { if ((index_flags & HA_KEY_READ_ONLY) && (field->key_type() != HA_KEYTYPE_TEXT || @@ -560,7 +561,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (field->key_length() != key_part->length) { key_part->key_part_flag|= HA_PART_KEY; - if (field->type() != FIELD_TYPE_BLOB) + if (!(field->flags & BLOB_FLAG)) { // Create a new field field=key_part->field=field->new_field(&outparam->mem_root, outparam); diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 897e2846659..702a34fde84 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1585,14 +1585,15 @@ static uchar to_upper_utf8[] = { }; -static int my_utf8_uni (CHARSET_INFO *cs __attribute__((unused)) , - my_wc_t * pwc, const uchar *s, const uchar *e) +static int my_utf8_uni(CHARSET_INFO *cs __attribute__((unused)), + my_wc_t * pwc, const uchar *s, const uchar *e) { - unsigned char c = s[0]; + unsigned char c; if (s >= e) return MY_CS_TOOFEW(0); + c= s[0]; if (c < 0x80) { *pwc = c; @@ -1624,10 +1625,8 @@ static int my_utf8_uni (CHARSET_INFO *cs __attribute__((unused)) , (my_wc_t) (s[2] ^ 0x80); return 3; - -#ifdef UNICODE_32BIT - } +#ifdef UNICODE_32BIT else if (c < 0xf8 && sizeof(my_wc_t)*8 >= 32) { if (s+4 > e) /* We need 4 characters */ @@ -1685,9 +1684,9 @@ static int my_utf8_uni (CHARSET_INFO *cs __attribute__((unused)) , | ((my_wc_t) (s[4] ^ 0x80) << 6) | (my_wc_t) (s[5] ^ 0x80); return 6; + } #endif - } else - return MY_CS_ILSEQ; + return MY_CS_ILSEQ; } static int my_uni_utf8 (CHARSET_INFO *cs __attribute__((unused)) , diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 4aadd98bd1b..ec88972c821 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -34,8 +34,7 @@ pkgdata_DATA = my-small.cnf \ my-large.cnf \ my-huge.cnf \ mysql-log-rotate \ - mysql-@VERSION@.spec \ - binary-configure + mysql-@VERSION@.spec pkgdata_SCRIPTS = mysql.server @@ -48,7 +47,6 @@ CLEANFILES = my-small.cnf \ mysql-log-rotate \ mysql.server \ binary-configure - mysql-@VERSION@.spec: mysql.spec rm -f $@ @@ -98,5 +96,7 @@ SUFFIXES = .sh $< > $@-t @MV@ $@-t $@ +all: binary-configure + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/support-files/binary-configure.sh b/support-files/binary-configure.sh index 107f468bffc..884a8363e22 100644 --- a/support-files/binary-configure.sh +++ b/support-files/binary-configure.sh @@ -14,11 +14,11 @@ echo "and start the MySQL server for you. If you run into any trouble, please" echo "consult the MySQL manual, that you can find in the Docs directory." echo "" -./scripts/mysql_install_db +./scripts/mysql_install_db --no-defaults if [ $? = 0 ] then echo "Starting the mysqld server. You can test that it is up and running" echo "with the command:" echo "./bin/mysqladmin version" - ./bin/mysqld_safe & + ./bin/mysqld_safe --no-defaults & fi