diff --git a/mysql-test/include/have_archive.inc b/mysql-test/include/have_archive.inc index 262f66076a8..75460316322 100644 --- a/mysql-test/include/have_archive.inc +++ b/mysql-test/include/have_archive.inc @@ -1,4 +1,4 @@ --require r/have_archive.require --disable_query_log -show variables like "have_archive"; +show variables like 'have_archive'; --enable_query_log diff --git a/mysql-test/include/have_bdb.inc b/mysql-test/include/have_bdb.inc index 3f7377e7515..c2f29e0d286 100644 --- a/mysql-test/include/have_bdb.inc +++ b/mysql-test/include/have_bdb.inc @@ -1,4 +1,4 @@ -- require r/have_bdb.require disable_query_log; -show variables like "have_bdb"; +show variables like 'have_bdb'; enable_query_log; diff --git a/mysql-test/include/have_big5.inc b/mysql-test/include/have_big5.inc index 790e8085e1a..dad4a0a8eeb 100644 --- a/mysql-test/include/have_big5.inc +++ b/mysql-test/include/have_big5.inc @@ -1,4 +1,4 @@ -- require r/have_big5.require disable_query_log; -show collation like "big5_chinese_ci"; +show collation like 'big5_chinese_ci'; enable_query_log; diff --git a/mysql-test/include/have_blackhole.inc b/mysql-test/include/have_blackhole.inc index c2b6ea18830..d13c9fda3f5 100644 --- a/mysql-test/include/have_blackhole.inc +++ b/mysql-test/include/have_blackhole.inc @@ -1,4 +1,4 @@ -- require r/have_blackhole.require disable_query_log; -show variables like "have_blackhole_engine"; +show variables like 'have_blackhole_engine'; enable_query_log; diff --git a/mysql-test/include/have_case_sensitive_file_system.inc b/mysql-test/include/have_case_sensitive_file_system.inc index 730af975497..7bb1bef93fd 100644 --- a/mysql-test/include/have_case_sensitive_file_system.inc +++ b/mysql-test/include/have_case_sensitive_file_system.inc @@ -1,4 +1,4 @@ --require r/case_sensitive_file_system.require --disable_query_log -show variables like "lower_case_file_system"; +show variables like 'lower_case_file_system'; --enable_query_log diff --git a/mysql-test/include/have_compress.inc b/mysql-test/include/have_compress.inc index c042cd7452a..150c7f3448d 100644 --- a/mysql-test/include/have_compress.inc +++ b/mysql-test/include/have_compress.inc @@ -1,4 +1,4 @@ -- require r/have_compress.require disable_query_log; -show variables like "have_compress"; +show variables like 'have_compress'; enable_query_log; diff --git a/mysql-test/include/have_cp1250_ch.inc b/mysql-test/include/have_cp1250_ch.inc index eec5d69fbd6..426fa658597 100644 --- a/mysql-test/include/have_cp1250_ch.inc +++ b/mysql-test/include/have_cp1250_ch.inc @@ -1,4 +1,4 @@ -- require r/have_cp1250_ch.require disable_query_log; -show collation like "cp1250_czech_cs"; +show collation like 'cp1250_czech_cs'; enable_query_log; diff --git a/mysql-test/include/have_cp932.inc b/mysql-test/include/have_cp932.inc index b500dac0bbe..ecad979c02a 100644 --- a/mysql-test/include/have_cp932.inc +++ b/mysql-test/include/have_cp932.inc @@ -1,4 +1,4 @@ -- require r/have_cp932.require disable_query_log; -show collation like "cp932_japanese_ci"; +show collation like 'cp932_japanese_ci'; enable_query_log; diff --git a/mysql-test/include/have_crypt.inc b/mysql-test/include/have_crypt.inc index fe1f974bffd..cbf0a7ac876 100644 --- a/mysql-test/include/have_crypt.inc +++ b/mysql-test/include/have_crypt.inc @@ -1,4 +1,4 @@ -- require r/have_crypt.require disable_query_log; -show variables like "have_crypt"; +show variables like 'have_crypt'; enable_query_log; diff --git a/mysql-test/include/have_csv.inc b/mysql-test/include/have_csv.inc index d28199831b8..12e69962486 100644 --- a/mysql-test/include/have_csv.inc +++ b/mysql-test/include/have_csv.inc @@ -1,4 +1,4 @@ -- require r/have_csv.require disable_query_log; -show variables like "have_csv"; +show variables like 'have_csv'; enable_query_log; diff --git a/mysql-test/include/have_eucjpms.inc b/mysql-test/include/have_eucjpms.inc index a5e1a5ac547..6d96eefcc31 100644 --- a/mysql-test/include/have_eucjpms.inc +++ b/mysql-test/include/have_eucjpms.inc @@ -1,4 +1,4 @@ -- require r/have_eucjpms.require disable_query_log; -show collation like "eucjpms_japanese_ci"; +show collation like 'eucjpms_japanese_ci'; enable_query_log; diff --git a/mysql-test/include/have_euckr.inc b/mysql-test/include/have_euckr.inc index af794aafc04..4b4e870cf47 100644 --- a/mysql-test/include/have_euckr.inc +++ b/mysql-test/include/have_euckr.inc @@ -1,4 +1,4 @@ -- require r/have_euckr.require disable_query_log; -show collation like "euckr_korean_ci"; +show collation like 'euckr_korean_ci'; enable_query_log; diff --git a/mysql-test/include/have_exampledb.inc b/mysql-test/include/have_exampledb.inc index 7ddd15c48b3..b8f9a24463e 100644 --- a/mysql-test/include/have_exampledb.inc +++ b/mysql-test/include/have_exampledb.inc @@ -1,4 +1,4 @@ -- require r/have_exampledb.require disable_query_log; -show variables like "have_example_engine"; +show variables like 'have_example_engine'; enable_query_log; diff --git a/mysql-test/include/have_federated_db.inc b/mysql-test/include/have_federated_db.inc index e4cf1366fda..4745534780d 100644 --- a/mysql-test/include/have_federated_db.inc +++ b/mysql-test/include/have_federated_db.inc @@ -1,4 +1,4 @@ -- require r/have_federated_db.require disable_query_log; -show variables like "have_federated_engine"; +show variables like 'have_federated_engine'; enable_query_log; diff --git a/mysql-test/include/have_gb2312.inc b/mysql-test/include/have_gb2312.inc index 4328bc67639..27591c01b6c 100644 --- a/mysql-test/include/have_gb2312.inc +++ b/mysql-test/include/have_gb2312.inc @@ -1,4 +1,4 @@ -- require r/have_gb2312.require disable_query_log; -show collation like "gb2312_chinese_ci"; +show collation like 'gb2312_chinese_ci'; enable_query_log; diff --git a/mysql-test/include/have_gbk.inc b/mysql-test/include/have_gbk.inc index 55805da0495..72252d6b00d 100644 --- a/mysql-test/include/have_gbk.inc +++ b/mysql-test/include/have_gbk.inc @@ -1,4 +1,4 @@ -- require r/have_gbk.require disable_query_log; -show collation like "gbk_chinese_ci"; +show collation like 'gbk_chinese_ci'; enable_query_log; diff --git a/mysql-test/include/have_geometry.inc b/mysql-test/include/have_geometry.inc index f0ec22af172..f1836469017 100644 --- a/mysql-test/include/have_geometry.inc +++ b/mysql-test/include/have_geometry.inc @@ -1,4 +1,4 @@ --require r/have_geometry.require --disable_query_log -show variables like "have_geometry"; +show variables like 'have_geometry'; --enable_query_log diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc index 4f83d378cbc..4142b84813b 100644 --- a/mysql-test/include/have_innodb.inc +++ b/mysql-test/include/have_innodb.inc @@ -1,4 +1,4 @@ -- require r/have_innodb.require disable_query_log; -show variables like "have_innodb"; +show variables like 'have_innodb'; enable_query_log; diff --git a/mysql-test/include/have_latin2_ch.inc b/mysql-test/include/have_latin2_ch.inc index 9d3ee6b341c..215715a6aaf 100644 --- a/mysql-test/include/have_latin2_ch.inc +++ b/mysql-test/include/have_latin2_ch.inc @@ -1,4 +1,4 @@ -- require r/have_latin2_ch.require disable_query_log; -show collation like "latin2_czech_cs"; +show collation like 'latin2_czech_cs'; enable_query_log; diff --git a/mysql-test/include/have_log_bin.inc b/mysql-test/include/have_log_bin.inc index 11530dc953e..5bcdb30b3e0 100644 --- a/mysql-test/include/have_log_bin.inc +++ b/mysql-test/include/have_log_bin.inc @@ -1,4 +1,4 @@ -- require r/have_log_bin.require disable_query_log; -show variables like "log_bin"; +show variables like 'log_bin'; enable_query_log; diff --git a/mysql-test/include/have_lowercase0.inc b/mysql-test/include/have_lowercase0.inc index 8d3ae02f61e..6192acb7b01 100644 --- a/mysql-test/include/have_lowercase0.inc +++ b/mysql-test/include/have_lowercase0.inc @@ -1,4 +1,4 @@ --require r/lowercase0.require --disable_query_log -show variables like "lower_case_%"; +show variables like 'lower_case_%'; --enable_query_log diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc index 45a551274f7..7f922d85ff2 100644 --- a/mysql-test/include/have_multi_ndb.inc +++ b/mysql-test/include/have_multi_ndb.inc @@ -10,7 +10,7 @@ drop table if exists t1, t2; --enable_warnings flush tables; --require r/have_ndb.require -show variables like "have_ndbcluster"; +show variables like 'have_ndbcluster'; enable_query_log; # Check that server2 has NDB support @@ -21,7 +21,7 @@ drop table if exists t1, t2; --enable_warnings flush tables; --require r/have_ndb.require -show variables like "have_ndbcluster"; +show variables like 'have_ndbcluster'; enable_query_log; # Set the default connection to 'server1' diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 721d79392b7..691adc12231 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -1,7 +1,7 @@ # Check that server is compiled and started with support for NDB -- require r/have_ndb.require disable_query_log; -show variables like "have_ndbcluster"; +show variables like 'have_ndbcluster'; enable_query_log; # Check that NDB is installed and known to be working diff --git a/mysql-test/include/have_query_cache.inc b/mysql-test/include/have_query_cache.inc index 39549157849..647f8598ae6 100644 --- a/mysql-test/include/have_query_cache.inc +++ b/mysql-test/include/have_query_cache.inc @@ -3,5 +3,5 @@ # of query cache hits -- disable_ps_protocol disable_query_log; -show variables like "have_query_cache"; +show variables like 'have_query_cache'; enable_query_log; diff --git a/mysql-test/include/have_sjis.inc b/mysql-test/include/have_sjis.inc index 0d580a3a232..ac6531ca868 100644 --- a/mysql-test/include/have_sjis.inc +++ b/mysql-test/include/have_sjis.inc @@ -1,4 +1,4 @@ -- require r/have_sjis.require disable_query_log; -show collation like "sjis_japanese_ci"; +show collation like 'sjis_japanese_ci'; enable_query_log; diff --git a/mysql-test/include/have_ssl.inc b/mysql-test/include/have_ssl.inc index fab57d630e5..6f2d5587a75 100644 --- a/mysql-test/include/have_ssl.inc +++ b/mysql-test/include/have_ssl.inc @@ -1,4 +1,4 @@ -- require r/have_ssl.require disable_query_log; -show variables like "have_ssl"; +show variables like 'have_ssl'; enable_query_log; diff --git a/mysql-test/include/have_tis620.inc b/mysql-test/include/have_tis620.inc index c1e775681b0..ad5ba9dea69 100644 --- a/mysql-test/include/have_tis620.inc +++ b/mysql-test/include/have_tis620.inc @@ -1,4 +1,4 @@ -- require r/have_tis620.require disable_query_log; -show collation like "tis620_thai_ci"; +show collation like 'tis620_thai_ci'; enable_query_log; diff --git a/mysql-test/include/have_ucs2.inc b/mysql-test/include/have_ucs2.inc index 92ec9b5fb44..324ed52dd02 100644 --- a/mysql-test/include/have_ucs2.inc +++ b/mysql-test/include/have_ucs2.inc @@ -1,4 +1,4 @@ -- require r/have_ucs2.require disable_query_log; -show collation like "ucs2_general_ci"; +show collation like 'ucs2_general_ci'; enable_query_log; diff --git a/mysql-test/include/have_udf.inc b/mysql-test/include/have_udf.inc index 42b9942f74d..154dccf2270 100644 --- a/mysql-test/include/have_udf.inc +++ b/mysql-test/include/have_udf.inc @@ -4,7 +4,7 @@ # --require r/have_udf.require disable_query_log; -show variables like "have_dynamic_loading"; +show variables like 'have_dynamic_loading'; enable_query_log; # diff --git a/mysql-test/include/have_ujis.inc b/mysql-test/include/have_ujis.inc index ecceb7a8408..e4b2f50cf93 100644 --- a/mysql-test/include/have_ujis.inc +++ b/mysql-test/include/have_ujis.inc @@ -1,4 +1,4 @@ -- require r/have_ujis.require disable_query_log; -show collation like "ujis_japanese_ci"; +show collation like 'ujis_japanese_ci'; enable_query_log; diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result index 1040c3fc8e9..b9d0028dc7c 100644 --- a/mysql-test/r/comments.result +++ b/mysql-test/r/comments.result @@ -35,7 +35,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;"; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*"; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';*' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*' at line 1 prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';"; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar'' at line 1 prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*"; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index d50dda55bfb..ce177b511b9 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -305,4 +305,18 @@ drop table t1; SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs; NAME_CONST('var', 'value') COLLATE latin1_general_cs value +select @@session.time_zone into @save_tz; +set @@session.time_zone='UTC'; +select uuid() into @my_uuid; +select mid(@my_uuid,15,1); +mid(@my_uuid,15,1) +1 +select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day; +select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate; +select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date; +select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic; +select @my_uuid_date - @my_uuid_synthetic; +@my_uuid_date - @my_uuid_synthetic +0 +set @@session.time_zone=@save_tz; End of 5.0 tests diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result new file mode 100644 index 00000000000..18391bd2a45 --- /dev/null +++ b/mysql-test/r/parser.result @@ -0,0 +1,68 @@ +DROP PROCEDURE IF EXISTS p26030; +select "non terminated"$$ +non terminated +non terminated +select "terminated";$$ +terminated +terminated +select "non terminated, space" $$ +non terminated, space +non terminated, space +select "terminated, space"; $$ +terminated, space +terminated, space +select "non terminated, comment" /* comment */$$ +non terminated, comment +non terminated, comment +select "terminated, comment"; /* comment */$$ +terminated, comment +terminated, comment +select "stmt 1";select "stmt 2 non terminated"$$ +stmt 1 +stmt 1 +stmt 2 non terminated +stmt 2 non terminated +select "stmt 1";select "stmt 2 terminated";$$ +stmt 1 +stmt 1 +stmt 2 terminated +stmt 2 terminated +select "stmt 1";select "stmt 2 non terminated, space" $$ +stmt 1 +stmt 1 +stmt 2 non terminated, space +stmt 2 non terminated, space +select "stmt 1";select "stmt 2 terminated, space"; $$ +stmt 1 +stmt 1 +stmt 2 terminated, space +stmt 2 terminated, space +select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$ +stmt 1 +stmt 1 +stmt 2 non terminated, comment +stmt 2 non terminated, comment +select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$ +stmt 1 +stmt 1 +stmt 2 terminated, comment +stmt 2 terminated, comment +select "stmt 1"; select "space, stmt 2"$$ +stmt 1 +stmt 1 +space, stmt 2 +space, stmt 2 +select "stmt 1";/* comment */select "comment, stmt 2"$$ +stmt 1 +stmt 1 +comment, stmt 2 +comment, stmt 2 +DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030() +$$ +1 +1 +DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030() +$$ +1 +1 +DROP PROCEDURE p26030; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 9aef58d5702..09deaf2f322 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -85,9 +85,9 @@ NULL NULL NULL prepare stmt6 from 'select 1; select2'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; select2' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select2' at line 1 prepare stmt6 from 'insert into t1 values (5,"five"); select2'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; select2' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select2' at line 1 explain prepare stmt6 from 'insert into t1 values (5,"five"); select2'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from 'insert into t1 values (5,"five"); select2'' at line 1 create table t2 diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index a41885a257d..f584c22f98a 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -78,3 +78,34 @@ alter table t1 modify a varchar(255); select length(a) from t1; length(a) 6 +select 0b01000001; +0b01000001 +A +select 0x41; +0x41 +A +select b'01000001'; +b'01000001' +A +select x'41', 0+x'41'; +x'41' 0+x'41' +A 65 +select N'abc', length(N'abc'); +abc length(N'abc') +abc 3 +select N'', length(N''); + length(N'') + 0 +select '', length(''); + length('') + 0 +select b'', 0+b''; +b'' 0+b'' + 0 +select x'', 0+x''; +x'' 0+x'' + 0 +select 0x; +ERROR 42S22: Unknown column '0x' in 'field list' +select 0b; +ERROR 42S22: Unknown column '0b' in 'field list' diff --git a/mysql-test/suite/funcs_1/t/is_columns_myisam_embedded.test b/mysql-test/suite/funcs_1/t/is_columns_myisam_embedded.test index 0d5f1a72cdb..3d0cca24474 100644 --- a/mysql-test/suite/funcs_1/t/is_columns_myisam_embedded.test +++ b/mysql-test/suite/funcs_1/t/is_columns_myisam_embedded.test @@ -10,11 +10,6 @@ # 2008-06-06 mleich Create this this variant for the embedded server. # -let $value= query_get_value(SHOW VARIABLES LIKE 'version_compile_os',Value,1); -if (`SELECT '$value' LIKE 'apple-darwin%'`) -{ - skip Bug#37380 Test funcs_1.is_columns_myisam_embedded fails on OS X; -} if (`SELECT VERSION() NOT LIKE '%embedded%'`) { --skip Test requires: embedded server diff --git a/mysql-test/suite/funcs_2/charset/charset_master.test b/mysql-test/suite/funcs_2/charset/charset_master.test index a241e62f0f4..09e24e2c246 100644 --- a/mysql-test/suite/funcs_2/charset/charset_master.test +++ b/mysql-test/suite/funcs_2/charset/charset_master.test @@ -1,14 +1,96 @@ ################################################################################# -# Author: Serge Kozlov # -# Date: 09/21/2005 # -# Purpose: used by ../t/*_charset.test # -# Require: set $engine_type= [NDB,MyISAM,InnoDB,etc] before calling # +# Author: Serge Kozlov # +# Date: 2005-09-21 # +# Purpose: used by ../t/*_charset.test # +# Require: set $engine_type= [NDB,MyISAM,InnoDB,etc] before calling # +# # +# Last modification: Matthias Leich # +# Date: 2008-07-02 # +# Purpose: Fix Bug#37160 funcs_2: The tests do not check if optional character # +# sets exist. # +# Add checking of prerequisites + minor cleanup # ################################################################################# # # # +# Check that all character sets needed are available +# Note(mleich): +# It is intentional that the common solution with +# "--source include/have_<character set>.inc" +# is not applied. +# - We currently do not have such a prerequisite test for every character set +# /collation needed. +# - There is also no real value in mentioning the first missing character set +# /collation within the "skip message" because it is most probably only +# one of many. +# +# Hint: 5 character_set_names per source line if possible +if (`SELECT COUNT(*) <> 36 FROM information_schema.character_sets + WHERE CHARACTER_SET_NAME IN ( + 'armscii8', 'ascii' , 'big5' , 'binary' , 'cp1250', + 'cp1251' , 'cp1256' , 'cp1257' , 'cp850' , 'cp852' , + 'cp866' , 'cp932' , 'dec8' , 'eucjpms', 'euckr' , + 'gb2312' , 'gbk' , 'geostd8', 'greek' , 'hebrew', + 'hp8' , 'keybcs2', 'koi8r' , 'koi8u' , 'latin1', + 'latin2' , 'latin5' , 'latin7' , 'macce' , 'macroman', + 'sjis' , 'swe7' , 'tis620' , 'ucs2' , 'ujis', + 'utf8' + )`) +{ + --skip Not all character sets required for this test are present +} +# Check that all collations needed are available +# Hint: 4 collation_names per source line if possible +if (`SELECT COUNT(*) <> 123 FROM information_schema.collations +WHERE collation_name IN ( +'armscii8_bin', 'armscii8_general_ci', 'ascii_bin', 'ascii_general_ci', +'big5_bin', 'big5_chinese_ci', 'cp1250_bin', 'cp1250_croatian_ci', +'cp1250_czech_cs', 'cp1250_general_ci', 'cp1251_bin', 'cp1251_bulgarian_ci', +'cp1251_general_ci', 'cp1251_general_cs', 'cp1251_ukrainian_ci', 'cp1256_bin', +'cp1256_general_ci', 'cp1257_bin', 'cp1257_general_ci', 'cp1257_lithuanian_ci', +'cp850_bin', 'cp850_general_ci', 'cp852_bin', 'cp852_general_ci', +'cp866_bin', 'cp866_general_ci', 'cp932_bin', 'cp932_japanese_ci', +'dec8_bin', 'dec8_swedish_ci', 'eucjpms_bin', 'eucjpms_japanese_ci', +'euckr_bin', 'euckr_korean_ci', 'gb2312_bin', 'gb2312_chinese_ci', +'gbk_bin', 'gbk_chinese_ci', 'geostd8_bin', 'geostd8_general_ci', +'greek_bin', 'greek_general_ci', 'hebrew_bin', 'hebrew_general_ci', +'hp8_bin', 'hp8_english_ci', 'keybcs2_bin', 'keybcs2_general_ci', +'koi8r_bin', 'koi8r_general_ci', 'koi8u_bin', 'koi8u_general_ci', +'latin1_bin', 'latin1_danish_ci', 'latin1_general_ci', 'latin1_general_cs', +'latin1_german1_ci', 'latin1_german2_ci', 'latin1_spanish_ci', 'latin1_swedish_ci', +'latin2_bin', 'latin2_croatian_ci', 'latin2_czech_cs', 'latin2_general_ci', +'latin2_hungarian_ci', 'latin5_bin', 'latin5_turkish_ci', 'latin7_bin', +'latin7_estonian_cs', 'latin7_general_ci', 'latin7_general_cs', 'macce_bin', +'macce_general_ci', 'macroman_bin', 'macroman_general_ci', 'sjis_bin', +'sjis_japanese_ci', 'swe7_bin', 'swe7_swedish_ci', 'tis620_bin', +'tis620_thai_ci', 'ucs2_bin', 'ucs2_czech_ci', 'ucs2_danish_ci', +'ucs2_estonian_ci', 'ucs2_general_ci', 'ucs2_hungarian_ci', 'ucs2_icelandic_ci', +'ucs2_latvian_ci', 'ucs2_lithuanian_ci', 'ucs2_persian_ci', 'ucs2_polish_ci', +'ucs2_roman_ci', 'ucs2_romanian_ci', 'ucs2_slovak_ci', 'ucs2_slovenian_ci', +'ucs2_spanish2_ci', 'ucs2_spanish_ci', 'ucs2_swedish_ci', 'ucs2_turkish_ci', +'ucs2_unicode_ci', 'ujis_bin', 'ujis_japanese_ci', 'utf8_bin', +'utf8_czech_ci', 'utf8_danish_ci', 'utf8_estonian_ci', 'utf8_general_ci', +'utf8_hungarian_ci', 'utf8_icelandic_ci', 'utf8_latvian_ci', 'utf8_lithuanian_ci', +'utf8_persian_ci', 'utf8_polish_ci', 'utf8_roman_ci', 'utf8_romanian_ci', +'utf8_slovak_ci', 'utf8_slovenian_ci', 'utf8_spanish2_ci', 'utf8_spanish_ci', +'utf8_swedish_ci', 'utf8_turkish_ci', 'utf8_unicode_ci' +)`) +{ + --skip Not all collations required for this test are present +} + +################################ +let $check_std_csets= 1; +let $check_ucs2_csets= 1; +let $check_utf8_csets= 1; + +# +# Check all charsets/collation combinations +# + +################################ let $check_std_csets= 1; let $check_ucs2_csets= 1; let $check_utf8_csets= 1; diff --git a/mysql-test/suite/funcs_2/t/innodb_charset.test b/mysql-test/suite/funcs_2/t/innodb_charset.test index 5d4a72cfa2e..b77bacfc01c 100644 --- a/mysql-test/suite/funcs_2/t/innodb_charset.test +++ b/mysql-test/suite/funcs_2/t/innodb_charset.test @@ -1,8 +1,10 @@ -################################################################################# -# Author: Serge Kozlov # -# Date: 09/21/2005 # -# Purpose: Testing the charsets for InnoDB engine # -################################################################################# +################################################################################ +# Author: Serge Kozlov # +# Date: 2005-09-21 # +# Purpose: Testing the charsets for InnoDB engine # +# # +# Checking of other prerequisites is in charset_master.test # +################################################################################ --source include/have_innodb.inc diff --git a/mysql-test/suite/funcs_2/t/memory_charset.test b/mysql-test/suite/funcs_2/t/memory_charset.test index ce9b80462f1..cc878652bfa 100644 --- a/mysql-test/suite/funcs_2/t/memory_charset.test +++ b/mysql-test/suite/funcs_2/t/memory_charset.test @@ -1,8 +1,10 @@ -################################################################################# -# Author: Serge Kozlov # -# Date: 09/21/2005 # -# Purpose: Testing the charsets for Memory engine # -################################################################################# +################################################################################ +# Author: Serge Kozlov # +# Date: 2005-09-21 # +# Purpose: Testing the charsets for Memory engine # +# # +# Checking of other prerequisites is in charset_master.test # +################################################################################ let $engine_type= Memory; --source suite/funcs_2/charset/charset_master.test diff --git a/mysql-test/suite/funcs_2/t/myisam_charset.test b/mysql-test/suite/funcs_2/t/myisam_charset.test index b3f862c89de..e9a62e1060b 100644 --- a/mysql-test/suite/funcs_2/t/myisam_charset.test +++ b/mysql-test/suite/funcs_2/t/myisam_charset.test @@ -1,8 +1,10 @@ -################################################################################# -# Author: Serge Kozlov # -# Date: 09/21/2005 # -# Purpose: Testing the charsets for MyISAM engine # -################################################################################# +################################################################################ +# Author: Serge Kozlov # +# Date: 2005-09-21 # +# Purpose: Testing the charsets for MyISAM engine # +# # +# Checking of other prerequisites is in charset_master.test # +################################################################################ let $engine_type= MyISAM; --source suite/funcs_2/charset/charset_master.test diff --git a/mysql-test/suite/funcs_2/t/ndb_charset.test b/mysql-test/suite/funcs_2/t/ndb_charset.test index 72ebbad43d7..68665cc1ae5 100644 --- a/mysql-test/suite/funcs_2/t/ndb_charset.test +++ b/mysql-test/suite/funcs_2/t/ndb_charset.test @@ -1,8 +1,10 @@ -################################################################################# -# Author: Serge Kozlov # -# Date: 09/21/2005 # -# Purpose: Testing the charsets for NDB engine # -################################################################################# +################################################################################ +# Author: Serge Kozlov # +# Date: 09/21/2005 # +# Purpose: Testing the charsets for NDB engine # +# # +# Checking of other prerequisites is in charset_master.test # +################################################################################ --source include/have_ndb.inc --source include/not_embedded.inc diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 36c18979154..93fe94ec94f 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -417,5 +417,24 @@ drop table t1; # SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs; +# +# Bug #35848: UUID() returns UUIDs with the wrong time +# +select @@session.time_zone into @save_tz; + +# make sure all times are UTC so the DayNr won't differ +set @@session.time_zone='UTC'; +select uuid() into @my_uuid; +# if version nibble isn't 1, the following calculations will be rubbish +select mid(@my_uuid,15,1); +select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day; +select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate; +select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date; +select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic; +# these should be identical; date part of UUID should be current date +select @my_uuid_date - @my_uuid_synthetic; + +set @@session.time_zone=@save_tz; + --echo End of 5.0 tests diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test new file mode 100644 index 00000000000..02fe98dc7b2 --- /dev/null +++ b/mysql-test/t/parser.test @@ -0,0 +1,59 @@ +# +# This file contains tests covering the parser +# + +#============================================================================= +# LEXICAL PARSER (lex) +#============================================================================= + +# +# Maintainer: these tests are for the lexical parser, so every character, +# even whitespace or comments, is significant here. +# + +# +# Bug#26030 (Parsing fails for stored routine w/multi-statement execution +# enabled) +# + +--disable_warnings +DROP PROCEDURE IF EXISTS p26030; +--enable_warnings + +delimiter $$; + +select "non terminated"$$ +select "terminated";$$ +select "non terminated, space" $$ +select "terminated, space"; $$ +select "non terminated, comment" /* comment */$$ +select "terminated, comment"; /* comment */$$ + +# Multi queries can not be used in --ps-protocol test mode +--disable_ps_protocol + +select "stmt 1";select "stmt 2 non terminated"$$ +select "stmt 1";select "stmt 2 terminated";$$ +select "stmt 1";select "stmt 2 non terminated, space" $$ +select "stmt 1";select "stmt 2 terminated, space"; $$ +select "stmt 1";select "stmt 2 non terminated, comment" /* comment */$$ +select "stmt 1";select "stmt 2 terminated, comment"; /* comment */$$ + +select "stmt 1"; select "space, stmt 2"$$ +select "stmt 1";/* comment */select "comment, stmt 2"$$ + +DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030() +$$ + +DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030() +$$ + +--enable_ps_protocol + +delimiter ;$$ +DROP PROCEDURE p26030; + +#============================================================================r +# SYNTACTIC PARSER (bison) +#============================================================================= + diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index 2f0c1c83e84..427c1a6b84a 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -84,3 +84,31 @@ select length(a) from t1; alter table t1 modify a varchar(255); select length(a) from t1; +# +# Bug#35658 (An empty binary value leads to mysqld crash) +# + +select 0b01000001; + +select 0x41; + +select b'01000001'; + +select x'41', 0+x'41'; + +select N'abc', length(N'abc'); + +select N'', length(N''); + +select '', length(''); + +select b'', 0+b''; + +select x'', 0+x''; + +--error ER_BAD_FIELD_ERROR +select 0x; + +--error ER_BAD_FIELD_ERROR +select 0b; + diff --git a/mysys/default.c b/mysys/default.c index e58903d6d64..bf32261129b 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -48,13 +48,12 @@ char *my_defaults_extra_file=0; /* Which directories are searched for options (and in which order) */ #define MAX_DEFAULT_DIRS 6 -const char *default_directories[MAX_DEFAULT_DIRS + 1]; +#define DEFAULT_DIRS_SIZE (MAX_DEFAULT_DIRS + 1) /* Terminate with NULL */ +static const char **default_directories = NULL; #ifdef __WIN__ static const char *f_extensions[]= { ".ini", ".cnf", 0 }; #define NEWLINE "\r\n" -static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN], - config_dir[FN_REFLEN]; #else static const char *f_extensions[]= { ".cnf", 0 }; #define NEWLINE "\n" @@ -85,19 +84,34 @@ static int search_default_file_with_ext(Process_option_func func, const char *config_file, int recursion_level); - /** Create the list of default directories. + @param alloc MEM_ROOT where the list of directories is stored + @details + The directories searched, in order, are: + - Windows: GetSystemWindowsDirectory() + - Windows: GetWindowsDirectory() + - Windows: C:/ + - Windows: Directory above where the executable is located + - Netware: sys:/etc/ + - Unix & OS/2: /etc/ + - Unix: --sysconfdir=<path> (compile-time option) + - OS/2: getenv(ETC) + - ALL: getenv(DEFAULT_HOME_ENV) + - ALL: --defaults-extra-file=<path> (run-time option) + - Unix: ~/ + On all systems, if a directory is already in the list, it will be moved to the end of the list. This avoids reading defaults files multiple times, while ensuring the correct precedence. - @return void + @retval NULL Failure (out of memory, probably) + @retval other Pointer to NULL-terminated array of default directories */ -static void (*init_default_directories)(); +static const char **init_default_directories(MEM_ROOT *alloc); static char *remove_end_comment(char *ptr); @@ -386,8 +400,9 @@ int load_defaults(const char *conf_file, const char **groups, struct handle_option_ctx ctx; DBUG_ENTER("load_defaults"); - init_default_directories(); init_alloc_root(&alloc,512,0); + if ((default_directories= init_default_directories(&alloc)) == NULL) + goto err; /* Check if the user doesn't want any default option processing --no-defaults is always the first option @@ -864,34 +879,49 @@ void my_print_default_files(const char *conf_file) my_bool have_ext= fn_ext(conf_file)[0] != 0; const char **exts_to_use= have_ext ? empty_list : f_extensions; char name[FN_REFLEN], **ext; - const char **dirs; - init_default_directories(); puts("\nDefault options are read from the following files in the given order:"); if (dirname_length(conf_file)) fputs(conf_file,stdout); else { - for (dirs=default_directories ; *dirs; dirs++) + /* + If default_directories is already initialized, use it. Otherwise, + use a private MEM_ROOT. + */ + const char **dirs = default_directories; + MEM_ROOT alloc; + init_alloc_root(&alloc,512,0); + + if (!dirs && (dirs= init_default_directories(&alloc)) == NULL) { - for (ext= (char**) exts_to_use; *ext; ext++) + fputs("Internal error initializing default directories list", stdout); + } + else + { + for ( ; *dirs; dirs++) { - const char *pos; - char *end; - if (**dirs) - pos= *dirs; - else if (my_defaults_extra_file) - pos= my_defaults_extra_file; - else - continue; - end= convert_dirname(name, pos, NullS); - if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ - *end++='.'; - strxmov(end, conf_file, *ext, " ", NullS); - fputs(name,stdout); + for (ext= (char**) exts_to_use; *ext; ext++) + { + const char *pos; + char *end; + if (**dirs) + pos= *dirs; + else if (my_defaults_extra_file) + pos= my_defaults_extra_file; + else + continue; + end= convert_dirname(name, pos, NullS); + if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ + *end++= '.'; + strxmov(end, conf_file, *ext, " ", NullS); + fputs(name, stdout); + } } } + + free_root(&alloc, MYF(0)); } puts(""); } @@ -928,32 +958,23 @@ void print_defaults(const char *conf_file, const char **groups) #include <help_end.h> -/* - This extra complexity is to avoid declaring 'rc' if it won't be - used. -*/ -#define ADD_DIRECTORY_INTERNAL(DIR) \ - array_append_string_unique((DIR), default_directories, \ - array_elements(default_directories)) -#ifdef DBUG_OFF -# define ADD_DIRECTORY(DIR) (void) ADD_DIRECTORY_INTERNAL(DIR) -#else -#define ADD_DIRECTORY(DIR) \ - do { \ - my_bool rc= ADD_DIRECTORY_INTERNAL(DIR); \ - DBUG_ASSERT(rc == FALSE); /* Success */ \ - } while (0) -#endif +static int add_directory(MEM_ROOT *alloc, const char *dir, const char **dirs) +{ + char buf[FN_REFLEN]; + uint len; + char *p; + my_bool err __attribute__((unused)); + /* Normalize directory name */ + len= unpack_dirname(buf, dir); + if (!(p= strmake_root(alloc, buf, len))) + return 1; /* Failure */ + /* Should never fail if DEFAULT_DIRS_SIZE is correct size */ + err= array_append_string_unique(p, dirs, DEFAULT_DIRS_SIZE); + DBUG_ASSERT(err == FALSE); -#define ADD_COMMON_DIRECTORIES() \ - do { \ - char *env; \ - if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) \ - ADD_DIRECTORY(env); \ - /* Placeholder for --defaults-extra-file=<path> */ \ - ADD_DIRECTORY(""); \ - } while (0) + return 0; +} #ifdef __WIN__ @@ -992,138 +1013,93 @@ static uint my_get_system_windows_directory(char *buffer, uint size) } -/** - Initialize default directories for Microsoft Windows - - @details - 1. GetSystemWindowsDirectory() - 2. GetWindowsDirectory() - 3. C:/ - 4. Directory above where the executable is located - 5. getenv(DEFAULT_HOME_ENV) - 6. --defaults-extra-file=<path> (run-time option) -*/ - -static void init_default_directories_win() +static const char *my_get_module_parent(char *buf, size_t size) { - bzero((char *) default_directories, sizeof(default_directories)); + char *last= NULL; + char *end; + if (!GetModuleFileName(NULL, buf, size)) + return NULL; + end= strend(buf); - if (my_get_system_windows_directory(shared_system_dir, - sizeof(shared_system_dir))) - ADD_DIRECTORY(shared_system_dir); - - if (GetWindowsDirectory(system_dir,sizeof(system_dir))) - ADD_DIRECTORY(system_dir); - - ADD_DIRECTORY("C:/"); - - if (GetModuleFileName(NULL, config_dir, sizeof(config_dir))) + /* + Look for the second-to-last \ in the filename, but hang on + to a pointer after the last \ in case we're in the root of + a drive. + */ + for ( ; end > buf; end--) { - char *last= NULL, *end= strend(config_dir); - /* - Look for the second-to-last \ in the filename, but hang on - to a pointer after the last \ in case we're in the root of - a drive. - */ - for ( ; end > config_dir; end--) + if (*end == FN_LIBCHAR) { - if (*end == FN_LIBCHAR) + if (last) { - if (last) - { - if (end != config_dir) - { - /* Keep the last '\' as this works both with D:\ and a directory */ - end[1]= 0; - } - else - { - /* No parent directory (strange). Use current dir + '\' */ - last[1]= 0; - } - break; - } - last= end; + /* Keep the last '\' as this works both with D:\ and a directory */ + end[1]= 0; + break; } + last= end; } - ADD_DIRECTORY(config_dir); } - ADD_COMMON_DIRECTORIES(); + return buf; } +#endif /* __WIN__ */ -static void (*init_default_directories)()= init_default_directories_win; + +static const char **init_default_directories(MEM_ROOT *alloc) +{ + const char **dirs; + char *env; + int errors= 0; + + dirs= (const char **)alloc_root(alloc, DEFAULT_DIRS_SIZE * sizeof(char *)); + if (dirs == NULL) + return NULL; + bzero((char *) dirs, DEFAULT_DIRS_SIZE * sizeof(char *)); + +#ifdef __WIN__ + + { + char fname_buffer[FN_REFLEN]; + if (my_get_system_windows_directory(fname_buffer, sizeof(fname_buffer))) + errors += add_directory(alloc, fname_buffer, dirs); + + if (GetWindowsDirectory(fname_buffer, sizeof(fname_buffer))) + errors += add_directory(alloc, fname_buffer, dirs); + + errors += add_directory(alloc, "C:/", dirs); + + if (my_get_module_parent(fname_buffer, sizeof(fname_buffer)) != NULL) + errors += add_directory(alloc, fname_buffer, dirs); + } #elif defined(__NETWARE__) -/** - Initialize default directories for Novell Netware - - @details - 1. sys:/etc/ - 2. getenv(DEFAULT_HOME_ENV) - 3. --defaults-extra-file=<path> (run-time option) -*/ - -static void init_default_directories_netware() -{ - bzero((char *) default_directories, sizeof(default_directories)); - ADD_DIRECTORY("sys:/etc/"); - ADD_COMMON_DIRECTORIES(); -} - -static void (*init_default_directories)()= init_default_directories_netware; - -#elif defined(__EMX__) || defined(OS2) - -/** - Initialize default directories for OS/2 - - @details - 1. /etc/ - 2. getenv(ETC) - 3. getenv(DEFAULT_HOME_ENV) - 4. --defaults-extra-file=<path> (run-time option) -*/ - -static void init_default_directories_os2() -{ - const char *env; - - bzero((char *) default_directories, sizeof(default_directories)); - ADD_DIRECTORY("/etc/"); - if ((env= getenv("ETC"))) - ADD_DIRECTORY(env); - ADD_COMMON_DIRECTORIES(); -} - -static void (*init_default_directories)()= init_default_directories_os2; + errors += add_directory(alloc, "sys:/etc/", dirs); #else -/** - Initialize default directories for Unix + errors += add_directory(alloc, "/etc/", dirs); - @details - 1. /etc/ - 2. --sysconfdir=<path> (compile-time option) - 3. getenv(DEFAULT_HOME_ENV) - 4. --defaults-extra-file=<path> (run-time option) - 5. "~/" -*/ - -static void init_default_directories_unix() -{ - bzero((char *) default_directories, sizeof(default_directories)); - ADD_DIRECTORY("/etc/"); -#ifdef DEFAULT_SYSCONFDIR +#if defined(__EMX__) || defined(OS2) + if ((env= getenv("ETC"))) + errors += add_directory(alloc, env, dirs); +#elif defined(DEFAULT_SYSCONFDIR) if (DEFAULT_SYSCONFDIR != "") - ADD_DIRECTORY(DEFAULT_SYSCONFDIR); + errors += add_directory(alloc, DEFAULT_SYSCONFDIR, dirs); +#endif /* __EMX__ || __OS2__ */ + #endif - ADD_COMMON_DIRECTORIES(); - ADD_DIRECTORY("~/"); + + if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) + errors += add_directory(alloc, env, dirs); + + /* Placeholder for --defaults-extra-file=<path> */ + errors += add_directory(alloc, "", dirs); + +#if !defined(__WIN__) && !defined(__NETWARE__) && \ + !defined(__EMX__) && !defined(OS2) + errors += add_directory(alloc, "~/", dirs); +#endif + + return (errors > 0 ? NULL : dirs); } - -static void (*init_default_directories)()= init_default_directories_unix; - -#endif diff --git a/sql/item.cc b/sql/item.cc index 9ff1f8c0084..bf447581afa 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5013,21 +5013,28 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length) if (!ptr) return; str_value.set(ptr, max_length, &my_charset_bin); - ptr+= max_length - 1; - ptr[1]= 0; // Set end null for string - for (; end >= str; end--) + + if (max_length > 0) { - if (power == 256) + ptr+= max_length - 1; + ptr[1]= 0; // Set end null for string + for (; end >= str; end--) { - power= 1; - *ptr--= bits; - bits= 0; + if (power == 256) + { + power= 1; + *ptr--= bits; + bits= 0; + } + if (*end == '1') + bits|= power; + power<<= 1; } - if (*end == '1') - bits|= power; - power<<= 1; + *ptr= (char) bits; } - *ptr= (char) bits; + else + ptr[0]= 0; + collation.set(&my_charset_bin, DERIVATION_COERCIBLE); fixed= 1; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c443364ce52..d1e3f45bba1 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3258,7 +3258,8 @@ static char clock_seq_and_node_str[]="-0000-000000000000"; /* number of 100-nanosecond intervals between 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */ -#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 ) +#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \ + 1000 * 1000 * 10) #define UUID_VERSION 0x1000 #define UUID_VARIANT 0x8000 @@ -3317,24 +3318,64 @@ String *Item_func_uuid::val_str(String *str) set_clock_seq_str(); } - ulonglong tv=my_getsystime() + UUID_TIME_OFFSET + nanoseq; - if (unlikely(tv < uuid_time)) - set_clock_seq_str(); - else if (unlikely(tv == uuid_time)) + ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq; + + if (likely(tv > uuid_time)) { - /* special protection from low-res system clocks */ - nanoseq++; - tv++; + /* + Current time is ahead of last timestamp, as it should be. + If we "borrowed time", give it back, just as long as we + stay ahead of the previous timestamp. + */ + if (nanoseq) + { + DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0)); + /* + -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time) + */ + ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1)); + tv-= delta; + nanoseq-= delta; + } } else { - if (nanoseq) + if (unlikely(tv == uuid_time)) { - tv-=nanoseq; - nanoseq=0; + /* + For low-res system clocks. If several requests for UUIDs + end up on the same tick, we add a nano-second to make them + different. + ( current_timestamp + nanoseq * calls_in_this_period ) + may end up > next_timestamp; this is OK. Nonetheless, we'll + try to unwind nanoseq when we get a chance to. + If nanoseq overflows, we'll start over with a new numberspace + (so the if() below is needed so we can avoid the ++tv and thus + match the follow-up if() if nanoseq overflows!). + */ + if (likely(++nanoseq)) + ++tv; + } + + if (unlikely(tv <= uuid_time)) + { + /* + If the admin changes the system clock (or due to Daylight + Saving Time), the system clock may be turned *back* so we + go through a period once more for which we already gave out + UUIDs. To avoid duplicate UUIDs despite potentially identical + times, we make a new random component. + We also come here if the nanoseq "borrowing" overflows. + In either case, we throw away any nanoseq borrowing since it's + irrelevant in the new numberspace. + */ + set_clock_seq_str(); + tv= my_getsystime() + UUID_TIME_OFFSET; + nanoseq= 0; + DBUG_PRINT("uuid",("making new numberspace")); } - DBUG_ASSERT(tv > uuid_time); } + uuid_time=tv; pthread_mutex_unlock(&LOCK_uuid_generator); diff --git a/sql/log_event.cc b/sql/log_event.cc index 05dccd782ad..ef419aaee40 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4154,8 +4154,14 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) /* Item_func_set_user_var can't substitute something else on its place => 0 can be passed as last argument (reference on item) + + Fix_fields() can fail, in which case a call of update_hash() might + crash the server, so if fix fields fails, we just return with an + error. */ - e.fix_fields(thd, 0); + if (e.fix_fields(thd, 0)) + return 1; + /* A variable can just be considered as a table with a single record and with a single column. Thus, like diff --git a/sql/sp_head.h b/sql/sp_head.h index 11ff7160c03..91f465a4e2a 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -117,7 +117,6 @@ public: create_field m_return_field_def; /* This is used for FUNCTIONs only. */ const char *m_tmp_query; // Temporary pointer to sub query string - uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value st_sp_chistics *m_chistics; ulong m_sql_mode; // For SHOW CREATE and execution LEX_STRING m_qname; // db.name diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6bfcd982b04..a1bfc3edc6c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1010,21 +1010,8 @@ int MYSQLlex(void *arg, void *yythd) yySkip(); return (SET_VAR); case MY_LEX_SEMICOLON: // optional line terminator - if (yyPeek()) - { - if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && - !lip->stmt_prepare_mode) - { - lex->safe_to_cache_query= 0; - lip->found_semicolon= lip->ptr; - thd->server_status|= SERVER_MORE_RESULTS_EXISTS; - lip->next_state= MY_LEX_END; - return (END_OF_INPUT); - } - state= MY_LEX_CHAR; // Return ';' - break; - } - /* fall true */ + state= MY_LEX_CHAR; // Return ';' + break; case MY_LEX_EOL: if (lip->ptr >= lip->end_of_query) { @@ -1039,7 +1026,7 @@ int MYSQLlex(void *arg, void *yythd) case MY_LEX_END: lip->next_state=MY_LEX_END; return(0); // We found end of input last time - + /* Actually real shouldn't start with . but allow them anyhow */ case MY_LEX_REAL_OR_POINT: if (my_isdigit(cs,yyPeek())) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 98e04e45bdd..62a5a79a833 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6169,6 +6169,11 @@ void mysql_parse(THD *thd, const char *inBuf, uint length, (thd->query_length= (ulong)(lip.found_semicolon - thd->query))) thd->query_length--; /* Actually execute the query */ + if (*found_semicolon) + { + lex->safe_to_cache_query= 0; + thd->server_status|= SERVER_MORE_RESULTS_EXISTS; + } lex->set_trg_event_type_for_tables(); mysql_execute_command(thd); query_cache_end_of_result(thd); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ffc84bde9c1..090585392a0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1203,21 +1203,54 @@ END_OF_INPUT query: - END_OF_INPUT - { - THD *thd= YYTHD; - if (!thd->bootstrap && - (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) - { - my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); - MYSQL_YYABORT; - } - else - { - thd->lex->sql_command= SQLCOM_EMPTY_QUERY; - } - } - | verb_clause END_OF_INPUT {}; + END_OF_INPUT + { + THD *thd= YYTHD; + if (!thd->bootstrap && + (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + { + my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); + MYSQL_YYABORT; + } + thd->lex->sql_command= SQLCOM_EMPTY_QUERY; + thd->m_lip->found_semicolon= NULL; + } + | verb_clause + { + Lex_input_stream *lip = YYTHD->m_lip; + + if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) && + ! lip->stmt_prepare_mode && + ! (lip->ptr >= lip->end_of_query)) + { + /* + We found a well formed query, and multi queries are allowed: + - force the parser to stop after the ';' + - mark the start of the next query for the next invocation + of the parser. + */ + lip->next_state= MY_LEX_END; + lip->found_semicolon= lip->ptr; + } + else + { + /* Single query, terminated. */ + lip->found_semicolon= NULL; + } + } + ';' + opt_end_of_input + | verb_clause END_OF_INPUT + { + /* Single query, not terminated. */ + YYTHD->m_lip->found_semicolon= NULL; + } + ; + +opt_end_of_input: + /* empty */ + | END_OF_INPUT + ; verb_clause: statement @@ -9867,13 +9900,6 @@ trigger_tail: lex->sphead= sp; lex->spname= $3; - /* - We have to turn of CLIENT_MULTI_QUERIES while parsing a - stored procedure, otherwise yylex will chop it into pieces - at each ';'. - */ - sp->m_old_cmq= thd->client_capabilities & CLIENT_MULTI_QUERIES; - thd->client_capabilities &= ~CLIENT_MULTI_QUERIES; bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); lex->sphead->m_chistics= &lex->sp_chistics; @@ -9888,9 +9914,6 @@ trigger_tail: lex->sql_command= SQLCOM_CREATE_TRIGGER; sp->init_strings(YYTHD, lex); - /* Restore flag if it was cleared above */ - if (sp->m_old_cmq) - YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; sp->restore_thd_mem_root(YYTHD); if (sp->is_not_allowed_in_function("trigger")) @@ -9968,13 +9991,6 @@ sf_tail: sp->m_type= TYPE_ENUM_FUNCTION; lex->sphead= sp; - /* - * We have to turn of CLIENT_MULTI_QUERIES while parsing a - * stored procedure, otherwise yylex will chop it into pieces - * at each ';'. - */ - sp->m_old_cmq= thd->client_capabilities & CLIENT_MULTI_QUERIES; - thd->client_capabilities &= ~CLIENT_MULTI_QUERIES; lex->sphead->m_param_begin= lip->tok_start+1; } sp_fdparam_list /* $6 */ @@ -10030,9 +10046,6 @@ sf_tail: my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); MYSQL_YYABORT; } - /* Restore flag if it was cleared above */ - if (sp->m_old_cmq) - YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; sp->restore_thd_mem_root(YYTHD); } ; @@ -10062,13 +10075,6 @@ sp_tail: sp->init_sp_name(YYTHD, $3); lex->sphead= sp; - /* - * We have to turn of CLIENT_MULTI_QUERIES while parsing a - * stored procedure, otherwise yylex will chop it into pieces - * at each ';'. - */ - sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; - YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); } '(' { @@ -10104,9 +10110,6 @@ sp_tail: sp->init_strings(YYTHD, lex); lex->sql_command= SQLCOM_CREATE_PROCEDURE; - /* Restore flag if it was cleared above */ - if (sp->m_old_cmq) - YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; sp->restore_thd_mem_root(YYTHD); } ;