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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
5709ed20
Commit
5709ed20
authored
Jul 08, 2003
by
gluh@gluh.mysql.r18.ru
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SAPDB date/time finctions
parent
e6eef748
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
238 additions
and
236 deletions
+238
-236
mysql-test/r/cast.result
mysql-test/r/cast.result
+2
-2
mysql-test/r/func_sapdb.result
mysql-test/r/func_sapdb.result
+9
-3
mysql-test/t/func_sapdb.test
mysql-test/t/func_sapdb.test
+4
-2
sql/item_create.cc
sql/item_create.cc
+2
-2
sql/item_timefunc.cc
sql/item_timefunc.cc
+162
-160
sql/item_timefunc.h
sql/item_timefunc.h
+18
-64
sql/mysql_priv.h
sql/mysql_priv.h
+2
-0
sql/protocol.cc
sql/protocol.cc
+13
-0
sql/sql_string.cc
sql/sql_string.cc
+17
-0
sql/sql_string.h
sql/sql_string.h
+2
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+6
-3
sql/time.cc
sql/time.cc
+1
-0
No files found.
mysql-test/r/cast.result
View file @
5709ed20
...
...
@@ -44,10 +44,10 @@ t1 CREATE TABLE `t1` (
drop table t1;
select cast("2001-1-1" as date) = "2001-01-01";
cast("2001-1-1" as date) = "2001-01-01"
0
1
select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
0
1
select cast("1:2:3" as TIME) = "1:02:03";
cast("1:2:3" as TIME) = "1:02:03"
0
...
...
mysql-test/r/func_sapdb.result
View file @
5709ed20
...
...
@@ -101,8 +101,8 @@ timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002")
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
timediff("1997-12-31 23:59:59.000001","23:59:59.000001")
NULL
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1");
timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1")
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.
00000
1");
timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.
00000
1")
-00:00:00.000001
select maketime(10,11,12);
maketime(10,11,12)
...
...
@@ -122,6 +122,12 @@ NULL
select timestamp("2001-12-01", "25:01:01");
timestamp("2001-12-01", "25:01:01")
2001-12-02 01:01:01
select timestamp("2001-12-01 01:01:01.000100");
timestamp("2001-12-01 01:01:01.000100")
2001-12-01 01:01:01.000100
select timestamp("2001-12-01");
timestamp("2001-12-01")
2001-12-01 00:00:00
select day("1997-12-31 23:59:59.000001");
day("1997-12-31 23:59:59.000001")
31
...
...
@@ -147,7 +153,7 @@ addtime(cast("23:59:59.999999" as time) , "1 1:1:1.000002") as f3,
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
maketime(10,11,12) as f6,
timestamp(
"2001-12-01"
, "01:01:01") as f7,
timestamp(
cast("2001-12-01" as date)
, "01:01:01") as f7,
date("1997-12-31 23:59:59.000001") as f8,
time("1997-12-31 23:59:59.000001") as f9;
describe t1;
...
...
mysql-test/t/func_sapdb.test
View file @
5709ed20
...
...
@@ -51,7 +51,7 @@ select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
select
timediff
(
"1997-12-31 23:59:59.000001"
,
"1997-12-30 01:01:01.000002"
);
select
timediff
(
"1997-12-30 23:59:59.000001"
,
"1997-12-31 23:59:59.000002"
);
select
timediff
(
"1997-12-31 23:59:59.000001"
,
"23:59:59.000001"
);
select
timediff
(
"2000:01:01 00:00:00"
,
"2000:01:01 00:00:00.1"
);
select
timediff
(
"2000:01:01 00:00:00"
,
"2000:01:01 00:00:00.
00000
1"
);
select
maketime
(
10
,
11
,
12
);
select
maketime
(
25
,
11
,
12
);
...
...
@@ -61,6 +61,8 @@ select maketime(-25,11,12);
select
timestamp
(
"2001-12-01"
,
"01:01:01.999999"
);
select
timestamp
(
"2001-13-01"
,
"01:01:01.000001"
);
select
timestamp
(
"2001-12-01"
,
"25:01:01"
);
select
timestamp
(
"2001-12-01 01:01:01.000100"
);
select
timestamp
(
"2001-12-01"
);
select
day
(
"1997-12-31 23:59:59.000001"
);
select
date
(
"1997-12-31 23:59:59.000001"
);
select
date
(
"1997-13-31 23:59:59.000001"
);
...
...
@@ -75,7 +77,7 @@ select makedate(1997,1) as f1,
timediff
(
"1997-12-31 23:59:59.000001"
,
"1997-12-30 01:01:01.000002"
)
as
f4
,
timediff
(
"1997-12-30 23:59:59.000001"
,
"1997-12-31 23:59:59.000002"
)
as
f5
,
maketime
(
10
,
11
,
12
)
as
f6
,
timestamp
(
"2001-12-01"
,
"01:01:01"
)
as
f7
,
timestamp
(
cast
(
"2001-12-01"
as
date
)
,
"01:01:01"
)
as
f7
,
date
(
"1997-12-31 23:59:59.000001"
)
as
f8
,
time
(
"1997-12-31 23:59:59.000001"
)
as
f9
;
describe
t1
;
...
...
sql/item_create.cc
View file @
5709ed20
...
...
@@ -709,12 +709,12 @@ Item *create_func_makedate(Item* a,Item* b)
Item
*
create_func_addtime
(
Item
*
a
,
Item
*
b
)
{
return
new
Item_func_add_time
(
a
,
b
,
0
);
return
new
Item_func_add_time
(
a
,
b
,
0
,
0
);
}
Item
*
create_func_subtime
(
Item
*
a
,
Item
*
b
)
{
return
new
Item_func_add_time
(
a
,
b
,
1
);
return
new
Item_func_add_time
(
a
,
b
,
0
,
1
);
}
Item
*
create_func_timediff
(
Item
*
a
,
Item
*
b
)
...
...
sql/item_timefunc.cc
View file @
5709ed20
...
...
@@ -29,6 +29,8 @@
** Todo: Move month and days to language files
*/
#define MAX_DAY_NUMBER 3652424L
static
String
month_names
[]
=
{
String
(
"January"
,
&
my_charset_latin1
),
...
...
@@ -55,10 +57,14 @@ static String day_names[] =
String
(
"Sunday"
,
&
my_charset_latin1
)
};
enum
date_time_format_types
{
TIME_ONLY
=
0
,
TIME_MICROSECOND
,
DATE_ONLY
,
DATE_TIME
,
DATE_TIME_MICROSECOND
};
enum
date_time_format_types
{
TIME_ONLY
=
0
,
TIME_MICROSECOND
,
DATE_ONLY
,
DATE_TIME
,
DATE_TIME_MICROSECOND
};
typedef
struct
date_time_format
{
typedef
struct
date_time_format
{
const
char
*
format_str
;
uint
length
;
};
...
...
@@ -73,6 +79,14 @@ static struct date_time_format date_time_formats[]=
};
/*
OPTIMIZATION TODO:
- Replace the switch with a function that should be called for each
date type.
- Remove sprintf and opencode the conversion, like we do in
Field_datetime.
*/
String
*
make_datetime
(
String
*
str
,
TIME
*
ltime
,
enum
date_time_format_types
format
)
{
...
...
@@ -898,8 +912,8 @@ String *Item_func_date_format::val_str(String *str)
null_value
=
1
;
return
0
;
}
length
=
my_sprintf
(
intbuff
,
(
intbuff
,
"%d"
,
l_time
.
day
))
;
str
->
append
(
intbuff
,
length
);
length
=
int10_to_str
(
l_time
.
day
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
if
(
l_time
.
day
>=
10
&&
l_time
.
day
<=
19
)
str
->
append
(
"th"
);
else
...
...
@@ -921,45 +935,45 @@ String *Item_func_date_format::val_str(String *str)
}
break
;
case
'Y'
:
sprintf
(
intbuff
,
"%04d"
,
l_time
.
year
)
;
str
->
append
(
intbuff
,
4
);
length
=
int10_to_str
(
l_time
.
year
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
4
,
'0'
);
break
;
case
'y'
:
sprintf
(
intbuff
,
"%02d"
,
l_time
.
year
%
100
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
l_time
.
year
%
100
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'm'
:
sprintf
(
intbuff
,
"%02d"
,
l_time
.
month
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
l_time
.
month
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'c'
:
sprintf
(
intbuff
,
"%d"
,
l_time
.
month
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
(
l_time
.
month
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
break
;
case
'd'
:
sprintf
(
intbuff
,
"%02d"
,
l_time
.
day
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
l_time
.
day
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'e'
:
sprintf
(
intbuff
,
"%d"
,
l_time
.
day
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
(
l_time
.
day
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
break
;
case
'f'
:
sprintf
(
intbuff
,
"%06ld"
,
l_time
.
second_part
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
(
l_time
.
second_part
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
6
,
'0'
);
break
;
case
'H'
:
sprintf
(
intbuff
,
"%02d"
,
l_time
.
hour
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
l_time
.
hour
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'h'
:
case
'I'
:
sprintf
(
intbuff
,
"%02d"
,
(
l_time
.
hour
+
11
)
%
12
+
1
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
((
l_time
.
hour
+
11
)
%
12
+
1
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'i'
:
/* minutes */
sprintf
(
intbuff
,
"%02d"
,
l_time
.
minute
)
;
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
l_time
.
minute
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'j'
:
if
(
date_or_time
)
...
...
@@ -967,52 +981,60 @@ String *Item_func_date_format::val_str(String *str)
null_value
=
1
;
return
0
;
}
sprintf
(
intbuff
,
"%03d"
,
(
int
)
(
calc_daynr
(
l_time
.
year
,
l_time
.
month
,
l_time
.
day
)
-
calc_daynr
(
l_time
.
year
,
1
,
1
))
+
1
);
str
->
append
(
intbuff
,
3
);
length
=
int10_to_str
(
calc_daynr
(
l_time
.
year
,
l_time
.
month
,
l_time
.
day
)
-
calc_daynr
(
l_time
.
year
,
1
,
1
)
+
1
,
intbuff
,
10
)
-
intbuff
;
str
->
append_with_prefill
(
intbuff
,
length
,
3
,
'0'
);
break
;
case
'k'
:
sprintf
(
intbuff
,
"%d"
,
l_time
.
hour
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
(
l_time
.
hour
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
break
;
case
'l'
:
sprintf
(
intbuff
,
"%d"
,
(
l_time
.
hour
+
11
)
%
12
+
1
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
((
l_time
.
hour
+
11
)
%
12
+
1
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
break
;
case
'p'
:
str
->
append
(
l_time
.
hour
<
12
?
"AM"
:
"PM"
,
2
);
break
;
case
'r'
:
sprintf
(
intbuff
,(
l_time
.
hour
<
12
)
?
"%02d:%02d:%02d AM"
:
"%02d:%02d:%02d PM"
,(
l_time
.
hour
+
11
)
%
12
+
1
,
l_time
.
minute
,
l_time
.
second
);
str
->
append
(
intbuff
);
length
=
my_sprintf
(
intbuff
,
(
intbuff
,
(
l_time
.
hour
<
12
)
?
"%02d:%02d:%02d AM"
:
"%02d:%02d:%02d PM"
,
(
l_time
.
hour
+
11
)
%
12
+
1
,
l_time
.
minute
,
l_time
.
second
));
str
->
append
(
intbuff
,
length
);
break
;
case
'S'
:
case
's'
:
sprintf
(
intbuff
,
"%02d"
,
l_time
.
second
)
;
str
->
append
(
intbuff
);
length
=
int10_to_str
(
l_time
.
second
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
break
;
case
'T'
:
sprintf
(
intbuff
,
"%02d:%02d:%02d"
,
l_time
.
hour
,
l_time
.
minute
,
l_time
.
second
);
str
->
append
(
intbuff
);
length
=
my_sprintf
(
intbuff
,
(
intbuff
,
"%02d:%02d:%02d"
,
l_time
.
hour
,
l_time
.
minute
,
l_time
.
second
));
str
->
append
(
intbuff
,
length
);
break
;
case
'U'
:
case
'u'
:
{
uint
year
;
sprintf
(
intbuff
,
"%02d"
,
calc_week
(
&
l_time
,
0
,
(
*
ptr
)
==
'U'
,
&
year
));
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
calc_week
(
&
l_time
,
0
,
(
*
ptr
)
==
'U'
,
&
year
),
intbuff
,
10
)
-
intbuff
;
str
->
append_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
}
break
;
case
'v'
:
case
'V'
:
{
uint
year
;
sprintf
(
intbuff
,
"%02d"
,
calc_week
(
&
l_time
,
1
,
(
*
ptr
)
==
'V'
,
&
year
));
str
->
append
(
intbuff
,
2
);
length
=
int10_to_str
(
calc_week
(
&
l_time
,
1
,
(
*
ptr
)
==
'V'
,
&
year
),
intbuff
,
10
)
-
intbuff
;
str
->
append_with_prefill
(
intbuff
,
length
,
2
,
'0'
);
}
break
;
case
'x'
:
...
...
@@ -1020,14 +1042,15 @@ String *Item_func_date_format::val_str(String *str)
{
uint
year
;
(
void
)
calc_week
(
&
l_time
,
1
,
(
*
ptr
)
==
'X'
,
&
year
);
sprintf
(
intbuff
,
"%04d"
,
year
)
;
str
->
append
(
intbuff
,
4
);
length
=
int10_to_str
(
year
,
intbuff
,
10
)
-
intbuff
;
str
->
append
_with_prefill
(
intbuff
,
length
,
4
,
'0'
);
}
break
;
case
'w'
:
weekday
=
calc_weekday
(
calc_daynr
(
l_time
.
year
,
l_time
.
month
,
l_time
.
day
),
1
);
sprintf
(
intbuff
,
"%d"
,
weekday
);
str
->
append
(
intbuff
,
1
);
length
=
int10_to_str
(
weekday
,
intbuff
,
10
)
-
intbuff
;
str
->
append_with_prefill
(
intbuff
,
length
,
1
,
'0'
);
break
;
default:
str
->
append
(
*
ptr
);
...
...
@@ -1109,7 +1132,7 @@ void Item_date_add_interval::fix_length_and_dec()
enum_field_types
arg0_field_type
;
set_charset
(
default_charset
());
maybe_null
=
1
;
max_length
=
26
*
default_charset
()
->
mbmaxlen
;
max_length
=
26
*
MY_CHARSET_BIN_MB_MAXLEN
;
value
.
alloc
(
32
);
/*
...
...
@@ -1197,13 +1220,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date)
ltime
->
hour
=
sec
/
3600
;
daynr
=
calc_daynr
(
ltime
->
year
,
ltime
->
month
,
1
)
+
days
;
get_date_from_daynr
(
daynr
,
&
ltime
->
year
,
&
ltime
->
month
,
&
ltime
->
day
);
if
(
daynr
<
0
||
daynr
>=
3652424
)
// Day number from year 0 to 9999-12-31
if
(
daynr
<
0
||
daynr
>=
MAX_DAY_NUMBER
)
// Day number from year 0 to 9999-12-31
goto
null_date
;
break
;
case
INTERVAL_DAY
:
period
=
calc_daynr
(
ltime
->
year
,
ltime
->
month
,
ltime
->
day
)
+
sign
*
interval
.
day
;
if
(
period
<
0
||
period
>=
3652424
)
// Daynumber from year 0 to 9999-12-31
if
(
period
<
0
||
period
>=
MAX_DAY_NUMBER
)
// Daynumber from year 0 to 9999-12-31
goto
null_date
;
get_date_from_daynr
((
long
)
period
,
&
ltime
->
year
,
&
ltime
->
month
,
&
ltime
->
day
);
break
;
...
...
@@ -1375,6 +1398,63 @@ void Item_typecast::print(String *str)
str
->
append
(
')'
);
}
String
*
Item_datetime_typecast
::
val_str
(
String
*
str
)
{
TIME
ltime
;
if
(
!
get_arg0_date
(
&
ltime
,
1
)
&&
make_datetime
(
str
,
&
ltime
,
ltime
.
second_part
?
DATE_TIME_MICROSECOND
:
DATE_TIME
))
return
str
;
null_date:
null_value
=
1
;
return
0
;
}
bool
Item_time_typecast
::
get_time
(
TIME
*
ltime
)
{
bool
res
=
get_arg0_time
(
ltime
);
ltime
->
time_type
=
TIMESTAMP_TIME
;
return
res
;
}
String
*
Item_time_typecast
::
val_str
(
String
*
str
)
{
TIME
ltime
;
if
(
!
get_arg0_time
(
&
ltime
)
&&
make_datetime
(
str
,
&
ltime
,
ltime
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
))
return
str
;
null_value
=
1
;
return
0
;
}
bool
Item_date_typecast
::
get_date
(
TIME
*
ltime
,
bool
fuzzy_date
)
{
bool
res
=
get_arg0_date
(
ltime
,
1
);
ltime
->
time_type
=
TIMESTAMP_DATE
;
return
res
;
}
String
*
Item_date_typecast
::
val_str
(
String
*
str
)
{
TIME
ltime
;
if
(
!
get_arg0_date
(
&
ltime
,
1
)
&&
make_datetime
(
str
,
&
ltime
,
DATE_ONLY
))
return
str
;
null_date:
null_value
=
1
;
return
0
;
}
/*
MAKEDATE(a,b) is a date function that creates a date value
from a year and day value.
...
...
@@ -1392,7 +1472,7 @@ String *Item_func_makedate::val_str(String *str)
goto
null_date
;
days
=
calc_daynr
(
yearnr
,
1
,
1
)
+
daynr
-
1
;
if
(
days
>
0
||
days
<
3652424L
)
// Day number from year 0 to 9999-12-31
if
(
days
>
0
||
days
<
MAX_DAY_NUMBER
)
// Day number from year 0 to 9999-12-31
{
null_value
=
0
;
get_date_from_daynr
(
days
,
&
l_time
.
year
,
&
l_time
.
month
,
&
l_time
.
day
);
...
...
@@ -1410,7 +1490,7 @@ void Item_func_add_time::fix_length_and_dec()
{
enum_field_types
arg0_field_type
;
decimals
=
0
;
max_length
=
26
*
my_charset_bin
.
mbmaxlen
;
max_length
=
26
*
MY_CHARSET_BIN_MB_MAXLEN
;
/*
The field type for the result of an Item_func_add_time function is defined as
...
...
@@ -1424,7 +1504,8 @@ void Item_func_add_time::fix_length_and_dec()
cached_field_type
=
MYSQL_TYPE_STRING
;
arg0_field_type
=
args
[
0
]
->
field_type
();
if
(
arg0_field_type
==
MYSQL_TYPE_DATETIME
||
if
(
arg0_field_type
==
MYSQL_TYPE_DATE
||
arg0_field_type
==
MYSQL_TYPE_DATETIME
||
arg0_field_type
==
MYSQL_TYPE_TIMESTAMP
)
cached_field_type
=
MYSQL_TYPE_DATETIME
;
else
if
(
arg0_field_type
==
MYSQL_TYPE_TIME
)
...
...
@@ -1443,20 +1524,28 @@ void Item_func_add_time::fix_length_and_dec()
String
*
Item_func_add_time
::
val_str
(
String
*
str
)
{
TIME
l_time1
,
l_time2
,
l_time3
;
bool
is_time
;
bool
is_time
=
0
;
long
microseconds
,
seconds
,
days
=
0
;
int
l_sign
=
sign
;
null_value
=
0
;
l_time3
.
neg
=
0
;
if
(
is_date
)
// TIMESTAMP function
{
if
(
get_arg0_date
(
&
l_time1
,
1
)
||
args
[
1
]
->
get_time
(
&
l_time2
)
||
l_time1
.
time_type
==
TIMESTAMP_TIME
||
l_time2
.
time_type
!=
TIMESTAMP_TIME
)
goto
null_date
;
}
else
// ADDTIME function
{
if
(
args
[
0
]
->
get_time
(
&
l_time1
)
||
args
[
1
]
->
get_time
(
&
l_time2
)
||
l_time2
.
time_type
==
TIMESTAMP_FULL
)
goto
null_date
;
is_time
=
(
l_time1
.
time_type
==
TIMESTAMP_TIME
);
l_time3
.
neg
=
0
;
if
(
is_time
)
{
if
((
l_time2
.
neg
==
l_time1
.
neg
)
&&
l_time1
.
neg
)
if
(
is_time
&&
(
l_time2
.
neg
==
l_time1
.
neg
&&
l_time1
.
neg
))
l_time3
.
neg
=
1
;
}
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
...
...
@@ -1504,13 +1593,17 @@ String *Item_func_add_time::val_str(String *str)
{
get_date_from_daynr
(
days
,
&
l_time3
.
year
,
&
l_time3
.
month
,
&
l_time3
.
day
);
if
(
l_time3
.
day
&&
make_datetime
(
str
,
&
l_time3
,
DATE_TIME_MICROSECOND
))
make_datetime
(
str
,
&
l_time3
,
l_time1
.
second_part
||
l_time2
.
second_part
?
DATE_TIME_MICROSECOND
:
DATE_TIME
))
return
str
;
goto
null_date
;
}
l_time3
.
hour
+=
days
*
24
;
if
(
make_datetime
(
str
,
&
l_time3
,
TIME_MICROSECOND
))
if
(
make_datetime
(
str
,
&
l_time3
,
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
))
return
str
;
null_date:
...
...
@@ -1578,7 +1671,9 @@ String *Item_func_timediff::val_str(String *str)
l_time3
.
neg
=
l_time3
.
neg
?
0
:
1
;
calc_time_from_sec
(
&
l_time3
,
seconds
,
microseconds
);
if
(
make_datetime
(
str
,
&
l_time3
,
TIME_MICROSECOND
))
if
(
make_datetime
(
str
,
&
l_time3
,
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
))
return
str
;
null_date:
...
...
@@ -1623,99 +1718,6 @@ null_date:
return
0
;
}
/*
TIMESTAMP(a,b) is a function ( extraction) that calculates a datetime value
comprising a date value, time value.
a: Date_or_datetime value
b: Time value
Result: Datetime value
*/
String
*
Item_func_timestamp
::
val_str
(
String
*
str
)
{
TIME
l_time1
,
l_time2
,
l_time3
;
long
seconds
;
long
microseconds
;
long
days
;
int
l_sign
;
if
(
get_arg0_date
(
&
l_time1
,
1
)
||
args
[
1
]
->
get_time
(
&
l_time2
)
||
l_time1
.
time_type
==
TIMESTAMP_TIME
||
l_time2
.
time_type
!=
TIMESTAMP_TIME
)
goto
null_date
;
l_sign
=
l_time2
.
neg
?
-
1
:
1
;
days
=
(
calc_daynr
((
uint
)
l_time1
.
year
,(
uint
)
l_time1
.
month
,
(
uint
)
l_time1
.
day
)
+
l_sign
*
l_time2
.
day
);
microseconds
=
l_time1
.
second_part
+
l_sign
*
l_time2
.
second_part
;
seconds
=
(
l_time1
.
hour
*
3600L
+
l_time1
.
minute
*
60L
+
l_time1
.
second
+
(
l_time2
.
day
*
86400L
+
l_time2
.
hour
*
3600L
+
l_time2
.
minute
*
60L
+
l_time2
.
second
)
*
l_sign
);
days
+=
seconds
/
86400L
;
seconds
%=
86400L
;
if
(
microseconds
<
0
)
{
microseconds
+=
1000000L
;
seconds
--
;
}
if
(
seconds
<
0
)
{
days
--
;
seconds
+=
86400L
;
}
if
(
days
<
0
)
goto
null_date
;
calc_time_from_sec
(
&
l_time3
,
seconds
,
microseconds
);
get_date_from_daynr
(
days
,
&
l_time3
.
year
,
&
l_time3
.
month
,
&
l_time3
.
day
);
make_datetime
(
str
,
&
l_time3
,
DATE_TIME_MICROSECOND
);
return
str
;
null_date:
null_value
=
1
;
return
0
;
}
/*
DATE(a) is a function ( extraction) that calculates a date value.
a: Datetime value
Result: Date value
*/
String
*
Item_func_date
::
val_str
(
String
*
str
)
{
TIME
ltime
;
if
(
!
get_arg0_date
(
&
ltime
,
1
)
&&
make_datetime
(
str
,
&
ltime
,
DATE_ONLY
))
return
str
;
null_date:
null_value
=
1
;
return
0
;
}
/*
TIME(a) is a function ( extraction) that calculates a time value.
a: Datetime value
Result: Time value
*/
String
*
Item_func_time
::
val_str
(
String
*
str
)
{
TIME
ltime
;
if
(
!
get_arg0_time
(
&
ltime
)
&&
make_datetime
(
str
,
&
ltime
,
TIME_MICROSECOND
))
return
str
;
null_value
=
1
;
return
0
;
}
/*
MICROSECOND(a) is a function ( extraction) that extracts the microseconds from a.
...
...
sql/item_timefunc.h
View file @
5709ed20
...
...
@@ -557,6 +557,8 @@ class Item_date_typecast :public Item_typecast
{
public:
Item_date_typecast
(
Item
*
a
)
:
Item_typecast
(
a
)
{}
String
*
val_str
(
String
*
str
);
bool
get_date
(
TIME
*
ltime
,
bool
fuzzy_date
);
const
char
*
func_name
()
const
{
return
"date"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATE
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
...
...
@@ -571,6 +573,8 @@ class Item_time_typecast :public Item_typecast
{
public:
Item_time_typecast
(
Item
*
a
)
:
Item_typecast
(
a
)
{}
String
*
val_str
(
String
*
str
);
bool
get_time
(
TIME
*
ltime
);
const
char
*
func_name
()
const
{
return
"time"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_TIME
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
...
...
@@ -585,6 +589,7 @@ class Item_datetime_typecast :public Item_typecast
{
public:
Item_datetime_typecast
(
Item
*
a
)
:
Item_typecast
(
a
)
{}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"datetime"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATETIME
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
...
...
@@ -604,7 +609,7 @@ public:
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
8
*
my_charset_bin
.
mbmaxlen
;
max_length
=
8
*
MY_CHARSET_BIN_MB_MAXLEN
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
...
...
@@ -613,18 +618,26 @@ public:
}
};
class
Item_func_add_time
:
public
Item_str_func
{
const
bool
is_date
;
int
sign
;
enum_field_types
cached_field_type
;
public:
Item_func_add_time
(
Item
*
a
,
Item
*
b
,
bool
neg_arg
)
:
Item_str_func
(
a
,
b
)
{
sign
=
neg_arg
?
-
1
:
1
;
}
Item_func_add_time
(
Item
*
a
,
Item
*
b
,
bool
type_arg
,
bool
neg_arg
)
:
Item_str_func
(
a
,
b
)
,
is_date
(
type_arg
)
{
sign
=
neg_arg
?
-
1
:
1
;
}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"addtime"
;
}
enum_field_types
field_type
()
const
{
return
cached_field_type
;
}
void
fix_length_and_dec
();
/*
TODO:
Change this when we support
microseconds in TIME/DATETIME
*/
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
{
...
...
@@ -647,7 +660,7 @@ public:
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
17
*
my_charset_bin
.
mbmaxlen
;
max_length
=
17
*
MY_CHARSET_BIN_MB_MAXLEN
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
...
...
@@ -667,66 +680,7 @@ public:
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
8
*
my_charset_bin
.
mbmaxlen
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
{
return
(
new
Field_time
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
};
class
Item_func_timestamp
:
public
Item_str_func
{
public:
Item_func_timestamp
(
Item
*
a
,
Item
*
b
)
:
Item_str_func
(
a
,
b
)
{}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"timestamp"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATETIME
;
}
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
26
*
my_charset_bin
.
mbmaxlen
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
{
return
(
new
Field_datetime
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
};
class
Item_func_date
:
public
Item_str_func
{
public:
Item_func_date
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"date"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATE
;
}
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
10
*
my_charset_bin
.
mbmaxlen
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
{
return
(
new
Field_date
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
};
class
Item_func_time
:
public
Item_str_func
{
public:
Item_func_time
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
String
*
val_str
(
String
*
str
);
const
char
*
func_name
()
const
{
return
"time"
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_TIME
;
}
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
15
*
my_charset_bin
.
mbmaxlen
;
max_length
=
8
*
MY_CHARSET_BIN_MB_MAXLEN
;
}
Field
*
tmp_table_field
()
{
return
result_field
;
}
Field
*
tmp_table_field
(
TABLE
*
t_arg
)
...
...
sql/mysql_priv.h
View file @
5709ed20
...
...
@@ -224,6 +224,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define RAID_BLOCK_SIZE 1024
#define MY_CHARSET_BIN_MB_MAXLEN 1
#ifdef EXTRA_DEBUG
/*
Sync points allow us to force the server to reach a certain line of code
...
...
sql/protocol.cc
View file @
5709ed20
...
...
@@ -823,6 +823,13 @@ bool Protocol_simple::store(Field *field)
}
/*
TODO:
Second_part format ("%06") needs to change when
we support 0-6 decimals for time.
*/
bool
Protocol_simple
::
store
(
TIME
*
tm
)
{
#ifndef DEBUG_OFF
...
...
@@ -863,6 +870,12 @@ bool Protocol_simple::store_date(TIME *tm)
}
/*
TODO:
Second_part format ("%06") needs to change when
we support 0-6 decimals for time.
*/
bool
Protocol_simple
::
store_time
(
TIME
*
tm
)
{
#ifndef DEBUG_OFF
...
...
sql/sql_string.cc
View file @
5709ed20
...
...
@@ -390,6 +390,23 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
return
FALSE
;
}
bool
String
::
append_with_prefill
(
const
char
*
s
,
uint32
arg_length
,
uint32
full_length
,
char
fill_char
)
{
int
t_length
=
arg_length
>
full_length
?
arg_length
:
full_length
;
if
(
realloc
(
str_length
+
t_length
))
return
TRUE
;
t_length
=
full_length
-
arg_length
;
if
(
t_length
>
0
)
{
bfill
(
Ptr
+
str_length
,
t_length
,
fill_char
);
str_length
=
str_length
+
t_length
;
}
append
(
s
,
arg_length
);
return
FALSE
;
}
uint32
String
::
numchars
()
{
return
str_charset
->
cset
->
numchars
(
str_charset
,
Ptr
,
Ptr
+
str_length
);
...
...
sql/sql_string.h
View file @
5709ed20
...
...
@@ -189,6 +189,8 @@ public:
bool
append
(
const
char
*
s
,
uint32
arg_length
=
0
);
bool
append
(
const
char
*
s
,
uint32
arg_length
,
CHARSET_INFO
*
cs
);
bool
append
(
IO_CACHE
*
file
,
uint32
arg_length
);
bool
append_with_prefill
(
const
char
*
s
,
uint32
arg_length
,
uint32
full_length
,
char
fill_char
);
int
strstr
(
const
String
&
search
,
uint32
offset
=
0
);
// Returns offset to substring or -1
int
strstr_case
(
const
String
&
s
,
uint32
offset
=
0
);
int
strrstr
(
const
String
&
search
,
uint32
offset
=
0
);
// Returns offset to substring or -1
...
...
sql/sql_yacc.yy
View file @
5709ed20
...
...
@@ -2381,7 +2381,7 @@ simple_expr:
Lex->safe_to_cache_query=0;
}
| DATE_SYM '(' expr ')'
{ $$= new Item_
func_date
($3); }
{ $$= new Item_
date_typecast
($3); }
| DAY_SYM '(' expr ')'
{ $$= new Item_func_dayofmonth($3); }
| ELT_FUNC '(' expr ',' expr_list ')'
...
...
@@ -2580,9 +2580,11 @@ simple_expr:
| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_substr_index($3,$5,$7); }
| TIME_SYM '(' expr ')'
{ $$= new Item_func_time($3); }
{ $$= new Item_time_typecast($3); }
| TIMESTAMP '(' expr ')'
{ $$= new Item_datetime_typecast($3); }
| TIMESTAMP '(' expr ',' expr ')'
{ $$= new Item_func_
timestamp($3, $5
); }
{ $$= new Item_func_
add_time($3, $5, 1, 0
); }
| TRIM '(' expr ')'
{ $$= new Item_func_trim($3); }
| TRIM '(' LEADING expr FROM expr ')'
...
...
@@ -4427,6 +4429,7 @@ keyword:
| MEDIUM_SYM {}
| MERGE_SYM {}
| MEMORY_SYM {}
| MICROSECOND_SYM {}
| MINUTE_SYM {}
| MIN_ROWS {}
| MODIFY_SYM {}
...
...
sql/time.cc
View file @
5709ed20
...
...
@@ -432,6 +432,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
l_time
->
minute
=
date
[
4
];
l_time
->
second
=
date
[
5
];
l_time
->
second_part
=
date
[
6
];
l_time
->
neg
=
0
;
DBUG_RETURN
(
l_time
->
time_type
=
(
number_of_fields
<=
3
?
TIMESTAMP_DATE
:
TIMESTAMP_FULL
));
}
...
...
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