diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 1646f2baf51..02829cd2178 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -456,7 +456,11 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, if (my_write(fd, query, strlen(query), MYF(MY_FNABP | MY_WME))) + { + my_close(fd, MYF(0)); + my_delete(query_file_path, MYF(0)); die("Failed to write to '%s'", query_file_path); + } ret= run_tool(mysql_path, ds_res, diff --git a/client/mysqltest.c b/client/mysqltest.c index a2412d4b30e..eae3b05f61a 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1580,10 +1580,21 @@ void check_result(DYNAMIC_STRING* ds) and then show the diff */ char reject_file[FN_REFLEN]; - str_to_file(fn_format(reject_file, result_file_name, opt_logdir, ".reject", - *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT : - MY_REPLACE_EXT), - ds->str, ds->length); + dirname_part(reject_file, result_file_name); + + if (access(reject_file, W_OK) == 0) + { + /* Result file directory is writable, save reject file there */ + fn_format(reject_file, result_file_name, NULL, + ".reject", MY_REPLACE_EXT); + } + else + { + /* Put reject file in opt_logdir */ + fn_format(reject_file, result_file_name, opt_logdir, + ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT); + } + str_to_file(reject_file, ds->str, ds->length); dynstr_set(ds, NULL); /* Don't create a .log file */ diff --git a/debian/po/ca.po b/debian/po/ca.po index 9dc1fc0de77..5019f05c909 100644 --- a/debian/po/ca.po +++ b/debian/po/ca.po @@ -162,9 +162,9 @@ msgid "" msgstr "" #, fuzzy -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" #~ msgstr "" -#~ "Feu una ullada al document: http://www.mysql.com/doc/en/Upgrade.html" +#~ "Feu una ullada al document: http://dev.mysql.com/doc/mysql/en/upgrade.html" #, fuzzy #~ msgid "" diff --git a/debian/po/cs.po b/debian/po/cs.po index 33e4f213bb2..ada32a3469b 100644 --- a/debian/po/cs.po +++ b/debian/po/cs.po @@ -213,8 +213,8 @@ msgstr "" #~ "se tabulky mohly narušit! Tento skript také rozšiřuje tabulky privilegií, " #~ "ovšem neměl by uživatelům přidat více práv, než měli dosud." -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Také si přečtěte http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Také si přečtěte http://dev.mysql.com/doc/mysql/en/upgrade.html" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " diff --git a/debian/po/da.po b/debian/po/da.po index 5e93e3f7b33..cfaf2705254 100644 --- a/debian/po/da.po +++ b/debian/po/da.po @@ -215,8 +215,8 @@ msgstr "" #~ "kan blive delagt! Dette script forbedrer ogs rettighedstabellerne, men " #~ "burde ikke give nogen bruger flere rettigheder, end han havde tidligere," -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Ls ogs http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Ls ogs http://dev.mysql.com/doc/mysql/en/upgrade.html" #~ msgid "Install Hints" #~ msgstr "Installationstips" diff --git a/debian/po/gl.po b/debian/po/gl.po index 44fd58872cc..de5356e24f3 100644 --- a/debian/po/gl.po +++ b/debian/po/gl.po @@ -211,8 +211,8 @@ msgstr "" #~ "privilexios, pero non se supón que vaia dar a ningún usuario máis " #~ "dereitos dos que tiña antes." -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Lea tamén http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Lea tamén http://dev.mysql.com/doc/mysql/en/upgrade.html" #~ msgid "Install Hints" #~ msgstr "Consellos de instalación" diff --git a/debian/po/ja.po b/debian/po/ja.po index 14d97ed977b..5d9151da652 100644 --- a/debian/po/ja.po +++ b/debian/po/ja.po @@ -274,5 +274,5 @@ msgstr "" #~ "す。スクリプトは、どのようなユーザに対しても、以前に保持していた以上の権限" #~ "を与えるようにはなっていません。" -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "http://www.mysql.com/doc/ja/Upgrade.html も参照してください" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "http://dev.mysql.com/doc/mysql/ja/upgrade.html も参照してください" diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po index 51557b006e6..e7684ae7bd6 100644 --- a/debian/po/pt_BR.po +++ b/debian/po/pt_BR.po @@ -205,8 +205,8 @@ msgstr "" #~ "atribuirá a nenhum usuário mais direitos do que os mesmos já possuíam " #~ "anteriormente." -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Por favor, leia http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Por favor, leia http://dev.mysql.com/doc/mysql/en/upgrade.html" #, fuzzy #~ msgid "Install Hints" diff --git a/debian/po/sv.po b/debian/po/sv.po index 54ef9246236..62f471dea0f 100644 --- a/debian/po/sv.po +++ b/debian/po/sv.po @@ -165,8 +165,8 @@ msgstr "S #~ "tabellerna vara skadade! Detta skript utkar ven privilegietabellerna " #~ "men r inte tnkte att ge ngon anvndare mer befogenhet n vad han hade " #~ "tidigare," -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Ls ven http://www.mysql.com/doc/en/Upgrade.html" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Ls ven http://dev.mysql.com/doc/mysql/en/upgrade.html" #~ msgid "Install Hints" #~ msgstr "Installationstips" #~ msgid "" diff --git a/debian/po/tr.po b/debian/po/tr.po index 20b4df45b6e..b81d28957e1 100644 --- a/debian/po/tr.po +++ b/debian/po/tr.po @@ -162,8 +162,8 @@ msgid "" msgstr "" #, fuzzy -#~ msgid "Please also read http://www.mysql.com/doc/en/Upgrade.html" -#~ msgstr "Lütfen http://www.mysql.com/doc/en/Upgrade.html belgesini okuyun" +#~ msgid "Please also read http://dev.mysql.com/doc/mysql/en/upgrade.html" +#~ msgstr "Lütfen http://dev.mysql.com/doc/mysql/en/upgrade.html belgesini okuyun" #, fuzzy #~ msgid "" diff --git a/extra/comp_err.c b/extra/comp_err.c index 7cc4a0aa43f..79f591e45fb 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -167,6 +167,7 @@ int main(int argc, char *argv[]) DBUG_ENTER("main"); charsets_dir= DEFAULT_CHARSET_DIR; + my_umask_dir= 0777; if (get_options(&argc, &argv)) DBUG_RETURN(1); if (!(row_count= parse_input_file(TXTFILE, &error_head, &lang_head))) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 5e176dce109..5aabb7f8863 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -27,6 +27,26 @@ sub collect_one_test_case ($$$$$$$); sub mtr_options_from_test_file($$); +my $do_test; +my $skip_test; + +sub init_pattern { + my ($from, $what)= @_; + if ( $from =~ /[a-z0-9]/ ) { + # Does not contain any regex, make the pattern match + # beginning of string + $from= "^$from"; + } + else { + # Check that pattern is a valid regex + eval { "" =~/$from/; 1 } or + mtr_error("Invalid regex '$from' passed to $what\nPerl says: $@"); + } + return $from; +} + + + ############################################################################## # # Collect information about test cases we are to run @@ -39,6 +59,9 @@ sub collect_test_cases ($) { my $testdir; my $resdir; + $do_test= init_pattern($::opt_do_test, "--do-test"); + $skip_test= init_pattern($::opt_skip_test, "--skip-test"); + if ( $suite eq "main" ) { $testdir= "$::glob_mysql_test_dir/t"; @@ -162,8 +185,7 @@ sub collect_test_cases ($) { } # Skip tests that does not match the --do-test= filter - next if $::opt_do_test and - ! defined mtr_match_prefix($elem,$::opt_do_test); + next if ($do_test and not $tname =~ /$do_test/o); collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, $component_id); @@ -288,7 +310,7 @@ sub collect_one_test_case($$$$$$$) { # Skip some tests but include in list, just mark them to skip # ---------------------------------------------------------------------- - if ( $::opt_skip_test and defined mtr_match_prefix($tname,$::opt_skip_test) ) + if ( $skip_test and $tname =~ /$skip_test/o ) { $tinfo->{'skip'}= 1; return; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index ca66138d279..1694ad1cb2e 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -196,7 +196,7 @@ sub mtr_report_stats ($) { "of what went wrong.\n", "If you want to report this error, please read first ", "the documentation at\n", - "http://www.mysql.com/doc/en/MySQL_test_suite.html\n"; + "http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html\n"; } if (!$::opt_extern) { diff --git a/mysql-test/mysql-test-run-shell.sh b/mysql-test/mysql-test-run-shell.sh index c0ff3d3d88e..e0f151904f8 100644 --- a/mysql-test/mysql-test-run-shell.sh +++ b/mysql-test/mysql-test-run-shell.sh @@ -935,7 +935,7 @@ show_failed_diff () $DIFF -c $result_file $reject_file echo "-------------------------------------------------------" echo "Please follow the instructions outlined at" - echo "http://dev.mysql.com/doc/mysql/en/reporting-mysqltest-bugs.html" + echo "http://forge.mysql.com/wiki/MySQL_Internals_Porting#Debugging_a_MySQL_Server" echo "to find the reason to this problem and how to report this." echo "" fi diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ad507440bb7..29d3265a462 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1334,12 +1334,13 @@ sub datadir_list_setup () { sub collect_mysqld_features () { my $found_variable_list_start= 0; + my $tmpdir= tempdir(CLEANUP => 0); # Directory removed by this function # # Execute "mysqld --no-defaults --help --verbose" to get a # list of all features and settings # - my $list= `$exe_mysqld --no-defaults --verbose --help`; + my $list= `$exe_mysqld --no-defaults --datadir=$tmpdir --verbose --help`; foreach my $line (split('\n', $list)) { @@ -1394,7 +1395,7 @@ sub collect_mysqld_features () { } } } - + rmtree($tmpdir); mtr_error("Could not find version of MySQL") unless $mysql_version_id; mtr_error("Could not find variabes list") unless $found_variable_list_start; @@ -5006,7 +5007,7 @@ sub valgrind_arguments { } # Add valgrind options, can be overriden by user - mtr_add_arg($args, '%s', $_) for (split(' ', $opt_valgrind_options)); + mtr_add_arg($args, '%s', $opt_valgrind_options); mtr_add_arg($args, $$exe); @@ -5079,12 +5080,16 @@ Options to control what test suites or cases to run skip-ndb[cluster] Skip all tests that need cluster skip-ndb[cluster]-slave Skip all tests that need a slave cluster ndb-extra Run extra tests from ndb directory - do-test=PREFIX Run test cases which name are prefixed with PREFIX + do-test=PREFIX or REGEX + Run test cases which name are prefixed with PREFIX + or fulfills REGEX + skip-test=PREFIX or REGEX + Skip test cases which name are prefixed with PREFIX + or fulfills REGEX start-from=PREFIX Run test cases starting from test prefixed with PREFIX suite=NAME Run the test suite named NAME. The default is "main" skip-rpl Skip the replication test cases. skip-im Don't start IM, and skip the IM test cases - skip-test=PREFIX Skip test cases which name are prefixed with PREFIX big-test Set the environment variable BIG_TEST, which can be checked from test cases. diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index a4c51cca277..855352a2195 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1121,6 +1121,9 @@ SELECT * FROM test.t1; f1 f2 1 1 2 2 +REVOKE UPDATE (f1) ON `test`.`t1` FROM 'mysqltest_1'@'localhost'; +REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost'; +REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; DROP DATABASE db27878; use test; DROP TABLE t1; diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result index 6193c4fd49d..cc7f46855b2 100644 --- a/mysql-test/r/grant3.result +++ b/mysql-test/r/grant3.result @@ -16,3 +16,125 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; +grant select on test.* to CUser@localhost; +grant select on test.* to CUser@LOCALHOST; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; +user host db select_priv +CUser LOCALHOST test Y +CUser localhost test Y +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; +user host db select_priv +CUser localhost test Y +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; +user host db select_priv +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; +create table t1 (a int); +grant select on test.t1 to CUser@localhost; +grant select on test.t1 to CUser@LOCALHOST; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +CUser LOCALHOST test t1 Select +CUser localhost test t1 Select +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +CUser localhost test t1 Select +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; +grant select(a) on test.t1 to CUser@localhost; +grant select(a) on test.t1 to CUser@LOCALHOST; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +CUser LOCALHOST test t1 Select +CUser localhost test t1 Select +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +CUser localhost test t1 Select +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +user host +CUser LOCALHOST +CUser localhost +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; +user host db Table_name Table_priv Column_priv +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; +drop table t1; +grant select on test.* to CUser2@localhost; +grant select on test.* to CUser2@LOCALHOST; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +user host +CUser2 LOCALHOST +CUser2 localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; +user host db select_priv +CUser2 LOCALHOST test Y +CUser2 localhost test Y +REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +user host +CUser2 LOCALHOST +CUser2 localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; +user host db select_priv +CUser2 localhost test Y +REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; +flush privileges; +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +user host +CUser2 LOCALHOST +CUser2 localhost +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; +user host db select_priv +DROP USER CUser2@localhost; +DROP USER CUser2@LOCALHOST; diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 9e47b5da2b6..590e9b7c9e0 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -427,3 +427,19 @@ f1 Warnings: Warning 1292 Incorrect datetime value: '2007010100000' for column 'f1' at row 1 drop table t1; +create table t1 (f1 time); +insert into t1 set f1 = '45:44:44'; +insert into t1 set f1 = '15:44:44'; +select * from t1 where (convert(f1,datetime)) != 1; +f1 +15:44:44 +Warnings: +Warning 1292 Truncated incorrect datetime value: '0000-00-00 45:44:44' +drop table t1; +create table t1 (a tinyint); +insert into t1 values (), (), (); +select sum(a) from t1 group by convert(a, datetime); +sum(a) +NULL +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 3cf24529421..65a72e0aa9b 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -683,6 +683,7 @@ select * from t1; a b 123.12345 123.1 drop table t1; +End of 4.1 tests CREATE TABLE t1 (EMPNUM CHAR(3) NOT NULL, HOURS DECIMAL(5)); @@ -799,3 +800,10 @@ SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; ROUND(qty,3) dps ROUND(qty,dps) 1.133 3 1.133 DROP TABLE t1; +create table t1 (f1 decimal(6,6),f2 decimal(6,6) zerofill); +insert into t1 values (-0.123456,0.123456); +select group_concat(f1),group_concat(f2) from t1; +group_concat(f1) group_concat(f2) +-0.123456 0.123456 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 32eb262fd51..1d11a669811 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1144,6 +1144,9 @@ UPDATE v1 SET f2 = 4; SELECT * FROM test.t1; disconnect user1; connection default; +REVOKE UPDATE (f1) ON `test`.`t1` FROM 'mysqltest_1'@'localhost'; +REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost'; +REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; DROP DATABASE db27878; use test; DROP TABLE t1; diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test index 115586e807d..fac577ef0ff 100644 --- a/mysql-test/t/grant3.test +++ b/mysql-test/t/grant3.test @@ -34,3 +34,103 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; + +# +# Bug: #19828 Case sensitivity in Grant/Revoke +# + +grant select on test.* to CUser@localhost; +grant select on test.* to CUser@LOCALHOST; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; + +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; + +#### table grants +create table t1 (a int); +grant select on test.t1 to CUser@localhost; +grant select on test.t1 to CUser@LOCALHOST; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; + +### column grants + +grant select(a) on test.t1 to CUser@localhost; +grant select(a) on test.t1 to CUser@LOCALHOST; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; + +DROP USER CUser@localhost; +DROP USER CUser@LOCALHOST; + +drop table t1; + +# revoke on a specific DB only + +grant select on test.* to CUser2@localhost; +grant select on test.* to CUser2@LOCALHOST; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; + +REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; + +REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; +flush privileges; + +SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; + +DROP USER CUser2@localhost; +DROP USER CUser2@LOCALHOST; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 8a38972c00f..ec188af0244 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1435,7 +1435,10 @@ select "this will be executed"; --exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result > /dev/null 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.result; +--error 0,1 remove_file $MYSQLTEST_VARDIR/log/zero_length_file.reject; +--error 0,1 +remove_file $MYSQL_TEST_DIR/r/zero_length_file.reject; # # Test that a test file that does not generate any output fails. diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index ffda593f320..20733a14d46 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -282,3 +282,23 @@ select * from t1 where f1 between 20020101 and 20070101000000; select * from t1 where f1 between 2002010 and 20070101000000; select * from t1 where f1 between 20020101 and 2007010100000; drop table t1; + +# +# Bug #31253: crash comparing datetime to double +# Should return 1st row only. Crashes if NULL propagation fails. +# +create table t1 (f1 time); +insert into t1 set f1 = '45:44:44'; +insert into t1 set f1 = '15:44:44'; +select * from t1 where (convert(f1,datetime)) != 1; +drop table t1; + +# +# Bug #31249: problem with convert(..., datetime) +# +create table t1 (a tinyint); +insert into t1 values (), (), (); +select sum(a) from t1 group by convert(a, datetime); +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 5538f19f5f9..458583fca81 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -278,7 +278,7 @@ update t1 set b=a; select * from t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests # # Test for BUG#8397: decimal type in subselects (Item_cache_decimal) @@ -408,3 +408,14 @@ INSERT INTO t1 VALUES (1.1325,3); SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; DROP TABLE t1; + +# +# Bug #31227: memory overrun with decimal (6,6) and zerofill and group_concat +# valgrind will complain about this (the group_concat(f2)) on unpatched mysqld. +# +create table t1 (f1 decimal(6,6),f2 decimal(6,6) zerofill); +insert into t1 values (-0.123456,0.123456); +select group_concat(f1),group_concat(f2) from t1; +drop table t1; + +--echo End of 5.0 tests diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index f83db77739e..dbbf11612ed 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -17,7 +17,7 @@ @mainpage NDB API Programmers' Guide This guide assumes a basic familiarity with MySQL Cluster concepts found - on http://dev.mysql.com/doc/mysql/en/NDBCluster.html . + on http://dev.mysql.com/doc/mysql/en/mysql-cluster.html. Some of the fundamental ones are also described in section @ref secConcepts. The NDB API is a MySQL Cluster application interface diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index a62de9013f9..3bdbc242f9e 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -175,7 +175,7 @@ void report_stats() log_msg("\nThe .out and .err files in %s may give you some\n", result_dir); log_msg("hint of what went wrong.\n"); log_msg("\nIf you want to report this error, please first read the documentation\n"); - log_msg("at: http://www.mysql.com/doc/en/MySQL_test_suite.html\n"); + log_msg("at: http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html\n"); } log_msg("\n%.02f total minutes elapsed in the test cases\n\n", total_time / 60); diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 52fe282f916..e6b015e7d16 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -231,7 +231,7 @@ then echo "Please do a cd to the mysql installation directory and restart" echo "this script from there as follows:" echo "./bin/mysqld_safe". - echo "See http://dev.mysql.com/doc/mysql/en/mysqld_safe.html for more" + echo "See http://dev.mysql.com/doc/mysql/en/mysqld-safe.html for more" echo "information" exit 1 fi diff --git a/sql/item.cc b/sql/item.cc index e9b2904e3da..5f73b016e50 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -274,6 +274,7 @@ my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value) if (get_date(<ime, TIME_FUZZY_DATE)) { my_decimal_set_zero(decimal_value); + null_value= 1; // set NULL, stop processing return 0; } return date2my_decimal(<ime, decimal_value); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 8e925a0156f..94bee28bb6b 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -844,7 +844,9 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } void fix_length_and_dec() { - Item_typecast_maybe_null::fix_length_and_dec(); + collation.set(&my_charset_bin); + maybe_null= 1; + max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN; decimals= DATETIME_DEC; } diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 4ef2ae5cf95..31a5b09370a 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -68,24 +68,43 @@ int decimal_operation_results(int result) } -/* - Converting decimal to string +/** + @brief Converting decimal to string - SYNOPSIS - my_decimal2string() + @details Convert given my_decimal to String; allocate buffer as needed. - return - E_DEC_OK - E_DEC_TRUNCATED - E_DEC_OVERFLOW - E_DEC_OOM + @param[in] mask what problems to warn on (mask of E_DEC_* values) + @param[in] d the decimal to print + @param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise + @param[in] fixed_dec number of decimal places (if fixed_prec != 0) + @param[in] filler what char to pad with (ZEROFILL et al.) + @param[out] *str where to store the resulting string + + @return error coce + @retval E_DEC_OK + @retval E_DEC_TRUNCATED + @retval E_DEC_OVERFLOW + @retval E_DEC_OOM */ int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec, uint fixed_dec, char filler, String *str) { - int length= (fixed_prec ? (fixed_prec + 1) : my_decimal_string_length(d)); + /* + Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a + holds true iff the type is also ZEROFILL, which in turn implies + UNSIGNED. Hence the buffer for a ZEROFILLed value is the length + the user requested, plus one for a possible decimal point, plus + one if the user only wanted decimal places, but we force a leading + zero on them. Because the type is implicitly UNSIGNED, we do not + need to reserve a character for the sign. For all other cases, + fixed_prec will be 0, and my_decimal_string_length() will be called + instead to calculate the required size of the buffer. + */ + int length= (fixed_prec + ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1) + : my_decimal_string_length(d)); int result; if (str->alloc(length)) return check_result(mask, E_DEC_OOM); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5173d4c9501..9d53ef19758 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2143,7 +2143,7 @@ bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size + You seem to be running 32-bit Linux and have %d concurrent connections.\n\ If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\ yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\ -the thread stack. Please read http://www.mysql.com/doc/en/Linux.html\n\n", +the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", thread_count); } #endif /* HAVE_LINUXTHREADS */ @@ -2163,7 +2163,7 @@ Some pointers may be invalid and cause the dump to abort...\n"); fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); } fprintf(stderr, "\ -The manual page at http://www.mysql.com/doc/en/Crashing.html contains\n\ +The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ information that should help you find out what is causing the crash.\n"); fflush(stderr); #endif /* HAVE_STACKTRACE */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f9bd2c6ba0d..6bc6cce5e72 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1132,7 +1132,7 @@ static void acl_update_db(const char *user, const char *host, const char *db, { if (!acl_db->host.hostname && !host[0] || acl_db->host.hostname && - !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) + !strcmp(host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -4344,6 +4344,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_db->host.hostname)) host= ""; + /* + We do not make SHOW GRANTS case-sensitive here (like REVOKE), + but make it case-insensitive because that's the way they are + actually applied, and showing fewer privileges than are applied + would be wrong from a security point of view. + */ + if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { @@ -4379,8 +4386,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) db.append(lex_user->user.str, lex_user->user.length, system_charset_info); db.append (STRING_WITH_LEN("'@'")); - db.append(lex_user->host.str, lex_user->host.length, - system_charset_info); + // host and lex_user->host are equal except for case + db.append(host, strlen(host), system_charset_info); db.append ('\''); if (want_access & GRANT_ACL) db.append(STRING_WITH_LEN(" WITH GRANT OPTION")); @@ -4407,6 +4414,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host= grant_table->host.hostname)) host= ""; + /* + We do not make SHOW GRANTS case-sensitive here (like REVOKE), + but make it case-insensitive because that's the way they are + actually applied, and showing fewer privileges than are applied + would be wrong from a security point of view. + */ + if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { @@ -4487,8 +4501,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(lex_user->user.str, lex_user->user.length, system_charset_info); global.append(STRING_WITH_LEN("'@'")); - global.append(lex_user->host.str,lex_user->host.length, - system_charset_info); + // host and lex_user->host are equal except for case + global.append(host, strlen(host), system_charset_info); global.append('\''); if (table_access & GRANT_ACL) global.append(STRING_WITH_LEN(" WITH GRANT OPTION")); @@ -4543,6 +4557,13 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash, if (!(host= grant_proc->host.hostname)) host= ""; + /* + We do not make SHOW GRANTS case-sensitive here (like REVOKE), + but make it case-insensitive because that's the way they are + actually applied, and showing fewer privileges than are applied + would be wrong from a security point of view. + */ + if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { @@ -4586,8 +4607,8 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash, global.append(lex_user->user.str, lex_user->user.length, system_charset_info); global.append(STRING_WITH_LEN("'@'")); - global.append(lex_user->host.str,lex_user->host.length, - system_charset_info); + // host and lex_user->host are equal except for case + global.append(host, strlen(host), system_charset_info); global.append('\''); if (proc_access & GRANT_ACL) global.append(STRING_WITH_LEN(" WITH GRANT OPTION")); @@ -5541,7 +5562,7 @@ bool mysql_revoke_all(THD *thd, List &list) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(system_charset_info, lex_user->host.str, host)) + !strcmp(lex_user->host.str, host)) { if (!replace_db_table(tables[1].table, acl_db->db, *lex_user, ~(ulong)0, 1)) { @@ -5572,7 +5593,7 @@ bool mysql_revoke_all(THD *thd, List &list) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(system_charset_info, lex_user->host.str, host)) + !strcmp(lex_user->host.str, host)) { if (replace_table_table(thd,grant_table,tables[2].table,*lex_user, grant_table->db, @@ -5618,7 +5639,7 @@ bool mysql_revoke_all(THD *thd, List &list) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(system_charset_info, lex_user->host.str, host)) + !strcmp(lex_user->host.str, host)) { if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, grant_proc->db, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1d11f23d854..7d4421b2749 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13902,13 +13902,31 @@ calc_group_buffer(JOIN *join,ORDER *group) group_item->decimals); break; case STRING_RESULT: + { + enum enum_field_types type= group_item->field_type(); /* - Group strings are taken as varstrings and require an length field. - A field is not yet created by create_tmp_field() - and the sizes should match up. + As items represented as DATE/TIME fields in the group buffer + have STRING_RESULT result type, we increase the length + by 8 as maximum pack length of such fields. */ - key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH; + if (type == MYSQL_TYPE_TIME || + type == MYSQL_TYPE_DATE || + type == MYSQL_TYPE_DATETIME || + type == MYSQL_TYPE_TIMESTAMP) + { + key_length+= 8; + } + else + { + /* + Group strings are taken as varstrings and require an length field. + A field is not yet created by create_tmp_field() + and the sizes should match up. + */ + key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH; + } break; + } default: /* This case should never be choosen */ DBUG_ASSERT(0);