mariadb/mysql-test/r/timezone2.result
unknown 0ea47f3ed4 BUG#9953: CONVERT_TZ requires mysql.time_zone_name to be locked
The problem was that some facilities (like CONVERT_TZ() function or
server HELP statement) may require implicit access to some tables in
'mysql' database.  This access was done by ordinary means of adding
such tables to the list of tables the query is going to open.
However, if we issued LOCK TABLES before that, we would get "table
was not locked" error trying to open such implicit tables.

The solution is to treat certain tables as MySQL system tables, like
we already do for mysql.proc.  Such tables may be opened for reading
at any moment regardless of any locks in effect.  The cost of this is
that system table may be locked for writing only together with other
system tables, it is disallowed to lock system tables for writing and
have any other lock on any other table.

After this patch the following tables are treated as MySQL system
tables:
  mysql.help_category
  mysql.help_keyword
  mysql.help_relation
  mysql.help_topic
  mysql.proc (it already was)
  mysql.time_zone
  mysql.time_zone_leap_second
  mysql.time_zone_name
  mysql.time_zone_transition
  mysql.time_zone_transition_type

These tables are now opened with open_system_tables_for_read() and
closed with close_system_tables(), or one table may be opened with
open_system_table_for_update() and closed with close_thread_tables()
(the latter is used for mysql.proc table, which is updated as part of
normal MySQL server operation).  These functions may be used when
some tables were opened and locked already.

NOTE: online update of time zone tables is not possible during
replication, because there's no time zone cache flush neither on LOCK
TABLES, nor on FLUSH TABLES, so the master may serve stale time zone
data from cache, while on slave updated data will be loaded from the
time zone tables.


mysql-test/r/help.result:
  Update result.
mysql-test/r/lock.result:
  Update result.
mysql-test/r/sp-error.result:
  Update result.
mysql-test/r/timezone2.result:
  Add result for bug#9953: CONVERT_TZ requires mysql.time_zone_name
  to be locked.
mysql-test/r/view.result:
  Update result: use table t3 rather than utilize MySQL system table.
mysql-test/t/help.test:
  Test that we can use HELP even under LOCK TABLES.
mysql-test/t/lock.test:
  Test LOCK TABLE on system tables.
mysql-test/t/timezone2.test:
  Add test case for bug#9953: CONVERT_TZ requires mysql.time_zone_name
  to be locked.
mysql-test/t/view.test:
  Update test: use table t3 rather that utilize MySQL system table.
sql/handler.h:
  Fix comment for 'count' parameter of check_if_locking_is_allowed().
  Add 'current' and 'system_count' parameters.
sql/item_create.cc:
  We no longer have LEX::add_time_zone_tables_to_query_tables().
sql/item_timefunc.cc:
  We no longer have LEX::time_zone_tables_used, so
  Item_func_convert_tz::fix_fields() became the same as base
  Item_date_func::fix_fields().
  
  my_tz_find() no longer takes table list, but takes THD pointer now.
sql/item_timefunc.h:
  Remove dead field and method.
sql/lock.cc:
  Pass values for 'current' and 'system_count' to
  check_if_locking_is_allowed().
sql/log_event.cc:
  We no longer have my_tz_find_with_opening_tz_tables(), its functions is
  performed by my_tz_find().
sql/mysql_priv.h:
  Add functions to work with MySQL system tables.
sql/set_var.cc:
  my_tz_find() no longer takes table list, but takes THD pointer now.
sql/sp.cc:
  Remove close_proc_table().  Use close_system_tables() instead.
  
  Use open_system_tables_for_read() and open_system_table_for_update().
sql/sp.h:
  Remove close_proc_table() declaration.
sql/sql_base.cc:
  Add implementation of open_system_tables_for_read(),
  close_system_tables(), open_system_table_for_update().
sql/sql_help.cc:
  Operate on MySQL system tables mysql.help_* with
  open_system_tables_for_read() and close_system_tables() to allow the
  usage of HELP statement under LOCK TABLES.
sql/sql_lex.cc:
  Remove LEX::time_zone_tables_used and
  LEX::add_time_zone_tables_to_query_tables() which are no longer used.
sql/sql_lex.h:
  Remove LEX::time_zone_tables_used and
  LEX::add_time_zone_tables_to_query_tables() which are no longer used.
sql/sql_parse.cc:
  Remove references to LEX::time_zone_tables_used and
  my_tz_check_n_skip_implicit_tables() which are no longer used.
sql/sql_show.cc:
  Use close_system_tables() instead of removed close_proc_table().
sql/sql_view.cc:
  LEX::time_zone_tables_used is no longer there.
sql/sql_yacc.yy:
  LEX::add_time_zone_tables_to_query_tables() is no longer there.
sql/table.cc:
  Add more tables that should be treated as MySQL system tables.
