Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
a6bd0eb5
Commit
a6bd0eb5
authored
Aug 10, 2004
by
dlenev@brandersnatch.localdomain
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into brandersnatch.localdomain:/home/dlenev/src/mysql-4.1-bg4508
parents
350ab6b6
f49d4f53
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
315 additions
and
199 deletions
+315
-199
mysql-test/r/timezone2.result
mysql-test/r/timezone2.result
+7
-0
mysql-test/t/timezone2.test
mysql-test/t/timezone2.test
+12
-0
scripts/mysql_create_system_tables.sh
scripts/mysql_create_system_tables.sh
+7
-4
sql/item_create.cc
sql/item_create.cc
+0
-5
sql/item_create.h
sql/item_create.h
+0
-1
sql/item_timefunc.cc
sql/item_timefunc.cc
+19
-9
sql/item_timefunc.h
sql/item_timefunc.h
+15
-1
sql/lex.h
sql/lex.h
+1
-1
sql/mysql_priv.h
sql/mysql_priv.h
+0
-1
sql/set_var.cc
sql/set_var.cc
+5
-3
sql/set_var.h
sql/set_var.h
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+16
-1
sql/sql_lex.cc
sql/sql_lex.cc
+36
-1
sql/sql_lex.h
sql/sql_lex.h
+7
-0
sql/sql_parse.cc
sql/sql_parse.cc
+3
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+2
-1
sql/sql_select.cc
sql/sql_select.cc
+0
-33
sql/sql_yacc.yy
sql/sql_yacc.yy
+12
-0
sql/tztime.cc
sql/tztime.cc
+170
-136
sql/tztime.h
sql/tztime.h
+2
-1
No files found.
mysql-test/r/timezone2.result
View file @
a6bd0eb5
...
...
@@ -244,3 +244,10 @@ 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;
mysql-test/t/timezone2.test
View file @
a6bd0eb5
...
...
@@ -187,3 +187,15 @@ select convert_tz('2003-12-31 04:00:00', 'SomeNotExistingTimeZone', 'UTC');
select
convert_tz
(
'2003-12-31 04:00:00'
,
'MET'
,
'SomeNotExistingTimeZone'
);
select
convert_tz
(
'2003-12-31 04:00:00'
,
'MET'
,
NULL
);
select
convert_tz
(
NULL
,
'MET'
,
'UTC'
);
#
# Test for bug #4508 "CONVERT_TZ() function with new time zone as param
# crashes server." (Was caused by improperly worked mechanism of time zone
# dynamical loading).
#
create
table
t1
(
ts
timestamp
);
set
timestamp
=
1000000000
;
insert
into
t1
(
ts
)
values
(
now
());
select
convert_tz
(
ts
,
@@
time_zone
,
'Japan'
)
from
t1
;
drop
table
t1
;
scripts/mysql_create_system_tables.sh
View file @
a6bd0eb5
...
...
@@ -307,7 +307,8 @@ then
then
i_tzn
=
"
$i_tzn
INSERT INTO time_zone_name (Name, Time_Zone_id) VALUES"
i_tzn
=
"
$i_tzn
('MET', 1), ('UTC', 2), ('Universal', 2), "
i_tzn
=
"
$i_tzn
('Europe/Moscow',3), ('leap/Europe/Moscow',4);"
i_tzn
=
"
$i_tzn
('Europe/Moscow',3), ('leap/Europe/Moscow',4), "
i_tzn
=
"
$i_tzn
('Japan', 5);"
fi
fi
...
...
@@ -327,7 +328,7 @@ then
if
test
"
$1
"
=
"test"
then
i_tz
=
"
$i_tz
INSERT INTO time_zone (Time_zone_id, Use_leap_seconds)"
i_tz
=
"
$i_tz
VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y');"
i_tz
=
"
$i_tz
VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y')
, (5,'N')
;"
fi
fi
...
...
@@ -546,7 +547,8 @@ then
i_tzt
=
"
$i_tzt
,(4, 2045689222, 8) ,(4, 2058390022, 9)"
i_tzt
=
"
$i_tzt
,(4, 2077138822, 8) ,(4, 2090444422, 9)"
i_tzt
=
"
$i_tzt
,(4, 2108588422, 8) ,(4, 2121894022, 9)"
i_tzt
=
"
$i_tzt
,(4, 2140038022, 8);"
i_tzt
=
"
$i_tzt
,(4, 2140038022, 8)"
i_tzt
=
"
$i_tzt
,(5, -1009875600, 1);"
fi
fi
...
...
@@ -584,7 +586,8 @@ then
i_tztt
=
"
$i_tztt
,(4, 4, 10800, 0, 'MSK') ,(4, 5, 14400, 1, 'MSD')"
i_tztt
=
"
$i_tztt
,(4, 6, 18000, 1, 'MSD') ,(4, 7, 7200, 0, 'EET')"
i_tztt
=
"
$i_tztt
,(4, 8, 10800, 0, 'MSK') ,(4, 9, 14400, 1, 'MSD')"
i_tztt
=
"
$i_tztt
,(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET');"
i_tztt
=
"
$i_tztt
,(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET')"
i_tztt
=
"
$i_tztt
,(5, 0, 32400, 0, 'CJT') ,(5, 1, 32400, 0, 'JST');"
fi
fi
...
...
sql/item_create.cc
View file @
a6bd0eb5
...
...
@@ -89,11 +89,6 @@ Item *create_func_conv(Item* a, Item *b, Item *c)
return
new
Item_func_conv
(
a
,
b
,
c
);
}
Item
*
create_func_convert_tz
(
Item
*
a
,
Item
*
b
,
Item
*
c
)
{
return
new
Item_func_convert_tz
(
a
,
b
,
c
);
}
Item
*
create_func_cos
(
Item
*
a
)
{
return
new
Item_func_cos
(
a
);
...
...
sql/item_create.h
View file @
a6bd0eb5
...
...
@@ -31,7 +31,6 @@ Item *create_func_char_length(Item* a);
Item
*
create_func_cast
(
Item
*
a
,
Cast_target
cast_type
,
int
len
,
CHARSET_INFO
*
cs
);
Item
*
create_func_connection_id
(
void
);
Item
*
create_func_conv
(
Item
*
a
,
Item
*
b
,
Item
*
c
);
Item
*
create_func_convert_tz
(
Item
*
a
,
Item
*
b
,
Item
*
c
);
Item
*
create_func_cos
(
Item
*
a
);
Item
*
create_func_cot
(
Item
*
a
);
Item
*
create_func_crc32
(
Item
*
a
);
...
...
sql/item_timefunc.cc
View file @
a6bd0eb5
...
...
@@ -1649,18 +1649,28 @@ bool Item_func_from_unixtime::get_date(TIME *ltime,
void
Item_func_convert_tz
::
fix_length_and_dec
()
{
String
str
;
thd
=
current_thd
;
collation
.
set
(
&
my_charset_bin
);
decimals
=
0
;
max_length
=
MAX_DATETIME_WIDTH
*
MY_CHARSET_BIN_MB_MAXLEN
;
}
bool
Item_func_convert_tz
::
fix_fields
(
THD
*
thd_arg
,
TABLE_LIST
*
tables_arg
,
Item
**
ref
)
{
String
str
;
if
(
Item_date_func
::
fix_fields
(
thd_arg
,
tables_arg
,
ref
))
return
1
;
tz_tables
=
thd_arg
->
lex
->
time_zone_tables_used
;
if
(
args
[
1
]
->
const_item
())
from_tz
=
my_tz_find
(
thd
,
args
[
1
]
->
val_str
(
&
str
)
);
from_tz
=
my_tz_find
(
args
[
1
]
->
val_str
(
&
str
),
tz_tables
);
if
(
args
[
2
]
->
const_item
())
to_tz
=
my_tz_find
(
thd
,
args
[
2
]
->
val_str
(
&
str
));
to_tz
=
my_tz_find
(
args
[
2
]
->
val_str
(
&
str
),
tz_tables
);
return
0
;
}
...
...
@@ -1701,10 +1711,10 @@ bool Item_func_convert_tz::get_date(TIME *ltime,
String
str
;
if
(
!
args
[
1
]
->
const_item
())
from_tz
=
my_tz_find
(
thd
,
args
[
1
]
->
val_str
(
&
str
)
);
from_tz
=
my_tz_find
(
args
[
1
]
->
val_str
(
&
str
),
tz_tables
);
if
(
!
args
[
2
]
->
const_item
())
to_tz
=
my_tz_find
(
thd
,
args
[
2
]
->
val_str
(
&
str
)
);
to_tz
=
my_tz_find
(
args
[
2
]
->
val_str
(
&
str
),
tz_tables
);
if
(
from_tz
==
0
||
to_tz
==
0
||
get_arg0_date
(
ltime
,
0
))
{
...
...
sql/item_timefunc.h
View file @
a6bd0eb5
...
...
@@ -531,9 +531,22 @@ class Item_func_from_unixtime :public Item_date_func
*/
class
Time_zone
;
/*
This class represents CONVERT_TZ() function.
The important fact about this function that it is handled in special way.
When such function is met in expression time_zone system tables are added
to global list of tables to open, so later those already opened and locked
tables can be used during this function calculation for loading time zone
descriptions.
*/
class
Item_func_convert_tz
:
public
Item_date_func
{
THD
*
thd
;
/* Cached pointer to list of pre-opened time zone tables. */
TABLE_LIST
*
tz_tables
;
/*
If time zone parameters are constants we are caching objects that
represent them.
*/
Time_zone
*
from_tz
,
*
to_tz
;
public:
Item_func_convert_tz
(
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
...
...
@@ -542,6 +555,7 @@ class Item_func_convert_tz :public Item_date_func
double
val
()
{
return
(
double
)
val_int
();
}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"convert_tz"
;
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
);
void
fix_length_and_dec
();
bool
get_date
(
TIME
*
res
,
uint
fuzzy_date
);
};
...
...
sql/lex.h
View file @
a6bd0eb5
...
...
@@ -499,7 +499,7 @@ static SYMBOL sql_functions[] = {
{
"CONNECTION_ID"
,
F_SYM
(
FUNC_ARG0
),
0
,
CREATE_FUNC
(
create_func_connection_id
)},
{
"CONTAINS"
,
F_SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC_GEOM
(
create_func_contains
)},
{
"CONV"
,
F_SYM
(
FUNC_ARG3
),
0
,
CREATE_FUNC
(
create_func_conv
)},
{
"CONVERT_TZ"
,
F_SYM
(
FUNC_ARG3
),
0
,
CREATE_FUNC
(
create_func_convert_tz
)},
{
"CONVERT_TZ"
,
SYM
(
CONVERT_TZ_SYM
)},
{
"COUNT"
,
SYM
(
COUNT_SYM
)},
{
"COS"
,
F_SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_cos
)},
{
"COT"
,
F_SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_cot
)},
...
...
sql/mysql_priv.h
View file @
a6bd0eb5
...
...
@@ -500,7 +500,6 @@ int mysql_select(THD *thd, Item ***rref_pointer_array,
select_result
*
result
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
);
void
free_underlaid_joins
(
THD
*
thd
,
SELECT_LEX
*
select
);
void
fix_tables_pointers
(
SELECT_LEX
*
select_lex
);
int
mysql_explain_union
(
THD
*
thd
,
SELECT_LEX_UNIT
*
unit
,
select_result
*
result
);
int
mysql_explain_select
(
THD
*
thd
,
SELECT_LEX
*
sl
,
char
const
*
type
,
...
...
sql/set_var.cc
View file @
a6bd0eb5
...
...
@@ -2373,7 +2373,8 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
}
#endif
if
(
!
(
var
->
save_result
.
time_zone
=
my_tz_find
(
thd
,
res
)))
if
(
!
(
var
->
save_result
.
time_zone
=
my_tz_find
(
res
,
thd
->
lex
->
time_zone_tables_used
)))
{
my_error
(
ER_UNKNOWN_TIME_ZONE
,
MYF
(
0
),
res
?
res
->
c_ptr
()
:
"NULL"
);
return
1
;
...
...
@@ -2418,7 +2419,8 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
if
(
default_tz_name
)
{
String
str
(
default_tz_name
,
&
my_charset_latin1
);
global_system_variables
.
time_zone
=
my_tz_find
(
thd
,
&
str
);
global_system_variables
.
time_zone
=
my_tz_find
(
&
str
,
thd
->
lex
->
time_zone_tables_used
);
}
else
global_system_variables
.
time_zone
=
my_tz_SYSTEM
;
...
...
sql/set_var.h
View file @
a6bd0eb5
...
...
@@ -908,6 +908,7 @@ ulong fix_sql_mode(ulong sql_mode);
extern
sys_var_str
sys_charset_system
;
extern
sys_var_str
sys_init_connect
;
extern
sys_var_str
sys_init_slave
;
extern
sys_var_thd_time_zone
sys_time_zone
;
CHARSET_INFO
*
get_old_charset_by_name
(
const
char
*
old_name
);
gptr
find_named
(
I_List
<
NAMED_LIST
>
*
list
,
const
char
*
name
,
uint
length
,
NAMED_LIST
**
found
);
...
...
sql/sql_base.cc
View file @
a6bd0eb5
...
...
@@ -1670,7 +1670,22 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
uint
counter
;
if
(
open_tables
(
thd
,
tables
,
&
counter
)
||
lock_tables
(
thd
,
tables
,
counter
))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
fix_tables_pointers
(
thd
->
lex
->
all_selects_list
);
/*
Let us propagate pointers to open tables from global table list
to table lists in particular selects if needed.
*/
if
(
thd
->
lex
->
all_selects_list
->
next_select_in_list
()
||
thd
->
lex
->
time_zone_tables_used
)
{
for
(
SELECT_LEX
*
sl
=
thd
->
lex
->
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
cursor
;
cursor
=
cursor
->
next
)
if
(
cursor
->
table_list
)
cursor
->
table
=
cursor
->
table_list
->
table
;
}
DBUG_RETURN
(
mysql_handle_derived
(
thd
->
lex
));
}
...
...
sql/sql_lex.cc
View file @
a6bd0eb5
...
...
@@ -22,6 +22,16 @@
#include <m_ctype.h>
#include <hash.h>
/*
Fake table list object, pointer to which is used as special value for
st_lex::time_zone_tables_used indicating that we implicitly use time
zone tables in this statement but real table list was not yet created.
Pointer to it is also returned by my_tz_get_tables_list() as indication
of transient error;
*/
TABLE_LIST
fake_time_zone_tables_list
;
/* Macros to look like lex */
#define yyGet() *(lex->ptr++)
...
...
@@ -1292,7 +1302,32 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex,
TABLE_LIST
**
result_arg
)
{
*
result_arg
=
0
;
res
=
create_total_list_n_last_return
(
thd_arg
,
lex
,
&
result_arg
);
if
(
!
(
res
=
create_total_list_n_last_return
(
thd_arg
,
lex
,
&
result_arg
)))
{
/*
If time zone tables were used implicitly in statement we should add
them to global table list.
*/
if
(
lex
->
time_zone_tables_used
)
{
/*
Altough we are modifying lex data, it won't raise any problem in
case when this lex belongs to some prepared statement or stored
procedure: such modification does not change any invariants imposed
by requirement to reuse the same lex for multiple executions.
*/
if
((
lex
->
time_zone_tables_used
=
my_tz_get_table_list
(
thd
))
!=
&
fake_time_zone_tables_list
)
{
*
result_arg
=
lex
->
time_zone_tables_used
;
}
else
{
send_error
(
thd
,
0
);
res
=
1
;
}
}
}
return
res
;
}
...
...
sql/sql_lex.h
View file @
a6bd0eb5
...
...
@@ -633,6 +633,12 @@ typedef struct st_lex
bool
prepared_stmt_code_is_varref
;
/* Names of user variables holding parameters (in EXECUTE) */
List
<
LEX_STRING
>
prepared_stmt_params
;
/*
If points to fake_time_zone_tables_list indicates that time zone
tables are implicitly used by statement, also is used for holding
list of those tables after they are opened.
*/
TABLE_LIST
*
time_zone_tables_used
;
st_lex
()
{}
inline
void
uncacheable
(
uint8
cause
)
{
...
...
@@ -661,6 +667,7 @@ typedef struct st_lex
TABLE_LIST
*
local_first
);
}
LEX
;
extern
TABLE_LIST
fake_time_zone_tables_list
;
void
lex_init
(
void
);
void
lex_free
(
void
);
...
...
sql/sql_parse.cc
View file @
a6bd0eb5
...
...
@@ -1897,7 +1897,8 @@ mysql_execute_command(THD *thd)
#endif
}
#endif
/* !HAVE_REPLICATION */
if
(
&
lex
->
select_lex
!=
lex
->
all_selects_list
&&
if
((
&
lex
->
select_lex
!=
lex
->
all_selects_list
||
lex
->
time_zone_tables_used
)
&&
lex
->
unit
.
create_total_list
(
thd
,
lex
,
&
tables
))
DBUG_VOID_RETURN
;
...
...
@@ -3875,6 +3876,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length)
lex
->
lock_option
=
TL_READ
;
lex
->
found_colon
=
0
;
lex
->
safe_to_cache_query
=
1
;
lex
->
time_zone_tables_used
=
0
;
lex_start
(
thd
,
buf
,
length
);
thd
->
select_number
=
lex
->
select_lex
.
select_number
=
1
;
thd
->
free_list
=
0
;
...
...
sql/sql_prepare.cc
View file @
a6bd0eb5
...
...
@@ -1407,7 +1407,8 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
DBUG_PRINT
(
"enter"
,(
"command: %d, param_count: %ld"
,
sql_command
,
stmt
->
param_count
));
if
(
select_lex
!=
lex
->
all_selects_list
&&
if
((
&
lex
->
select_lex
!=
lex
->
all_selects_list
||
lex
->
time_zone_tables_used
)
&&
lex
->
unit
.
create_total_list
(
thd
,
lex
,
&
tables
))
DBUG_RETURN
(
1
);
...
...
sql/sql_select.cc
View file @
a6bd0eb5
...
...
@@ -213,39 +213,6 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
}
void
relink_tables
(
SELECT_LEX
*
select_lex
)
{
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
cursor
;
cursor
=
cursor
->
next
)
if
(
cursor
->
table_list
)
cursor
->
table
=
cursor
->
table_list
->
table
;
}
void
fix_tables_pointers
(
SELECT_LEX
*
select_lex
)
{
if
(
select_lex
->
next_select_in_list
())
{
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
for
(
SELECT_LEX
*
sl
=
select_lex
;
sl
;
sl
=
sl
->
next_select_in_list
())
relink_tables
(
sl
);
}
}
void
fix_tables_pointers
(
SELECT_LEX_UNIT
*
unit
)
{
for
(
SELECT_LEX
*
sl
=
unit
->
first_select
();
sl
;
sl
=
sl
->
next_select
())
{
relink_tables
(
sl
);
for
(
SELECT_LEX_UNIT
*
un
=
sl
->
first_inner_unit
();
un
;
un
=
un
->
next_unit
())
fix_tables_pointers
(
un
);
}
}
/*
Function to setup clauses without sum functions
*/
...
...
sql/sql_yacc.yy
View file @
a6bd0eb5
...
...
@@ -463,6 +463,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CASE_SYM
%token CONCAT
%token CONCAT_WS
%token CONVERT_TZ_SYM
%token CURDATE
%token CURTIME
%token DATABASE
...
...
@@ -2825,6 +2826,11 @@ simple_expr:
{ $$= new Item_func_concat(* $3); }
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
{
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
$$= new Item_func_convert_tz($3, $5, $7);
}
| CURDATE optional_braces
{ $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; }
| CURTIME optional_braces
...
...
@@ -5308,6 +5314,12 @@ internal_variable_name:
$$.var= tmp;
$$.base_name.str=0;
$$.base_name.length=0;
/*
If this is time_zone variable we should open time zone
describing tables
*/
if (tmp == &sys_time_zone)
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
}
| ident '.' ident
{
...
...
sql/tztime.cc
View file @
a6bd0eb5
...
...
@@ -1359,6 +1359,13 @@ static bool tz_inited= 0;
static
uint
tz_leapcnt
=
0
;
static
LS_INFO
*
tz_lsis
=
0
;
/*
Shows whenever we have found time zone tables during start-up.
Used for avoiding of putting those tables to global table list
for queries that use time zone info.
*/
static
bool
time_zone_tables_exist
=
1
;
typedef
struct
st_tz_names_entry
:
public
Sql_alloc
{
...
...
@@ -1387,6 +1394,68 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
}
/*
Prepare table list with time zone related tables from preallocated array.
SYNOPSIS
tz_init_table_list()
tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects.
DESCRIPTION
This function prepares list of TABLE_LIST objects which can be used
for opening of time zone tables from preallocated array.
*/
void
tz_init_table_list
(
TABLE_LIST
*
tz_tabs
)
{
bzero
(
tz_tabs
,
sizeof
(
TABLE_LIST
)
*
4
);
tz_tabs
[
0
].
alias
=
tz_tabs
[
0
].
real_name
=
(
char
*
)
"time_zone_name"
;
tz_tabs
[
1
].
alias
=
tz_tabs
[
1
].
real_name
=
(
char
*
)
"time_zone"
;
tz_tabs
[
2
].
alias
=
tz_tabs
[
2
].
real_name
=
(
char
*
)
"time_zone_transition_type"
;
tz_tabs
[
3
].
alias
=
tz_tabs
[
3
].
real_name
=
(
char
*
)
"time_zone_transition"
;
tz_tabs
[
0
].
next
=
tz_tabs
+
1
;
tz_tabs
[
1
].
next
=
tz_tabs
+
2
;
tz_tabs
[
2
].
next
=
tz_tabs
+
3
;
tz_tabs
[
0
].
lock_type
=
tz_tabs
[
1
].
lock_type
=
tz_tabs
[
2
].
lock_type
=
tz_tabs
[
3
].
lock_type
=
TL_READ
;
tz_tabs
[
0
].
db
=
tz_tabs
[
1
].
db
=
tz_tabs
[
2
].
db
=
tz_tabs
[
3
].
db
=
(
char
*
)
"mysql"
;
}
/*
Create table list with time zone related tables.
SYNOPSIS
my_tz_get_table_list()
thd - current thread object
DESCRIPTION
This function creates list of TABLE_LIST objects allocated in thd's
memroot, which can be used for opening of time zone tables.
RETURN VALUES
Returns pointer to first TABLE_LIST object, (could be 0 if time zone
tables don't exist) and &fake_time_zone_tables_list in case of error.
*/
TABLE_LIST
*
my_tz_get_table_list
(
THD
*
thd
)
{
TABLE_LIST
*
tz_tabs
;
if
(
!
time_zone_tables_exist
)
return
0
;
if
(
!
(
tz_tabs
=
(
TABLE_LIST
*
)
thd
->
alloc
(
sizeof
(
TABLE_LIST
)
*
4
)))
return
&
fake_time_zone_tables_list
;
tz_init_table_list
(
tz_tabs
);
return
tz_tabs
;
}
/*
Initialize time zone support infrastructure.
...
...
@@ -1399,13 +1468,13 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
DESCRIPTION
This function will init memory structures needed for time zone support,
it will register mandatory SYSTEM time zone in them. It will try to open
mysql.time_zone
_leap_seconds table and and load information which further
will be shared among all time zones loaded. It will also try to load
information about default time zone. If system tables with time zone
descriptions don't exist it won't fail (unless default_tzname is time zone
from tables). If bootstrap parameter is true then this routine assumes tha
t
we are in bootstrap mode and won't load time zone descriptions unless some
one
specifies default time zone
which is supposedly stored in those tables.
mysql.time_zone
* tables and load information about default time zone and
information which further will be shared among all time zones loaded.
If system tables with time zone descriptions don't exist it won't fail
(unless default_tzname is time zone from tables). If bootstrap parameter
is true then this routine assumes that we are in bootstrap mode and won'
t
load time zone descriptions unless someone specifies default time z
one
which is supposedly stored in those tables.
It'll also set default time zone if it is specified.
RETURN VALUES
...
...
@@ -1416,14 +1485,13 @@ my_bool
my_tz_init
(
THD
*
org_thd
,
const
char
*
default_tzname
,
my_bool
bootstrap
)
{
THD
*
thd
;
TABLE_LIST
tables
;
TABLE_LIST
*
tables
=
0
;
TABLE_LIST
tables_buff
[
5
];
TABLE
*
table
;
TABLE
*
lock_ptr
;
MYSQL_LOCK
*
lock
;
TZ_NAMES_ENTRY
*
tmp_tzname
;
my_bool
return_val
=
1
;
int
res
;
uint
not_used
;
uint
counter
;
DBUG_ENTER
(
"my_tz_init"
);
/*
...
...
@@ -1468,7 +1536,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
if
(
bootstrap
)
{
/* If we are in bootstrap mode we should not load time zone tables */
return_val
=
0
;
return_val
=
time_zone_tables_exist
=
0
;
goto
end_with_setting_default_tz
;
}
...
...
@@ -1480,28 +1548,25 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
thd
->
db
=
my_strdup
(
"mysql"
,
MYF
(
0
));
thd
->
db_length
=
5
;
// Safety
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
alias
=
tables
.
real_name
=
(
char
*
)
"time_zone_leap_second"
;
tables
.
lock_type
=
TL_READ
;
tables
.
db
=
thd
->
db
;
if
(
open_tables
(
thd
,
&
tables
,
&
not_used
))
{
sql_print_error
(
"Warning: Can't open time zone table: %s "
bzero
((
char
*
)
&
tables_buff
,
sizeof
(
TABLE_LIST
));
tables_buff
[
0
].
alias
=
tables_buff
[
0
].
real_name
=
(
char
*
)
"time_zone_leap_second"
;
tables_buff
[
0
].
lock_type
=
TL_READ
;
tables_buff
[
0
].
db
=
thd
->
db
;
tables_buff
[
0
].
next
=
tables_buff
+
1
;
/* Fill TABLE_LIST for rest of the time zone describing tables */
tz_init_table_list
(
tables_buff
+
1
);
if
(
open_tables
(
thd
,
tables_buff
,
&
counter
)
||
lock_tables
(
thd
,
tables_buff
,
counter
))
{
sql_print_error
(
"Warning: Can't open and lock time zone table: %s "
"trying to live without them"
,
thd
->
net
.
last_error
);
/* We will try emulate that everything is ok */
return_val
=
0
;
return_val
=
time_zone_tables_exist
=
0
;
goto
end_with_setting_default_tz
;
}
lock_ptr
=
tables
.
table
;
if
(
!
(
lock
=
mysql_lock_tables
(
thd
,
&
lock_ptr
,
1
)))
{
sql_print_error
(
"Fatal error: Can't lock time zone table: %s"
,
thd
->
net
.
last_error
);
goto
end_with_close
;
}
tables
=
tables_buff
+
1
;
/*
Now we are going to load leap seconds descriptions that are shared
...
...
@@ -1514,11 +1579,16 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
{
sql_print_error
(
"Fatal error: Out of memory while loading "
"mysql.time_zone_leap_second table"
);
goto
end_with_
unlock
;
goto
end_with_
close
;
}
table
=
tables
.
table
;
table
->
file
->
ha_index_init
(
0
);
table
=
tables_buff
[
0
].
table
;
/*
It is OK to ignore ha_index_init()/ha_index_end() return values since
mysql.time_zone* tables are MyISAM and these operations always succeed
for MyISAM.
*/
(
void
)
table
->
file
->
ha_index_init
(
0
);
tz_leapcnt
=
0
;
res
=
table
->
file
->
index_first
(
table
->
record
[
0
]);
...
...
@@ -1530,7 +1600,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
sql_print_error
(
"Fatal error: While loading mysql.time_zone_leap_second"
" table: too much leaps"
);
table
->
file
->
ha_index_end
();
goto
end_with_
unlock
;
goto
end_with_
close
;
}
tz_lsis
[
tz_leapcnt
].
ls_trans
=
(
my_time_t
)
table
->
field
[
0
]
->
val_int
();
...
...
@@ -1546,13 +1616,13 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
res
=
table
->
file
->
index_next
(
table
->
record
[
0
]);
}
table
->
file
->
ha_index_end
();
(
void
)
table
->
file
->
ha_index_end
();
if
(
res
!=
HA_ERR_END_OF_FILE
)
{
sql_print_error
(
"Fatal error: Error while loading "
"mysql.time_zone_leap_second table"
);
goto
end_with_
unlock
;
goto
end_with_
close
;
}
/*
...
...
@@ -1562,19 +1632,12 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
return_val
=
0
;
end_with_unlock:
mysql_unlock_tables
(
thd
,
lock
);
end_with_close:
close_thread_tables
(
thd
);
thd
->
version
--
;
/* Force close to free memory */
end_with_setting_default_tz:
/* If
not an error and
have default time zone try to load it */
if
(
!
return_val
&&
default_tzname
)
/* If
we
have default time zone try to load it */
if
(
default_tzname
)
{
String
tzname
(
default_tzname
,
&
my_charset_latin1
);
if
(
!
(
global_system_variables
.
time_zone
=
my_tz_find
(
thd
,
&
tzname
)))
if
(
!
(
global_system_variables
.
time_zone
=
my_tz_find
(
&
tzname
,
tables
)))
{
sql_print_error
(
"Fatal error: Illegal or unknown default time zone '%s'"
,
default_tzname
);
...
...
@@ -1582,6 +1645,10 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
}
}
end_with_close:
thd
->
version
--
;
/* Force close to free memory */
close_thread_tables
(
thd
);
end_with_cleanup:
/* if there were error free time zone describing structs */
...
...
@@ -1625,29 +1692,27 @@ void my_tz_free()
Load time zone description from system tables.
SYNOPSIS
tz_load_from_db()
thd - current thread object
tz_load_from_open_tables()
tz_name - name of time zone that should be loaded.
tz_tables - list of tables from which time zone description
should be loaded
DESCRIPTION
This function will try to open system tables describing time zones
and to load information about time zone specified. It will also update
information in hash used for time zones lookup.
This function will try to load information about time zone specified
from the list of the already opened and locked tables (first table in
tz_tables should be time_zone_name, next time_zone, then
time_zone_transition_type and time_zone_transition should be last).
It will also update information in hash used for time zones lookup.
RETURN VALUES
Returns pointer to newly created Time_zone object or 0 in case of error.
*/
static
Time_zone
*
tz_load_from_
db
(
THD
*
thd
,
const
String
*
tz_name
)
tz_load_from_
open_tables
(
const
String
*
tz_name
,
TABLE_LIST
*
tz_tables
)
{
TABLE_LIST
tables
[
4
];
TABLE
*
table
=
0
;
TABLE
*
lock_ptr
[
4
];
MYSQL_LOCK
*
lock
;
char
system_db_name
[]
=
"mysql"
;
char
*
db_save
;
uint
db_length_save
;
TIME_ZONE_INFO
*
tz_info
;
TZ_NAMES_ENTRY
*
tmp_tzname
;
Time_zone
*
return_val
=
0
;
...
...
@@ -1667,9 +1732,8 @@ tz_load_from_db(THD *thd, const String *tz_name)
#ifdef ABBR_ARE_USED
char
chars
[
max
(
TZ_MAX_CHARS
+
1
,
(
2
*
(
MY_TZNAME_MAX
+
1
)))];
#endif
uint
not_used
;
DBUG_ENTER
(
"tz_load_from_
db
"
);
DBUG_ENTER
(
"tz_load_from_
open_tables
"
);
/* Prepare tz_info for loading also let us make copy of time zone name */
...
...
@@ -1689,77 +1753,46 @@ tz_load_from_db(THD *thd, const String *tz_name)
*/
strmake
(
tz_name_buff
,
tz_name
->
ptr
(),
tz_name
->
length
());
/*
Open and lock time zone description tables
*/
db_save
=
thd
->
db
;
db_length_save
=
thd
->
db_length
;
thd
->
db
=
system_db_name
;
thd
->
db_length
=
5
;
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
[
0
].
alias
=
tables
[
0
].
real_name
=
(
char
*
)
"time_zone_name"
;
tables
[
1
].
alias
=
tables
[
1
].
real_name
=
(
char
*
)
"time_zone"
;
tables
[
2
].
alias
=
tables
[
2
].
real_name
=
(
char
*
)
"time_zone_transition"
;
tables
[
3
].
alias
=
tables
[
3
].
real_name
=
(
char
*
)
"time_zone_transition_type"
;
tables
[
0
].
next
=
tables
+
1
;
tables
[
1
].
next
=
tables
+
2
;
tables
[
2
].
next
=
tables
+
3
;
tables
[
0
].
lock_type
=
tables
[
1
].
lock_type
=
tables
[
2
].
lock_type
=
tables
[
3
].
lock_type
=
TL_READ
;
tables
[
0
].
db
=
tables
[
1
].
db
=
tables
[
2
].
db
=
tables
[
3
].
db
=
thd
->
db
;
if
(
open_tables
(
thd
,
tables
,
&
not_used
))
{
sql_print_error
(
"Error: Can't open time zone tables: %s"
,
thd
->
net
.
last_error
);
goto
end
;
}
lock_ptr
[
0
]
=
tables
[
0
].
table
;
lock_ptr
[
1
]
=
tables
[
1
].
table
;
lock_ptr
[
2
]
=
tables
[
2
].
table
;
lock_ptr
[
3
]
=
tables
[
3
].
table
;
if
(
!
(
lock
=
mysql_lock_tables
(
thd
,
lock_ptr
,
4
)))
{
sql_print_error
(
"Error: Can't lock time zone tables: %s"
,
thd
->
net
.
last_error
);
goto
end_with_close
;
}
/*
Let us find out time zone id by its name (there is only one index
and it is specifically for this purpose).
*/
table
=
t
ables
[
0
].
table
;
table
=
t
z_tables
->
table
;
tz_tables
=
tz_tables
->
next
;
table
->
field
[
0
]
->
store
(
tz_name
->
ptr
(),
tz_name
->
length
(),
&
my_charset_latin1
);
table
->
file
->
ha_index_init
(
0
);
/*
It is OK to ignore ha_index_init()/ha_index_end() return values since
mysql.time_zone* tables are MyISAM and these operations always succeed
for MyISAM.
*/
(
void
)
table
->
file
->
ha_index_init
(
0
);
if
(
table
->
file
->
index_read
(
table
->
record
[
0
],
(
byte
*
)
table
->
field
[
0
]
->
ptr
,
0
,
HA_READ_KEY_EXACT
))
{
sql_print_error
(
"Error: Can't find description of time zone."
);
goto
end
_with_unlock
;
goto
end
;
}
tzid
=
(
uint
)
table
->
field
[
1
]
->
val_int
();
table
->
file
->
ha_index_end
();
(
void
)
table
->
file
->
ha_index_end
();
/*
Now we need to lookup record in mysql.time_zone table in order to
understand whenever this timezone uses leap seconds (again we are
using the only index in this table).
*/
table
=
tables
[
1
].
table
;
table
=
tz_tables
->
table
;
tz_tables
=
tz_tables
->
next
;
table
->
field
[
0
]
->
store
((
longlong
)
tzid
);
table
->
file
->
ha_index_init
(
0
);
(
void
)
table
->
file
->
ha_index_init
(
0
);
if
(
table
->
file
->
index_read
(
table
->
record
[
0
],
(
byte
*
)
table
->
field
[
0
]
->
ptr
,
0
,
HA_READ_KEY_EXACT
))
{
sql_print_error
(
"Error: Can't find description of time zone."
);
goto
end
_with_unlock
;
goto
end
;
}
/* If Uses_leap_seconds == 'Y' */
...
...
@@ -1769,7 +1802,7 @@ tz_load_from_db(THD *thd, const String *tz_name)
tz_info
->
lsis
=
tz_lsis
;
}
table
->
file
->
ha_index_end
();
(
void
)
table
->
file
->
ha_index_end
();
/*
Now we will iterate through records for out time zone in
...
...
@@ -1777,9 +1810,10 @@ tz_load_from_db(THD *thd, const String *tz_name)
only for our time zone guess what are we doing?
Right - using special index.
*/
table
=
tables
[
3
].
table
;
table
=
tz_tables
->
table
;
tz_tables
=
tz_tables
->
next
;
table
->
field
[
0
]
->
store
((
longlong
)
tzid
);
table
->
file
->
ha_index_init
(
0
);
(
void
)
table
->
file
->
ha_index_init
(
0
);
// FIXME Is there any better approach than explicitly specifying 4 ???
res
=
table
->
file
->
index_read
(
table
->
record
[
0
],
(
byte
*
)
table
->
field
[
0
]
->
ptr
,
...
...
@@ -1793,7 +1827,7 @@ tz_load_from_db(THD *thd, const String *tz_name)
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition_type table: too big "
"transition type id"
);
goto
end
_with_unlock
;
goto
end
;
}
ttis
[
ttid
].
tt_gmtoff
=
(
long
)
table
->
field
[
2
]
->
val_int
();
...
...
@@ -1807,7 +1841,7 @@ tz_load_from_db(THD *thd, const String *tz_name)
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition_type table: not enough "
"room for abbreviations"
);
goto
end
_with_unlock
;
goto
end
;
}
ttis
[
ttid
].
tt_abbrind
=
tz_info
->
charcnt
;
memcpy
(
chars
+
tz_info
->
charcnt
,
abbr
.
ptr
(),
abbr
.
length
());
...
...
@@ -1838,10 +1872,10 @@ tz_load_from_db(THD *thd, const String *tz_name)
{
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition_type table"
);
goto
end
_with_unlock
;
goto
end
;
}
table
->
file
->
ha_index_end
();
(
void
)
table
->
file
->
ha_index_end
();
/*
...
...
@@ -1849,9 +1883,9 @@ tz_load_from_db(THD *thd, const String *tz_name)
mysql.time_zone_transition table. Here we additionaly need records
in ascending order by index scan also satisfies us.
*/
table
=
t
ables
[
2
].
table
;
table
=
t
z_tables
->
table
;
table
->
field
[
0
]
->
store
((
longlong
)
tzid
);
table
->
file
->
ha_index_init
(
0
);
(
void
)
table
->
file
->
ha_index_init
(
0
);
// FIXME Is there any better approach than explicitly specifying 4 ???
res
=
table
->
file
->
index_read
(
table
->
record
[
0
],
(
byte
*
)
table
->
field
[
0
]
->
ptr
,
...
...
@@ -1866,14 +1900,14 @@ tz_load_from_db(THD *thd, const String *tz_name)
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition table: "
"too much transitions"
);
goto
end
_with_unlock
;
goto
end
;
}
if
(
ttid
+
1
>
tz_info
->
typecnt
)
{
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition table: "
"bad transition type id"
);
goto
end
_with_unlock
;
goto
end
;
}
ats
[
tz_info
->
timecnt
]
=
ttime
;
...
...
@@ -1896,10 +1930,10 @@ tz_load_from_db(THD *thd, const String *tz_name)
{
sql_print_error
(
"Error while loading time zone description from "
"mysql.time_zone_transition table"
);
goto
end
_with_unlock
;
goto
end
;
}
table
->
file
->
ha_index_end
();
(
void
)
table
->
file
->
ha_index_end
();
table
=
0
;
/*
...
...
@@ -1916,7 +1950,7 @@ tz_load_from_db(THD *thd, const String *tz_name)
{
sql_print_error
(
"Error: Out of memory while loading time zone "
"description"
);
goto
end
_with_unlock
;
goto
end
;
}
...
...
@@ -1941,12 +1975,12 @@ tz_load_from_db(THD *thd, const String *tz_name)
if
(
tz_info
->
typecnt
<
1
)
{
sql_print_error
(
"Error: loading time zone without transition types"
);
goto
end
_with_unlock
;
goto
end
;
}
if
(
prepare_tz_info
(
tz_info
,
&
tz_storage
))
{
sql_print_error
(
"Error: Unable to build mktime map for time zone"
);
goto
end
_with_unlock
;
goto
end
;
}
...
...
@@ -1958,7 +1992,7 @@ tz_load_from_db(THD *thd, const String *tz_name)
my_hash_insert
(
&
tz_names
,
(
const
byte
*
)
tmp_tzname
)))
{
sql_print_error
(
"Error: Out of memory while loading time zone"
);
goto
end
_with_unlock
;
goto
end
;
}
/*
...
...
@@ -1966,19 +2000,11 @@ tz_load_from_db(THD *thd, const String *tz_name)
*/
return_val
=
tmp_tzname
->
tz
;
end
_with_unlock
:
end:
if
(
table
)
table
->
file
->
ha_index_end
();
mysql_unlock_tables
(
thd
,
lock
);
(
void
)
table
->
file
->
ha_index_end
();
end_with_close:
close_thread_tables
(
thd
);
end:
thd
->
db
=
db_save
;
thd
->
db_length
=
db_length_save
;
DBUG_RETURN
(
return_val
);
}
...
...
@@ -2068,8 +2094,8 @@ str_to_offset(const char *str, uint length, long *offset)
SYNOPSIS
my_tz_find()
thd - current thread
name - time zone specification
tz_tables - list of opened'n'locked time zone describing tables
DESCRIPTION
This function checks if name is one of time zones described in db,
...
...
@@ -2091,7 +2117,11 @@ str_to_offset(const char *str, uint length, long *offset)
values as parameter without additional external check and this property
is used by @@time_zone variable handling code).
It will perform lookup in system tables (mysql.time_zone*) if needed.
It will perform lookup in system tables (mysql.time_zone*) if needed
using tz_tables as list of already opened tables (for info about this
list look at tz_load_from_open_tables() description). It won't perform
such lookup if no time zone describing tables were found during server
start up.
RETURN VALUE
Pointer to corresponding Time_zone object. 0 - in case of bad time zone
...
...
@@ -2099,7 +2129,7 @@ str_to_offset(const char *str, uint length, long *offset)
*/
Time_zone
*
my_tz_find
(
THD
*
thd
,
const
String
*
name
)
my_tz_find
(
const
String
*
name
,
TABLE_LIST
*
tz_tables
)
{
TZ_NAMES_ENTRY
*
tmp_tzname
;
Time_zone
*
result_tz
=
0
;
...
...
@@ -2109,6 +2139,8 @@ my_tz_find(THD *thd, const String * name)
DBUG_PRINT
(
"enter"
,
(
"time zone name='%s'"
,
name
?
((
String
*
)
name
)
->
c_ptr
()
:
"NULL"
));
DBUG_ASSERT
(
!
time_zone_tables_exist
||
tz_tables
);
if
(
!
name
)
DBUG_RETURN
(
0
);
...
...
@@ -2136,8 +2168,10 @@ my_tz_find(THD *thd, const String * name)
(
const
byte
*
)
name
->
ptr
(),
name
->
length
())))
result_tz
=
tmp_tzname
->
tz
;
else
if
(
time_zone_tables_exist
)
result_tz
=
tz_load_from_open_tables
(
name
,
tz_tables
);
else
result_tz
=
tz_load_from_db
(
thd
,
name
)
;
result_tz
=
0
;
}
VOID
(
pthread_mutex_unlock
(
&
tz_LOCK
));
...
...
sql/tztime.h
View file @
a6bd0eb5
...
...
@@ -59,7 +59,8 @@ class Time_zone: public Sql_alloc
extern
Time_zone
*
my_tz_UTC
;
extern
Time_zone
*
my_tz_SYSTEM
;
extern
Time_zone
*
my_tz_find
(
THD
*
thd
,
const
String
*
name
);
extern
TABLE_LIST
*
my_tz_get_table_list
(
THD
*
thd
);
extern
Time_zone
*
my_tz_find
(
const
String
*
name
,
TABLE_LIST
*
tz_tables
);
extern
my_bool
my_tz_init
(
THD
*
org_thd
,
const
char
*
default_tzname
,
my_bool
bootstrap
);
extern
void
my_tz_free
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment