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
d9a412dc
Commit
d9a412dc
authored
Dec 08, 2003
by
gluh@gluh.mysql.r18.ru
Browse files
Options
Browse Files
Download
Plain Diff
post-merge fixes
parents
301d8137
ec874924
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
433 additions
and
71 deletions
+433
-71
mysql-test/r/func_sapdb.result
mysql-test/r/func_sapdb.result
+10
-9
mysql-test/r/func_time.result
mysql-test/r/func_time.result
+57
-0
mysql-test/r/keywords.result
mysql-test/r/keywords.result
+9
-7
mysql-test/t/func_sapdb.test
mysql-test/t/func_sapdb.test
+2
-1
mysql-test/t/func_time.test
mysql-test/t/func_time.test
+24
-0
mysql-test/t/keywords.test
mysql-test/t/keywords.test
+5
-3
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
+262
-32
sql/item_timefunc.h
sql/item_timefunc.h
+22
-5
sql/lex.h
sql/lex.h
+14
-2
sql/sql_yacc.yy
sql/sql_yacc.yy
+28
-6
No files found.
mysql-test/r/func_sapdb.result
View file @
d9a412dc
...
...
@@ -188,13 +188,14 @@ ttt qqq
NULL NULL
NULL NULL
2001-01-01 02:02:02 26:02:02
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
ttt qqq
-744:00:00 NULL
26305:01:02 22:58:58
-26305:01:02 -22:58:58
NULL 26:02:02
NULL NULL
NULL NULL
00:00:00 -24:00:00
SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq,
TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test;
ttt qqq eee rrr
-744:00:00 NULL NULL NULL
26305:01:02 22:58:58 -22:58:58 NULL
-26305:01:02 -22:58:58 22:58:58 NULL
NULL 26:02:02 26:02:02 NULL
NULL NULL NULL NULL
NULL NULL NULL NULL
00:00:00 -24:00:00 24:00:00 NULL
drop table t1, test;
mysql-test/r/func_time.result
View file @
d9a412dc
...
...
@@ -464,6 +464,63 @@ date_add(date,INTERVAL "1 1:1" DAY_MINUTE)
select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1;
date_add(date,INTERVAL "1 1:1:1" DAY_SECOND)
2003-01-03 01:01:01
select date_add(date,INTERVAL "1" WEEK) from t1;
date_add(date,INTERVAL "1" WEEK)
2003-01-09 00:00:00
select date_add(date,INTERVAL "1" QUARTER) from t1;
date_add(date,INTERVAL "1" QUARTER)
2003-04-02
select timestampadd(MINUTE, 1, date) from t1;
timestampadd(MINUTE, 1, date)
2003-01-02 00:01:00
select timestampadd(WEEK, 1, date) from t1;
timestampadd(WEEK, 1, date)
2003-01-09 00:00:00
select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_SECOND, 1, date)
2003-01-02 00:00:01
select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_FRAC_SECOND, 1, date)
2003-01-02 00:00:00.000001
select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a;
a
3
select timestampdiff(YEAR, '2002-05-01', '2001-01-01') as a;
a
-1
select timestampdiff(QUARTER, '2002-05-01', '2001-01-01') as a;
a
-5
select timestampdiff(MONTH, '2000-03-28', '2000-02-29') as a;
a
0
select timestampdiff(MONTH, '1991-03-28', '2000-02-29') as a;
a
107
select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a;
a
12
select timestampdiff(SQL_TSI_HOUR, '2001-02-01', '2001-05-01') as a;
a
2136
select timestampdiff(SQL_TSI_DAY, '2001-02-01', '2001-05-01') as a;
a
89
select timestampdiff(SQL_TSI_MINUTE, '2001-02-01 12:59:59', '2001-05-01 12:58:59') as a;
a
128159
select timestampdiff(SQL_TSI_SECOND, '2001-02-01 12:59:59', '2001-05-01 12:58:58') as a;
a
7689539
select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a;
a
7689538999999
select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1,
timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2,
timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3,
timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4;
a1 a2 a3 a4
28 28 29 29
select date_add(time,INTERVAL 1 SECOND) from t1;
date_add(time,INTERVAL 1 SECOND)
2006-07-08 00:00:01
...
...
mysql-test/r/keywords.result
View file @
d9a412dc
drop table if exists t1;
create table t1 (time time, date date, timestamp timestamp);
insert into t1 values ("12:22:22","97:02:03","1997-01-02");
create table t1 (time time, date date, timestamp timestamp,
quarter int, week int, year int, timestampadd int, timestampdiff int);
insert into t1 values ("12:22:22","97:02:03","1997-01-02",1,2,3,4,5);
select * from t1;
time date timestamp
12:22:22 1997-02-03 1997-01-02 00:00:00
select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time)
122222 19970203 19970102000000 1997-02-03 12:22:22
time date timestamp quarter week year timestampadd timestampdiff
12:22:22 1997-02-03 1997-01-02 00:00:00 1 2 3 4 5
select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time),
t1.quarter+t1.week, t1.year+timestampadd, timestampdiff from t1;
t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time) t1.quarter+t1.week t1.year+timestampadd timestampdiff
122222 19970203 19970102000000 1997-02-03 12:22:22 3 7 5
drop table t1;
create table events(binlog int);
insert into events values(1);
...
...
mysql-test/t/func_sapdb.test
View file @
d9a412dc
...
...
@@ -94,6 +94,7 @@ insert into test values
(
'2001-01-01 01:01:01'
,
'01:01:01'
,
'1 01:01:01'
,
'2001-01-01 01:01:01'
);
SELECT
ADDTIME
(
t1
,
t2
)
As
ttt
,
ADDTIME
(
t2
,
t3
)
As
qqq
from
test
;
SELECT
TIMEDIFF
(
t1
,
t4
)
As
ttt
,
TIMEDIFF
(
t2
,
t3
)
As
qqq
from
test
;
SELECT
TIMEDIFF
(
t1
,
t4
)
As
ttt
,
TIMEDIFF
(
t2
,
t3
)
As
qqq
,
TIMEDIFF
(
t3
,
t2
)
As
eee
,
TIMEDIFF
(
t2
,
t4
)
As
rrr
from
test
;
drop
table
t1
,
test
;
mysql-test/t/func_time.test
View file @
d9a412dc
...
...
@@ -220,6 +220,30 @@ select date_add(date,INTERVAL "1:1:1" HOUR_SECOND) from t1;
select
date_add
(
date
,
INTERVAL
"1 1:1"
DAY_MINUTE
)
from
t1
;
select
date_add
(
date
,
INTERVAL
"1 1:1:1"
DAY_SECOND
)
from
t1
;
select
date_add
(
date
,
INTERVAL
"1"
WEEK
)
from
t1
;
select
date_add
(
date
,
INTERVAL
"1"
QUARTER
)
from
t1
;
select
timestampadd
(
MINUTE
,
1
,
date
)
from
t1
;
select
timestampadd
(
WEEK
,
1
,
date
)
from
t1
;
select
timestampadd
(
SQL_TSI_SECOND
,
1
,
date
)
from
t1
;
select
timestampadd
(
SQL_TSI_FRAC_SECOND
,
1
,
date
)
from
t1
;
select
timestampdiff
(
MONTH
,
'2001-02-01'
,
'2001-05-01'
)
as
a
;
select
timestampdiff
(
YEAR
,
'2002-05-01'
,
'2001-01-01'
)
as
a
;
select
timestampdiff
(
QUARTER
,
'2002-05-01'
,
'2001-01-01'
)
as
a
;
select
timestampdiff
(
MONTH
,
'2000-03-28'
,
'2000-02-29'
)
as
a
;
select
timestampdiff
(
MONTH
,
'1991-03-28'
,
'2000-02-29'
)
as
a
;
select
timestampdiff
(
SQL_TSI_WEEK
,
'2001-02-01'
,
'2001-05-01'
)
as
a
;
select
timestampdiff
(
SQL_TSI_HOUR
,
'2001-02-01'
,
'2001-05-01'
)
as
a
;
select
timestampdiff
(
SQL_TSI_DAY
,
'2001-02-01'
,
'2001-05-01'
)
as
a
;
select
timestampdiff
(
SQL_TSI_MINUTE
,
'2001-02-01 12:59:59'
,
'2001-05-01 12:58:59'
)
as
a
;
select
timestampdiff
(
SQL_TSI_SECOND
,
'2001-02-01 12:59:59'
,
'2001-05-01 12:58:58'
)
as
a
;
select
timestampdiff
(
SQL_TSI_FRAC_SECOND
,
'2001-02-01 12:59:59.120000'
,
'2001-05-01 12:58:58.119999'
)
as
a
;
select
timestampdiff
(
SQL_TSI_DAY
,
'1986-02-01'
,
'1986-03-01'
)
as
a1
,
timestampdiff
(
SQL_TSI_DAY
,
'1900-02-01'
,
'1900-03-01'
)
as
a2
,
timestampdiff
(
SQL_TSI_DAY
,
'1996-02-01'
,
'1996-03-01'
)
as
a3
,
timestampdiff
(
SQL_TSI_DAY
,
'2000-02-01'
,
'2000-03-01'
)
as
a4
;
# The following is not as one would expect...
select
date_add
(
time
,
INTERVAL
1
SECOND
)
from
t1
;
drop
table
t1
;
...
...
mysql-test/t/keywords.test
View file @
d9a412dc
...
...
@@ -6,10 +6,12 @@
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
time
time
,
date
date
,
timestamp
timestamp
);
insert
into
t1
values
(
"12:22:22"
,
"97:02:03"
,
"1997-01-02"
);
create
table
t1
(
time
time
,
date
date
,
timestamp
timestamp
,
quarter
int
,
week
int
,
year
int
,
timestampadd
int
,
timestampdiff
int
);
insert
into
t1
values
(
"12:22:22"
,
"97:02:03"
,
"1997-01-02"
,
1
,
2
,
3
,
4
,
5
);
select
*
from
t1
;
select
t1
.
time
+
0
,
t1
.
date
+
0
,
t1
.
timestamp
+
0
,
concat
(
date
,
" "
,
time
)
from
t1
;
select
t1
.
time
+
0
,
t1
.
date
+
0
,
t1
.
timestamp
+
0
,
concat
(
date
,
" "
,
time
),
t1
.
quarter
+
t1
.
week
,
t1
.
year
+
timestampadd
,
timestampdiff
from
t1
;
drop
table
t1
;
create
table
events
(
binlog
int
);
insert
into
events
values
(
1
);
...
...
sql/item_create.cc
View file @
d9a412dc
...
...
@@ -312,11 +312,6 @@ Item *create_func_current_user()
system_charset_info
);
}
Item
*
create_func_quarter
(
Item
*
a
)
{
return
new
Item_func_quarter
(
a
);
}
Item
*
create_func_radians
(
Item
*
a
)
{
return
new
Item_func_units
((
char
*
)
"radians"
,
a
,
M_PI
/
180
,
0.0
);
...
...
sql/item_create.h
View file @
d9a412dc
...
...
@@ -72,7 +72,6 @@ Item *create_func_period_diff(Item* a, Item *b);
Item
*
create_func_pi
(
void
);
Item
*
create_func_pow
(
Item
*
a
,
Item
*
b
);
Item
*
create_func_current_user
(
void
);
Item
*
create_func_quarter
(
Item
*
a
);
Item
*
create_func_radians
(
Item
*
a
);
Item
*
create_func_release_lock
(
Item
*
a
);
Item
*
create_func_repeat
(
Item
*
a
,
Item
*
b
);
...
...
sql/item_timefunc.cc
View file @
d9a412dc
...
...
@@ -869,9 +869,15 @@ static bool get_interval_value(Item *args,interval_type int_type,
case
INTERVAL_YEAR
:
interval
->
year
=
value
;
break
;
case
INTERVAL_QUARTER
:
interval
->
month
=
value
*
3
;
break
;
case
INTERVAL_MONTH
:
interval
->
month
=
value
;
break
;
case
INTERVAL_WEEK
:
interval
->
day
=
value
*
7
;
break
;
case
INTERVAL_DAY
:
interval
->
day
=
value
;
break
;
...
...
@@ -1547,6 +1553,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
goto
null_date
;
break
;
case
INTERVAL_DAY
:
case
INTERVAL_WEEK
:
period
=
calc_daynr
(
ltime
->
year
,
ltime
->
month
,
ltime
->
day
)
+
sign
*
interval
.
day
;
if
(
period
<
0
||
period
>=
MAX_DAY_NUMBER
)
// Daynumber from year 0 to 9999-12-31
...
...
@@ -1562,6 +1569,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
ltime
->
day
=
28
;
// Was leap-year
break
;
case
INTERVAL_YEAR_MONTH
:
case
INTERVAL_QUARTER
:
case
INTERVAL_MONTH
:
period
=
(
ltime
->
year
*
12
+
sign
*
interval
.
year
*
12
+
ltime
->
month
-
1
+
sign
*
interval
.
month
);
...
...
@@ -1659,7 +1667,9 @@ void Item_extract::fix_length_and_dec()
switch
(
int_type
)
{
case
INTERVAL_YEAR
:
max_length
=
4
;
date_value
=
1
;
break
;
case
INTERVAL_YEAR_MONTH
:
max_length
=
6
;
date_value
=
1
;
break
;
case
INTERVAL_QUARTER
:
max_length
=
2
;
date_value
=
1
;
break
;
case
INTERVAL_MONTH
:
max_length
=
2
;
date_value
=
1
;
break
;
case
INTERVAL_WEEK
:
max_length
=
2
;
date_value
=
1
;
break
;
case
INTERVAL_DAY
:
max_length
=
2
;
date_value
=
1
;
break
;
case
INTERVAL_DAY_HOUR
:
max_length
=
9
;
date_value
=
0
;
break
;
case
INTERVAL_DAY_MINUTE
:
max_length
=
11
;
date_value
=
0
;
break
;
...
...
@@ -1682,6 +1692,8 @@ void Item_extract::fix_length_and_dec()
longlong
Item_extract
::
val_int
()
{
TIME
ltime
;
uint
year
;
ulong
week_format
;
long
neg
;
if
(
date_value
)
{
...
...
@@ -1703,7 +1715,16 @@ longlong Item_extract::val_int()
switch
(
int_type
)
{
case
INTERVAL_YEAR
:
return
ltime
.
year
;
case
INTERVAL_YEAR_MONTH
:
return
ltime
.
year
*
100L
+
ltime
.
month
;
case
INTERVAL_QUARTER
:
return
ltime
.
month
/
3
+
1
;
case
INTERVAL_MONTH
:
return
ltime
.
month
;
case
INTERVAL_WEEK
:
{
week_format
=
current_thd
->
variables
.
default_week_format
;
return
calc_week
(
&
ltime
,
(
week_format
&
2
)
!=
0
,
(
week_format
&
1
)
==
0
,
&
year
);
}
case
INTERVAL_DAY
:
return
ltime
.
day
;
case
INTERVAL_DAY_HOUR
:
return
(
long
)
(
ltime
.
day
*
100L
+
ltime
.
hour
)
*
neg
;
case
INTERVAL_DAY_MINUTE
:
return
(
long
)
(
ltime
.
day
*
10000L
+
...
...
@@ -2085,6 +2106,79 @@ void Item_func_add_time::print(String *str)
}
/*
SYNOPSIS
calc_time_diff()
l_time1 TIME/DATE/DATETIME value
l_time2 TIME/DATE/DATETIME value
l_sign Can be 1 (operation of addition)
or -1 (substraction)
seconds_out Returns count of seconds bitween
l_time1 and l_time2
microseconds_out Returns count of microseconds bitween
l_time1 and l_time2.
DESCRIPTION
Calculates difference in seconds(seconds_out)
and microseconds(microseconds_out)
bitween two TIME/DATE/DATETIME values.
RETURN VALUES
Rertuns sign of difference.
1 means negative result
0 means positive result
*/
bool
calc_time_diff
(
TIME
*
l_time1
,
TIME
*
l_time2
,
int
l_sign
,
longlong
*
seconds_out
,
long
*
microseconds_out
)
{
long
days
;
bool
neg
;
longlong
seconds
=
*
seconds_out
;
long
microseconds
=
*
microseconds_out
;
/*
We suppose that if first argument is TIMESTAMP_TIME
the second argument should be TIMESTAMP_TIME also.
We should check it before calc_time_diff call.
*/
if
(
l_time1
->
time_type
==
TIMESTAMP_TIME
)
// Time value
days
=
l_time1
->
day
-
l_sign
*
l_time2
->
day
;
else
// DateTime value
days
=
(
calc_daynr
((
uint
)
l_time1
->
year
,
(
uint
)
l_time1
->
month
,
(
uint
)
l_time1
->
day
)
-
l_sign
*
calc_daynr
((
uint
)
l_time2
->
year
,
(
uint
)
l_time2
->
month
,
(
uint
)
l_time2
->
day
));
microseconds
=
l_time1
->
second_part
-
l_sign
*
l_time2
->
second_part
;
seconds
=
((
longlong
)
days
*
86400L
+
l_time1
->
hour
*
3600L
+
l_time1
->
minute
*
60L
+
l_time1
->
second
+
microseconds
/
1000000L
-
(
longlong
)
l_sign
*
(
l_time2
->
hour
*
3600L
+
l_time2
->
minute
*
60L
+
l_time2
->
second
));
neg
=
0
;
if
(
seconds
<
0
)
{
seconds
=
-
seconds
;
neg
=
1
;
}
else
if
(
seconds
==
0
&&
microseconds
<
0
)
{
microseconds
=
-
microseconds
;
neg
=
1
;
}
if
(
microseconds
<
0
)
{
microseconds
+=
1000000L
;
seconds
--
;
}
*
seconds_out
=
seconds
;
*
microseconds_out
=
microseconds
;
return
neg
;
}
/*
TIMEDIFF(t,s) is a time function that calculates the
time value between a start and end time.
...
...
@@ -2110,40 +2204,16 @@ String *Item_func_timediff::val_str(String *str)
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
l_sign
=
-
l_sign
;
if
(
l_time1
.
time_type
==
TIMESTAMP_TIME
)
// Time value
days
=
l_time1
.
day
-
l_sign
*
l_time2
.
day
;
else
// DateTime value
days
=
(
calc_daynr
((
uint
)
l_time1
.
year
,
(
uint
)
l_time1
.
month
,
(
uint
)
l_time1
.
day
)
-
l_sign
*
calc_daynr
((
uint
)
l_time2
.
year
,
(
uint
)
l_time2
.
month
,
(
uint
)
l_time2
.
day
));
microseconds
=
l_time1
.
second_part
-
l_sign
*
l_time2
.
second_part
;
seconds
=
((
longlong
)
days
*
86400L
+
l_time1
.
hour
*
3600L
+
l_time1
.
minute
*
60L
+
l_time1
.
second
+
microseconds
/
1000000L
-
(
longlong
)
l_sign
*
(
l_time2
.
hour
*
3600L
+
l_time2
.
minute
*
60L
+
l_time2
.
second
));
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
l_sign
,
&
seconds
,
&
microseconds
);
l_time3
.
neg
=
0
;
if
(
seconds
<
0
)
{
seconds
=
-
seconds
;
l_time3
.
neg
=
1
;
}
else
if
(
seconds
==
0
&&
microseconds
<
0
)
{
microseconds
=
-
microseconds
;
l_time3
.
neg
=
1
;
}
if
(
microseconds
<
0
)
{
microseconds
+=
1000000L
;
seconds
--
;
}
/*
For TIMESTAMP_TIME only:
If both argumets are negative values and diff between them
is negative we need to swap sign as result should be positive.
*/
if
((
l_time2
.
neg
==
l_time1
.
neg
)
&&
l_time1
.
neg
)
l_time3
.
neg
=
l_time3
.
neg
?
0
:
1
;
l_time3
.
neg
=
1
-
l_time3
.
neg
;
// Swap sign of result
calc_time_from_sec
(
&
l_time3
,
(
long
)
seconds
,
microseconds
);
...
...
@@ -2210,6 +2280,166 @@ longlong Item_func_microsecond::val_int()
}
longlong
Item_func_timestamp_diff
::
val_int
()
{
TIME
ltime1
,
ltime2
;
longlong
seconds
;
long
microseconds
;
long
months
=
0
;
int
neg
=
1
;
null_value
=
0
;
if
(
args
[
0
]
->
get_date
(
&
ltime1
,
0
)
||
args
[
1
]
->
get_date
(
&
ltime2
,
0
))
goto
null_date
;
if
(
calc_time_diff
(
&
ltime2
,
&
ltime1
,
1
,
&
seconds
,
&
microseconds
))
neg
=
-
1
;
if
(
int_type
==
INTERVAL_YEAR
||
int_type
==
INTERVAL_QUARTER
||
int_type
==
INTERVAL_MONTH
)
{
uint
year
,
year_tmp
;
uint
year_beg
,
year_end
,
month_beg
,
month_end
;
uint
diff_days
=
seconds
/
86400L
;
uint
diff_months
=
0
;
uint
diff_years
=
0
;
if
(
neg
==
-
1
)
{
year_beg
=
ltime2
.
year
;
year_end
=
ltime1
.
year
;
month_beg
=
ltime2
.
month
;
month_end
=
ltime1
.
month
;
}
else
{
year_beg
=
ltime1
.
year
;
year_end
=
ltime2
.
year
;
month_beg
=
ltime1
.
month
;
month_end
=
ltime2
.
month
;
}
/* calc years*/
for
(
year
=
year_beg
;
year
<
year_end
;
year
++
)
{
uint
days
=
calc_days_in_year
(
year
);
if
(
days
>
diff_days
)
break
;
diff_days
-=
days
;
diff_years
++
;
}
/* calc months; Current year is in the 'year' variable */
month_beg
--
;
/* Change months to be 0-11 for easier calculation */
month_end
--
;
months
=
12
*
diff_years
;
while
(
month_beg
!=
month_end
)
{
uint
m_days
=
(
uint
)
days_in_month
[
month_beg
];
if
(
month_beg
==
1
)
{
/* This is only calculated once so there is no reason to cache it*/
uint
leap
=
(
uint
)
((
year
&
3
)
==
0
&&
(
year
%
100
||
(
year
%
400
==
0
&&
year
)));
m_days
+=
leap
;
}
if
(
m_days
>
diff_days
)
break
;
diff_days
-=
m_days
;
months
++
;
if
(
month_beg
++
==
11
)
/* if we wrap to next year */
{
month_beg
=
0
;
year
++
;
}
}
if
(
neg
==
-
1
)
months
=
-
months
;
}
switch
(
int_type
)
{
case
INTERVAL_YEAR
:
return
months
/
12
;
case
INTERVAL_QUARTER
:
return
months
/
3
;
case
INTERVAL_MONTH
:
return
months
;
case
INTERVAL_WEEK
:
return
seconds
/
86400L
/
7L
*
neg
;
case
INTERVAL_DAY
:
return
seconds
/
86400L
*
neg
;
case
INTERVAL_HOUR
:
return
seconds
/
3600L
*
neg
;
case
INTERVAL_MINUTE
:
return
seconds
/
60L
*
neg
;
case
INTERVAL_SECOND
:
return
seconds
*
neg
;
case
INTERVAL_MICROSECOND
:
{
longlong
max_sec
=
LONGLONG_MAX
/
1000000
;
if
(
max_sec
>
seconds
||
max_sec
==
seconds
&&
LONGLONG_MAX
%
1000000
>=
microseconds
)
return
(
longlong
)
(
seconds
*
1000000L
+
microseconds
)
*
neg
;
goto
null_date
;
}
default:
break
;
}
null_date:
null_value
=
1
;
return
0
;
}
void
Item_func_timestamp_diff
::
print
(
String
*
str
)
{
str
->
append
(
func_name
());
str
->
append
(
'('
);
switch
(
int_type
)
{
case
INTERVAL_YEAR
:
str
->
append
(
"YEAR"
);
break
;
case
INTERVAL_QUARTER
:
str
->
append
(
"QUARTER"
);
break
;
case
INTERVAL_MONTH
:
str
->
append
(
"MONTH"
);
break
;
case
INTERVAL_WEEK
:
str
->
append
(
"WEEK"
);
break
;
case
INTERVAL_DAY
:
str
->
append
(
"DAY"
);
break
;
case
INTERVAL_HOUR
:
str
->
append
(
"HOUR"
);
break
;
case
INTERVAL_MINUTE
:
str
->
append
(
"MINUTE"
);
break
;
case
INTERVAL_SECOND
:
str
->
append
(
"SECOND"
);
break
;
case
INTERVAL_MICROSECOND
:
str
->
append
(
"SECOND_FRAC"
);
break
;
default:
break
;
}
for
(
uint
i
=
0
;
i
<
2
;
i
++
)
{
str
->
append
(
','
);
args
[
i
]
->
print
(
str
);
}
str
->
append
(
')'
);
}
String
*
Item_func_get_format
::
val_str
(
String
*
str
)
{
const
char
*
format_name
;
...
...
sql/item_timefunc.h
View file @
d9a412dc
...
...
@@ -543,11 +543,11 @@ class Item_func_sec_to_time :public Item_str_func
enum
interval_type
{
INTERVAL_YEAR
,
INTERVAL_
MONTH
,
INTERVAL_DAY
,
INTERVAL_HOUR
,
INTERVAL_MINUTE
,
INTERVAL_
SECOND
,
INTERVAL_MICROSECOND
,
INTERVAL_YEAR_MONTH
,
INTERVAL_
DAY_HOUR
,
INTERVAL_DAY_MINUTE
,
INTERVAL_DAY_SECOND
,
INTERVAL_
HOUR_MINUTE
,
INTERVAL_HOUR_SECOND
,
INTERVAL_MINUTE
_SECOND
,
INTERVAL_DAY_MICROSECOND
,
INTERVAL_HOUR_MICROSECOND
,
INTERVAL_YEAR
,
INTERVAL_
QUARTER
,
INTERVAL_MONTH
,
INTERVAL_DAY
,
INTERVAL_HOUR
,
INTERVAL_
MINUTE
,
INTERVAL_WEEK
,
INTERVAL_SECOND
,
INTERVAL_MICROSECOND
,
INTERVAL_
YEAR_MONTH
,
INTERVAL_DAY_HOUR
,
INTERVAL_DAY_MINUTE
,
INTERVAL_
DAY_SECOND
,
INTERVAL_HOUR_MINUTE
,
INTERVAL_HOUR
_SECOND
,
INTERVAL_
MINUTE_SECOND
,
INTERVAL_
DAY_MICROSECOND
,
INTERVAL_HOUR_MICROSECOND
,
INTERVAL_MINUTE_MICROSECOND
,
INTERVAL_SECOND_MICROSECOND
};
...
...
@@ -769,6 +769,23 @@ class Item_func_microsecond :public Item_int_func
};
class
Item_func_timestamp_diff
:
public
Item_int_func
{
const
interval_type
int_type
;
public:
Item_func_timestamp_diff
(
Item
*
a
,
Item
*
b
,
interval_type
type_arg
)
:
Item_int_func
(
a
,
b
),
int_type
(
type_arg
)
{}
const
char
*
func_name
()
const
{
return
"timestamp_diff"
;
}
longlong
val_int
();
void
fix_length_and_dec
()
{
decimals
=
0
;
maybe_null
=
1
;
}
void
print
(
String
*
str
);
};
enum
date_time_format
{
USA_FORMAT
,
JIS_FORMAT
,
ISO_FORMAT
,
EUR_FORMAT
,
INTERNAL_FORMAT
...
...
sql/lex.h
View file @
d9a412dc
...
...
@@ -179,6 +179,7 @@ static SYMBOL symbols[] = {
{
"FOREIGN"
,
SYM
(
FOREIGN
),
0
,
0
},
{
"FORCE"
,
SYM
(
FORCE_SYM
),
0
,
0
},
{
"FOUND"
,
SYM
(
FOUND_SYM
),
0
,
0
},
{
"FRAC_SECOND"
,
SYM
(
FRAC_SECOND_SYM
),
0
,
0
},
{
"RAID_TYPE"
,
SYM
(
RAID_TYPE
),
0
,
0
},
{
"RAID_CHUNKS"
,
SYM
(
RAID_CHUNKS
),
0
,
0
},
{
"RAID_CHUNKSIZE"
,
SYM
(
RAID_CHUNKSIZE
),
0
,
0
},
...
...
@@ -336,6 +337,7 @@ static SYMBOL symbols[] = {
{
"PROCESS"
,
SYM
(
PROCESS
),
0
,
0
},
{
"PROCESSLIST"
,
SYM
(
PROCESSLIST_SYM
),
0
,
0
},
{
"PRIVILEGES"
,
SYM
(
PRIVILEGES
),
0
,
0
},
{
"QUARTER"
,
SYM
(
QUARTER_SYM
),
0
,
0
},
{
"QUERY"
,
SYM
(
QUERY_SYM
),
0
,
0
},
{
"QUICK"
,
SYM
(
QUICK
),
0
,
0
},
{
"RAID0"
,
SYM
(
RAID_0_SYM
),
0
,
0
},
...
...
@@ -401,6 +403,15 @@ static SYMBOL symbols[] = {
{
"SQL_NO_CACHE"
,
SYM
(
SQL_NO_CACHE_SYM
),
0
,
0
},
{
"SQL_SMALL_RESULT"
,
SYM
(
SQL_SMALL_RESULT
),
0
,
0
},
{
"SQL_THREAD"
,
SYM
(
SQL_THREAD
),
0
,
0
},
{
"SQL_TSI_FRAC_SECOND"
,
SYM
(
FRAC_SECOND_SYM
),
0
,
0
},
{
"SQL_TSI_SECOND"
,
SYM
(
SECOND_SYM
),
0
,
0
},
{
"SQL_TSI_MINUTE"
,
SYM
(
MINUTE_SYM
),
0
,
0
},
{
"SQL_TSI_HOUR"
,
SYM
(
HOUR_SYM
),
0
,
0
},
{
"SQL_TSI_DAY"
,
SYM
(
DAY_SYM
),
0
,
0
},
{
"SQL_TSI_WEEK"
,
SYM
(
WEEK_SYM
),
0
,
0
},
{
"SQL_TSI_MONTH"
,
SYM
(
MONTH_SYM
),
0
,
0
},
{
"SQL_TSI_QUARTER"
,
SYM
(
QUARTER_SYM
),
0
,
0
},
{
"SQL_TSI_YEAR"
,
SYM
(
YEAR_SYM
),
0
,
0
},
{
"SOUNDS"
,
SYM
(
SOUNDS_SYM
),
0
,
0
},
{
"SSL"
,
SYM
(
SSL_SYM
),
0
,
0
},
{
"STRAIGHT_JOIN"
,
SYM
(
STRAIGHT_JOIN
),
0
,
0
},
...
...
@@ -421,6 +432,8 @@ static SYMBOL symbols[] = {
{
"THEN"
,
SYM
(
THEN_SYM
),
0
,
0
},
{
"TIME"
,
SYM
(
TIME_SYM
),
0
,
0
},
{
"TIMESTAMP"
,
SYM
(
TIMESTAMP
),
0
,
0
},
{
"TIMESTAMPADD"
,
SYM
(
TIMESTAMP_ADD
),
0
,
0
},
{
"TIMESTAMPDIFF"
,
SYM
(
TIMESTAMP_DIFF
),
0
,
0
},
{
"TINYBLOB"
,
SYM
(
TINYBLOB
),
0
,
0
},
{
"TINYTEXT"
,
SYM
(
TINYTEXT
),
0
,
0
},
{
"TINYINT"
,
SYM
(
TINYINT
),
0
,
0
},
...
...
@@ -456,6 +469,7 @@ static SYMBOL symbols[] = {
{
"VARYING"
,
SYM
(
VARYING
),
0
,
0
},
{
"VARBINARY"
,
SYM
(
VARBINARY
),
0
,
0
},
{
"WARNINGS"
,
SYM
(
WARNINGS
),
0
,
0
},
{
"WEEK"
,
SYM
(
WEEK_SYM
),
0
,
0
},
{
"WITH"
,
SYM
(
WITH
),
0
,
0
},
{
"WORK"
,
SYM
(
WORK_SYM
),
0
,
0
},
{
"WRITE"
,
SYM
(
WRITE_SYM
),
0
,
0
},
...
...
@@ -644,7 +658,6 @@ static SYMBOL sql_functions[] = {
{
"POSITION"
,
SYM
(
POSITION_SYM
),
0
,
0
},
{
"POW"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_pow
)},
{
"POWER"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_pow
)},
{
"QUARTER"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_quarter
)},
{
"QUOTE"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_quote
)},
{
"RADIANS"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_radians
)},
{
"RAND"
,
SYM
(
RAND
),
0
,
0
},
...
...
@@ -691,7 +704,6 @@ static SYMBOL sql_functions[] = {
{
"UPPER"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_ucase
)},
{
"VARIANCE"
,
SYM
(
VARIANCE_SYM
),
0
,
0
},
{
"VERSION"
,
SYM
(
FUNC_ARG0
),
0
,
CREATE_FUNC
(
create_func_version
)},
{
"WEEK"
,
SYM
(
WEEK_SYM
),
0
,
0
},
{
"WEEKDAY"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_weekday
)},
{
"WEEKOFYEAR"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_weekofyear
)},
{
"WITHIN"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_within
)},
...
...
sql/sql_yacc.yy
View file @
d9a412dc
...
...
@@ -81,7 +81,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B)
enum Item_udftype udf_type;
CHARSET_INFO *charset;
thr_lock_type lock_type;
interval_type interval;
interval_type interval
, interval_time_st
;
timestamp_type date_time_type;
st_select_lex *select_lex;
chooser_compare_func_creator boolfunc2creator;
...
...
@@ -459,6 +459,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token STRING_SYM
%token TEXT_SYM
%token TIMESTAMP
%token TIMESTAMP_ADD
%token TIMESTAMP_DIFF
%token TIME_SYM
%token TINYBLOB
%token TINYINT
...
...
@@ -502,6 +504,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FIELD_FUNC
%token FORMAT_SYM
%token FOR_SYM
%token FRAC_SECOND_SYM
%token FROM_UNIXTIME
%token GEOMCOLLFROMTEXT
%token GEOMFROMTEXT
...
...
@@ -547,6 +550,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token POLYGON
%token POSITION_SYM
%token PROCEDURE
%token QUARTER_SYM
%token RAND
%token REPLACE
%token RIGHT
...
...
@@ -691,6 +695,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <date_time_type> date_time_type;
%type <interval> interval
%type <interval_time_st> interval_time_st
%type <db_type> table_types
%type <row_type> row_types
...
...
@@ -3766,6 +3772,8 @@ simple_expr:
Geometry::wkbPolygon, Geometry::wkbLineString); }
| POSITION_SYM '(' no_in_expr IN_SYM expr ')'
{ $$ = new Item_func_locate($5,$3); }
| QUARTER_SYM '(' expr ')'
{ $$ = new Item_func_quarter($3); }
| RAND '(' expr ')'
{ $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);}
| RAND '(' ')'
...
...
@@ -3799,6 +3807,10 @@ simple_expr:
{ $$= new Item_datetime_typecast($3); }
| TIMESTAMP '(' expr ',' expr ')'
{ $$= new Item_func_add_time($3, $5, 1, 0); }
| TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')'
{ $$= new Item_date_add_interval($7,$5,$3,0); }
| TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')'
{ $$= new Item_func_timestamp_diff($5,$7,$3); }
| TRIM '(' expr ')'
{ $$= new Item_func_trim($3); }
| TRIM '(' LEADING expr FROM expr ')'
...
...
@@ -4289,23 +4301,29 @@ using_list:
};
interval:
DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; }
interval_time_st {}
| DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; }
| DAY_MICROSECOND_SYM { $$=INTERVAL_DAY_MICROSECOND; }
| DAY_MINUTE_SYM { $$=INTERVAL_DAY_MINUTE; }
| DAY_SECOND_SYM { $$=INTERVAL_DAY_SECOND; }
| DAY_SYM { $$=INTERVAL_DAY; }
| HOUR_MICROSECOND_SYM { $$=INTERVAL_HOUR_MICROSECOND; }
| HOUR_MINUTE_SYM { $$=INTERVAL_HOUR_MINUTE; }
| HOUR_SECOND_SYM { $$=INTERVAL_HOUR_SECOND; }
| HOUR_SYM { $$=INTERVAL_HOUR; }
| MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
| MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; }
| MINUTE_SECOND_SYM { $$=INTERVAL_MINUTE_SECOND; }
| SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; }
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; };
interval_time_st:
DAY_SYM { $$=INTERVAL_DAY; }
| WEEK_SYM { $$=INTERVAL_WEEK; }
| HOUR_SYM { $$=INTERVAL_HOUR; }
| FRAC_SECOND_SYM { $$=INTERVAL_MICROSECOND; }
| MINUTE_SYM { $$=INTERVAL_MINUTE; }
| MONTH_SYM { $$=INTERVAL_MONTH; }
|
SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND
; }
|
QUARTER_SYM { $$=INTERVAL_QUARTER
; }
| SECOND_SYM { $$=INTERVAL_SECOND; }
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }
| YEAR_SYM { $$=INTERVAL_YEAR; };
date_time_type:
...
...
@@ -5812,6 +5830,7 @@ keyword:
| PREV_SYM {}
| PROCESS {}
| PROCESSLIST_SYM {}
| QUARTER_SYM {}
| QUERY_SYM {}
| QUICK {}
| RAID_0_SYM {}
...
...
@@ -5863,6 +5882,8 @@ keyword:
| TRANSACTION_SYM {}
| TRUNCATE_SYM {}
| TIMESTAMP {}
| TIMESTAMP_ADD {}
| TIMESTAMP_DIFF {}
| TIME_SYM {}
| TYPE_SYM {}
| FUNCTION_SYM {}
...
...
@@ -5874,6 +5895,7 @@ keyword:
| VARIABLES {}
| VALUE_SYM {}
| WARNINGS {}
| WEEK_SYM {}
| WORK_SYM {}
| X509_SYM {}
| YEAR_SYM {}
...
...
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