sql/share/errmsg.txt:
  Change the error message, as now we allow write-locking of several
  system tables if not mixed with ordinary tables.
sql/tztime.cc:
  Do not add time zone tables to the list of query tables in
  tz_init_table_list().
  
  Remove fake_time_zone_tables_list and my_tz_get_tables_list().
  
  In my_tz_init(), open mysql.time_zone_leap_second with
  simple_open_n_lock_tables(), but pass time zone name to my_tz_find(),
  which will open and close time zone tables as necessary.
  
  In tz_load_from_open_tables() do not call table->use_all_columns(), as
  this was already done in open_system_tables_for_read().
  
  my_tz_find() takes THD pointer instead of table list, and calls
  open_system_tables_for_read() and close_system_tables() as necessary.
  
  Remove my_tz_find_with_opening_tz_tables().
sql/tztime.h:
  Remove declarations of my_tz_get_table_list(),
  my_tz_find_with_opening_tz_tables(), fake_time_zone_tables_list,
  definition of my_tz_check_n_skip_implicit_tables().
  Update prototype for my_tz_find().
storage/csv/ha_tina.cc:
  Add new parameters to check_if_locking_is_allowed().
storage/csv/ha_tina.h:
  Add new parameters to check_if_locking_is_allowed().
storage/myisam/ha_myisam.cc:
  Add new parameters to check_if_locking_is_allowed().  In this
  function we count system tables.  If there are system tables, but
  there are also non-system tables, we report an error.
storage/myisam/ha_myisam.h:
  Add new parameters to check_if_locking_is_allowed().
2007-03-09 13:12:31 +03:00

298 lines
10 KiB
Text

drop table if exists t1, t2;
drop function if exists f1;
create table t1 (ts timestamp);
set time_zone='+00:00';
select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp())
0
insert into t1 (ts) values ('2003-03-30 02:30:00');
set time_zone='+10:30';
select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp())
-37800
insert into t1 (ts) values ('2003-03-30 02:30:00');
set time_zone='-10:00';
select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp())
36000
insert into t1 (ts) values ('2003-03-30 02:30:00');
select * from t1;
ts
2003-03-29 16:30:00
2003-03-29 06:00:00
2003-03-30 02:30:00
drop table t1;
select Name from mysql.time_zone_name where Name in
('UTC','Universal','MET','Europe/Moscow','leap/Europe/Moscow');
Name
Europe/Moscow
leap/Europe/Moscow
MET
Universal
UTC
create table t1 (i int, ts timestamp);
set time_zone='MET';
insert into t1 (i, ts) values
(unix_timestamp('2003-03-01 00:00:00'),'2003-03-01 00:00:00');
insert into t1 (i, ts) values
(unix_timestamp('2003-03-30 01:59:59'),'2003-03-30 01:59:59'),
(unix_timestamp('2003-03-30 02:30:00'),'2003-03-30 02:30:00'),
(unix_timestamp('2003-03-30 03:00:00'),'2003-03-30 03:00:00');
Warnings:
Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2
insert into t1 (i, ts) values
(unix_timestamp(20030330015959),20030330015959),
(unix_timestamp(20030330023000),20030330023000),
(unix_timestamp(20030330030000),20030330030000);
Warnings:
Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2
insert into t1 (i, ts) values
(unix_timestamp('2003-05-01 00:00:00'),'2003-05-01 00:00:00');
insert into t1 (i, ts) values
(unix_timestamp('2003-10-26 01:00:00'),'2003-10-26 01:00:00'),
(unix_timestamp('2003-10-26 02:00:00'),'2003-10-26 02:00:00'),
(unix_timestamp('2003-10-26 02:59:59'),'2003-10-26 02:59:59'),
(unix_timestamp('2003-10-26 04:00:00'),'2003-10-26 04:00:00'),
(unix_timestamp('2003-10-26 02:59:59'),'2003-10-26 02:59:59');
set time_zone='UTC';
select * from t1;
i ts
1046473200 2003-02-28 23:00:00
1048985999 2003-03-30 00:59:59
1048986000 2003-03-30 01:00:00
1048986000 2003-03-30 01:00:00
1048985999 2003-03-30 00:59:59
1048986000 2003-03-30 01:00:00
1048986000 2003-03-30 01:00:00
1051740000 2003-04-30 22:00:00
1067122800 2003-10-25 23:00:00
1067126400 2003-10-26 00:00:00
1067129999 2003-10-26 00:59:59
1067137200 2003-10-26 03:00:00
1067129999 2003-10-26 00:59:59
truncate table t1;
set time_zone='Europe/Moscow';
insert into t1 (i, ts) values
(unix_timestamp('2004-01-01 00:00:00'),'2004-01-01 00:00:00'),
(unix_timestamp('2004-03-28 02:30:00'),'2004-03-28 02:30:00'),
(unix_timestamp('2004-08-01 00:00:00'),'2003-08-01 00:00:00'),
(unix_timestamp('2004-10-31 02:30:00'),'2004-10-31 02:30:00');
Warnings:
Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2
select * from t1;
i ts
1072904400 2004-01-01 00:00:00
1080428400 2004-03-28 03:00:00
1091304000 2003-08-01 00:00:00
1099175400 2004-10-31 02:30:00
truncate table t1;
set time_zone='leap/Europe/Moscow';
insert into t1 (i, ts) values
(unix_timestamp('2004-01-01 00:00:00'),'2004-01-01 00:00:00'),
(unix_timestamp('2004-03-28 02:30:00'),'2004-03-28 02:30:00'),
(unix_timestamp('2004-08-01 00:00:00'),'2003-08-01 00:00:00'),
(unix_timestamp('2004-10-31 02:30:00'),'2004-10-31 02:30:00');
Warnings:
Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2
select * from t1;
i ts
1072904422 2004-01-01 00:00:00
1080428422 2004-03-28 03:00:00
1091304022 2003-08-01 00:00:00
1099175422 2004-10-31 02:30:00
truncate table t1;
insert into t1 (i, ts) values
(unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'),
(unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00');
select * from t1;
i ts
362793608 1981-07-01 03:59:59
362793610 1981-07-01 04:00:00
select from_unixtime(362793609);
from_unixtime(362793609)
1981-07-01 03:59:60
drop table t1;
create table t1 (ts timestamp);
set time_zone='UTC';
insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'),
('1970-01-01 00:00:00'),('1970-01-01 00:00:01'),
('2038-01-19 03:14:07'),('2038-01-19 03:14:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
Warning 1264 Out of range value for column 'ts' at row 6
select * from t1;
ts
0000-00-00 00:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 00:00:01
2038-01-19 03:14:07
0000-00-00 00:00:00
truncate table t1;
set time_zone='MET';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'),
('1970-01-01 01:00:00'),('1970-01-01 01:00:01'),
('2038-01-19 04:14:07'),('2038-01-19 04:14:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
Warning 1264 Out of range value for column 'ts' at row 6
select * from t1;
ts
0000-00-00 00:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 01:00:01
2038-01-19 04:14:07
0000-00-00 00:00:00
truncate table t1;
set time_zone='+01:30';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'),
('1970-01-01 01:30:00'),('1970-01-01 01:30:01'),
('2038-01-19 04:44:07'),('2038-01-19 04:44:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
Warning 1264 Out of range value for column 'ts' at row 6
select * from t1;
ts
0000-00-00 00:00:00
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 01:30:01
2038-01-19 04:44:07
0000-00-00 00:00:00
drop table t1;
show variables like 'time_zone';
Variable_name Value
time_zone +01:30
set time_zone = default;
show variables like 'time_zone';
Variable_name Value
time_zone SYSTEM
set time_zone= '0';
ERROR HY000: Unknown or incorrect time zone: '0'
set time_zone= '0:0';
ERROR HY000: Unknown or incorrect time zone: '0:0'
set time_zone= '-20:00';
ERROR HY000: Unknown or incorrect time zone: '-20:00'
set time_zone= '+20:00';
ERROR HY000: Unknown or incorrect time zone: '+20:00'
set time_zone= 'Some/Unknown/Time/Zone';
ERROR HY000: Unknown or incorrect time zone: 'Some/Unknown/Time/Zone'
select convert_tz(now(),'UTC', 'Universal') = now();
convert_tz(now(),'UTC', 'Universal') = now()
1
select convert_tz(now(),'utc', 'UTC') = now();
convert_tz(now(),'utc', 'UTC') = now()
1
select convert_tz('1917-11-07 12:00:00', 'MET', 'UTC');
convert_tz('1917-11-07 12:00:00', 'MET', 'UTC')
1917-11-07 12:00:00
select convert_tz('1970-01-01 01:00:00', 'MET', 'UTC');
convert_tz('1970-01-01 01:00:00', 'MET', 'UTC')
1970-01-01 01:00:00
select convert_tz('1970-01-01 01:00:01', 'MET', 'UTC');
convert_tz('1970-01-01 01:00:01', 'MET', 'UTC')
1970-01-01 00:00:01
select convert_tz('2003-03-01 00:00:00', 'MET', 'UTC');
convert_tz('2003-03-01 00:00:00', 'MET', 'UTC')
2003-02-28 23:00:00
select convert_tz('2003-03-30 01:59:59', 'MET', 'UTC');
convert_tz('2003-03-30 01:59:59', 'MET', 'UTC')
2003-03-30 00:59:59
select convert_tz('2003-03-30 02:30:00', 'MET', 'UTC');
convert_tz('2003-03-30 02:30:00', 'MET', 'UTC')
2003-03-30 01:00:00
select convert_tz('2003-03-30 03:00:00', 'MET', 'UTC');
convert_tz('2003-03-30 03:00:00', 'MET', 'UTC')
2003-03-30 01:00:00
select convert_tz('2003-05-01 00:00:00', 'MET', 'UTC');
convert_tz('2003-05-01 00:00:00', 'MET', 'UTC')
2003-04-30 22:00:00
select convert_tz('2003-10-26 01:00:00', 'MET', 'UTC');
convert_tz('2003-10-26 01:00:00', 'MET', 'UTC')
2003-10-25 23:00:00
select convert_tz('2003-10-26 02:00:00', 'MET', 'UTC');
convert_tz('2003-10-26 02:00:00', 'MET', 'UTC')
2003-10-26 00:00:00
select convert_tz('2003-10-26 02:59:59', 'MET', 'UTC');
convert_tz('2003-10-26 02:59:59', 'MET', 'UTC')
2003-10-26 00:59:59
select convert_tz('2003-10-26 04:00:00', 'MET', 'UTC');
convert_tz('2003-10-26 04:00:00', 'MET', 'UTC')
2003-10-26 03:00:00
select convert_tz('2038-01-19 04:14:07', 'MET', 'UTC');
convert_tz('2038-01-19 04:14:07', 'MET', 'UTC')
2038-01-19 03:14:07
select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC');
convert_tz('2038-01-19 04:14:08', 'MET', 'UTC')
2038-01-19 04:14:08
select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC');
convert_tz('2103-01-01 04:00:00', 'MET', 'UTC')
2103-01-01 04:00:00
create table t1 (tz varchar(3));
insert into t1 (tz) values ('MET'), ('UTC');
select tz, convert_tz('2003-12-31 00:00:00',tz,'UTC'), convert_tz('2003-12-31 00:00:00','UTC',tz) from t1 order by tz;
tz convert_tz('2003-12-31 00:00:00',tz,'UTC') convert_tz('2003-12-31 00:00:00','UTC',tz)
MET 2003-12-30 23:00:00 2003-12-31 01:00:00
UTC 2003-12-31 00:00:00 2003-12-31 00:00:00
drop table t1;
select convert_tz('2003-12-31 04:00:00', NULL, 'UTC');
convert_tz('2003-12-31 04:00:00', NULL, 'UTC')
NULL
select convert_tz('2003-12-31 04:00:00', 'SomeNotExistingTimeZone', 'UTC');
convert_tz('2003-12-31 04:00:00', 'SomeNotExistingTimeZone', 'UTC')
NULL
select convert_tz('2003-12-31 04:00:00', 'MET', 'SomeNotExistingTimeZone');
convert_tz('2003-12-31 04:00:00', 'MET', 'SomeNotExistingTimeZone')
NULL
select convert_tz('2003-12-31 04:00:00', 'MET', NULL);
convert_tz('2003-12-31 04:00:00', 'MET', NULL)
NULL
select convert_tz( NULL, 'MET', 'UTC');
convert_tz( NULL, 'MET', 'UTC')
NULL
create table t1 (ts timestamp);
set timestamp=1000000000;
insert into t1 (ts) values (now());
select convert_tz(ts, @@time_zone, 'Japan') from t1;
convert_tz(ts, @@time_zone, 'Japan')
2001-09-09 10:46:40
drop table t1;
select convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) from (select 'UTC' as custTimeZone) as tmp;
convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone)
2005-01-14 17:00:00
create table t1 select convert_tz(NULL, NULL, NULL);
select * from t1;
convert_tz(NULL, NULL, NULL)
NULL
drop table t1;
SET GLOBAL log_bin_trust_function_creators = 1;
create table t1 (ldt datetime, udt datetime);
create function f1(i datetime) returns datetime
return convert_tz(i, 'UTC', 'Europe/Moscow');
create trigger t1_bi before insert on t1 for each row
set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
insert into t1 (ldt) values ('2006-04-19 16:30:00');
select * from t1;
ldt udt
2006-04-19 16:30:00 2006-04-19 12:30:00
select ldt, f1(udt) as ldt2 from t1;
ldt ldt2
2006-04-19 16:30:00 2006-04-19 16:30:00
drop table t1;
drop function f1;
SET GLOBAL log_bin_trust_function_creators = 0;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (t TIMESTAMP);
INSERT INTO t1 VALUES (NULL), (NULL);
LOCK TABLES t1 WRITE;
SELECT CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL;
CONVERT_TZ(NOW(), 'UTC', 'Europe/Moscow') IS NULL
0
UPDATE t1 SET t = CONVERT_TZ(t, 'UTC', 'Europe/Moscow');
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests