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
f7179c44
Commit
f7179c44
authored
Oct 15, 2018
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-17460 Move the code from Item_extract::val_int() to a new class Extract_source
parent
1c5fd80a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
176 additions
and
114 deletions
+176
-114
sql/item_timefunc.cc
sql/item_timefunc.cc
+32
-56
sql/item_timefunc.h
sql/item_timefunc.h
+26
-37
sql/sql_time.cc
sql/sql_time.cc
+0
-20
sql/sql_time.h
sql/sql_time.h
+0
-1
sql/sql_type.h
sql/sql_type.h
+118
-0
No files found.
sql/item_timefunc.cc
View file @
f7179c44
...
...
@@ -2119,69 +2119,45 @@ bool Item_extract::fix_length_and_dec()
}
longlong
Item_extract
::
val_int
()
uint
Extract_source
::
week
(
THD
*
thd
)
const
{
DBUG_ASSERT
(
fixed
==
1
);
MYSQL_TIME
ltime
;
DBUG_ASSERT
(
is_valid_extract_source
());
uint
year
;
ulong
week_format
;
long
neg
;
date_mode_t
is_time_flag
=
date_value
?
date_mode_t
(
0
)
:
TIME_TIME_ONLY
;
// Not using get_arg0_date to avoid automatic TIME to DATETIME conversion
if
((
null_value
=
args
[
0
]
->
get_date
(
current_thd
,
&
ltime
,
is_time_flag
)))
return
0
;
neg
=
ltime
.
neg
?
-
1
:
1
;
ulong
week_format
=
current_thd
->
variables
.
default_week_format
;
return
calc_week
(
this
,
week_mode
(
week_format
),
&
year
);
}
DBUG_ASSERT
(
ltime
.
time_type
!=
MYSQL_TIMESTAMP_TIME
||
ltime
.
day
==
0
);
if
(
ltime
.
time_type
==
MYSQL_TIMESTAMP_TIME
)
time_to_daytime_interval
(
&
ltime
);
longlong
Item_extract
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
Extract_source
dt
(
current_thd
,
args
[
0
],
m_date_mode
);
if
((
null_value
=
!
dt
.
is_valid_extract_source
()))
return
0
;
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
+
2
)
/
3
;
case
INTERVAL_MONTH
:
return
ltime
.
month
;
case
INTERVAL_WEEK
:
{
week_format
=
current_thd
->
variables
.
default_week_format
;
return
calc_week
(
&
ltime
,
week_mode
(
week_format
),
&
year
);
}
case
INTERVAL_DAY
:
return
(
long
)
ltime
.
day
*
neg
;
case
INTERVAL_DAY_HOUR
:
return
(
long
)
(
ltime
.
day
*
100L
+
ltime
.
hour
)
*
neg
;
case
INTERVAL_DAY_MINUTE
:
return
(
long
)
(
ltime
.
day
*
10000L
+
ltime
.
hour
*
100L
+
ltime
.
minute
)
*
neg
;
case
INTERVAL_DAY_SECOND
:
return
((
longlong
)
ltime
.
day
*
1000000L
+
(
longlong
)
(
ltime
.
hour
*
10000L
+
ltime
.
minute
*
100
+
ltime
.
second
))
*
neg
;
case
INTERVAL_HOUR
:
return
(
long
)
ltime
.
hour
*
neg
;
case
INTERVAL_HOUR_MINUTE
:
return
(
long
)
(
ltime
.
hour
*
100
+
ltime
.
minute
)
*
neg
;
case
INTERVAL_HOUR_SECOND
:
return
(
long
)
(
ltime
.
hour
*
10000
+
ltime
.
minute
*
100
+
ltime
.
second
)
*
neg
;
case
INTERVAL_MINUTE
:
return
(
long
)
ltime
.
minute
*
neg
;
case
INTERVAL_MINUTE_SECOND
:
return
(
long
)
(
ltime
.
minute
*
100
+
ltime
.
second
)
*
neg
;
case
INTERVAL_SECOND
:
return
(
long
)
ltime
.
second
*
neg
;
case
INTERVAL_MICROSECOND
:
return
(
long
)
ltime
.
second_part
*
neg
;
case
INTERVAL_DAY_MICROSECOND
:
return
(((
longlong
)
ltime
.
day
*
1000000L
+
(
longlong
)
ltime
.
hour
*
10000L
+
ltime
.
minute
*
100
+
ltime
.
second
)
*
1000000L
+
ltime
.
second_part
)
*
neg
;
case
INTERVAL_HOUR_MICROSECOND
:
return
(((
longlong
)
ltime
.
hour
*
10000L
+
ltime
.
minute
*
100
+
ltime
.
second
)
*
1000000L
+
ltime
.
second_part
)
*
neg
;
case
INTERVAL_MINUTE_MICROSECOND
:
return
(((
longlong
)(
ltime
.
minute
*
100
+
ltime
.
second
))
*
1000000L
+
ltime
.
second_part
)
*
neg
;
case
INTERVAL_SECOND_MICROSECOND
:
return
((
longlong
)
ltime
.
second
*
1000000L
+
ltime
.
second_part
)
*
neg
;
case
INTERVAL_YEAR
:
return
dt
.
year
();
case
INTERVAL_YEAR_MONTH
:
return
dt
.
year_month
();
case
INTERVAL_QUARTER
:
return
dt
.
quarter
();
case
INTERVAL_MONTH
:
return
dt
.
month
();
case
INTERVAL_WEEK
:
return
dt
.
week
(
current_thd
);
case
INTERVAL_DAY
:
return
dt
.
day
();
case
INTERVAL_DAY_HOUR
:
return
dt
.
day_hour
();
case
INTERVAL_DAY_MINUTE
:
return
dt
.
day_minute
();
case
INTERVAL_DAY_SECOND
:
return
dt
.
day_second
();
case
INTERVAL_HOUR
:
return
dt
.
hour
();
case
INTERVAL_HOUR_MINUTE
:
return
dt
.
hour_minute
();
case
INTERVAL_HOUR_SECOND
:
return
dt
.
hour_second
();
case
INTERVAL_MINUTE
:
return
dt
.
minute
();
case
INTERVAL_MINUTE_SECOND
:
return
dt
.
minute_second
();
case
INTERVAL_SECOND
:
return
dt
.
second
();
case
INTERVAL_MICROSECOND
:
return
dt
.
microsecond
();
case
INTERVAL_DAY_MICROSECOND
:
return
dt
.
day_microsecond
();
case
INTERVAL_HOUR_MICROSECOND
:
return
dt
.
hour_microsecond
();
case
INTERVAL_MINUTE_MICROSECOND
:
return
dt
.
minute_microsecond
();
case
INTERVAL_SECOND_MICROSECOND
:
return
dt
.
second_microsecond
();
case
INTERVAL_LAST
:
DBUG_ASSERT
(
0
);
break
;
/* purecov: deadcode */
}
return
0
;
// Impossible
return
0
;
// Impossible
}
bool
Item_extract
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
...
...
sql/item_timefunc.h
View file @
f7179c44
...
...
@@ -964,9 +964,17 @@ class Item_date_add_interval :public Item_handled_func
};
class
Item_extract
:
public
Item_int_func
class
Item_extract
:
public
Item_int_func
,
public
Type_handler_hybrid_field_type
{
bool
date_value
;
date_mode_t
m_date_mode
;
const
Type_handler_int_result
*
handler_by_length
(
uint32
length
,
uint32
threashold
)
{
if
(
length
>=
threashold
)
return
&
type_handler_longlong
;
return
&
type_handler_long
;
}
void
set_date_length
(
uint32
length
)
{
/*
...
...
@@ -975,53 +983,34 @@ class Item_extract :public Item_int_func
because all around the code we assume that max_length is sign inclusive.
Another options is to set unsigned_flag to "true".
*/
max_length
=
length
;
//
QQ: see above
date_value
=
true
;
set_handler
(
handler_by_length
(
max_length
=
length
,
10
));
//
QQ: see above
m_date_mode
=
date_mode_t
(
0
)
;
}
void
set_day_length
(
uint32
length
)
{
max_length
=
length
+
1
/*sign*/
;
// e.g. '-24:00:00' -> -1
date_value
=
true
;
/*
Units starting with DAY can be negative:
EXTRACT(DAY FROM '-24:00:00') -> -1
*/
set_handler
(
handler_by_length
(
max_length
=
length
+
1
/*sign*/
,
11
));
m_date_mode
=
date_mode_t
(
0
);
}
void
set_time_length
(
uint32
length
)
{
max_length
=
length
+
1
/*sign*/
;
date_value
=
false
;
set_handler
(
handler_by_length
(
max_length
=
length
+
1
/*sign*/
,
11
))
;
m_date_mode
=
TIME_TIME_ONLY
;
}
public:
const
interval_type
int_type
;
// keep it public
Item_extract
(
THD
*
thd
,
interval_type
type_arg
,
Item
*
a
)
:
Item_int_func
(
thd
,
a
),
int_type
(
type_arg
)
{}
Item_int_func
(
thd
,
a
),
Type_handler_hybrid_field_type
(
&
type_handler_longlong
),
m_date_mode
(
date_mode_t
(
0
)),
int_type
(
type_arg
)
{
}
const
Type_handler
*
type_handler
()
const
{
switch
(
int_type
)
{
case
INTERVAL_YEAR
:
case
INTERVAL_YEAR_MONTH
:
case
INTERVAL_QUARTER
:
case
INTERVAL_MONTH
:
case
INTERVAL_WEEK
:
case
INTERVAL_DAY
:
case
INTERVAL_DAY_HOUR
:
case
INTERVAL_DAY_MINUTE
:
case
INTERVAL_DAY_SECOND
:
case
INTERVAL_HOUR
:
case
INTERVAL_HOUR_MINUTE
:
case
INTERVAL_HOUR_SECOND
:
case
INTERVAL_MINUTE
:
case
INTERVAL_MINUTE_SECOND
:
case
INTERVAL_SECOND
:
case
INTERVAL_MICROSECOND
:
case
INTERVAL_SECOND_MICROSECOND
:
return
&
type_handler_long
;
case
INTERVAL_DAY_MICROSECOND
:
case
INTERVAL_HOUR_MICROSECOND
:
case
INTERVAL_MINUTE_MICROSECOND
:
return
&
type_handler_longlong
;
case
INTERVAL_LAST
:
break
;
}
DBUG_ASSERT
(
0
);
return
&
type_handler_longlong
;
return
Type_handler_hybrid_field_type
::
type_handler
();
}
longlong
val_int
();
enum
Functype
functype
()
const
{
return
EXTRACT_FUNC
;
}
...
...
sql/sql_time.cc
View file @
f7179c44
...
...
@@ -1218,26 +1218,6 @@ bool time_to_datetime(MYSQL_TIME *ltime)
}
/*
Convert a TIME value to DAY-TIME interval, e.g. for extraction:
EXTRACT(DAY FROM x), EXTRACT(HOUR FROM x), etc.
Moves full days from ltime->hour to ltime->day.
Note, time_type is set to MYSQL_TIMESTAMP_NONE, to make sure that
the structure is not used for anything else other than extraction:
non-extraction TIME functions expect zero day value!
*/
void
time_to_daytime_interval
(
MYSQL_TIME
*
ltime
)
{
DBUG_ASSERT
(
ltime
->
time_type
==
MYSQL_TIMESTAMP_TIME
);
DBUG_ASSERT
(
ltime
->
year
==
0
);
DBUG_ASSERT
(
ltime
->
month
==
0
);
DBUG_ASSERT
(
ltime
->
day
==
0
);
ltime
->
day
=
ltime
->
hour
/
24
;
ltime
->
hour
%=
24
;
ltime
->
time_type
=
MYSQL_TIMESTAMP_NONE
;
}
/*** Conversion from TIME to DATETIME ***/
/*
...
...
sql/sql_time.h
View file @
f7179c44
...
...
@@ -36,7 +36,6 @@ ulong convert_period_to_month(ulong period);
ulong
convert_month_to_period
(
ulong
month
);
void
set_current_date
(
THD
*
thd
,
MYSQL_TIME
*
to
);
bool
time_to_datetime
(
MYSQL_TIME
*
ltime
);
void
time_to_daytime_interval
(
MYSQL_TIME
*
l_time
);
bool
get_date_from_daynr
(
long
daynr
,
uint
*
year
,
uint
*
month
,
uint
*
day
);
my_time_t
TIME_to_timestamp
(
THD
*
thd
,
const
MYSQL_TIME
*
t
,
uint
*
error_code
);
bool
str_to_datetime_with_warn
(
THD
*
thd
,
...
...
sql/sql_type.h
View file @
f7179c44
...
...
@@ -478,6 +478,10 @@ class Temporal: protected MYSQL_TIME
second
<=
TIME_MAX_SECOND
&&
second_part
<=
TIME_MAX_SECOND_PART
;
}
bool
has_zero_YYYYMM
()
const
{
return
year
==
0
&&
month
==
0
;
}
bool
has_zero_YYYYMMDD
()
const
{
return
year
==
0
&&
month
==
0
&&
day
==
0
;
...
...
@@ -556,6 +560,120 @@ class Temporal_hybrid: public Temporal
};
/*
This class resembles the SQL standard <extract source>,
used in extract expressions, e.g: EXTRACT(DAY FROM dt)
<extract expression> ::=
EXTRACT <left paren> <extract field> FROM <extract source> <right paren>
<extract source> ::= <datetime value expression> | <interval value expression>
*/
class
Extract_source
:
public
Temporal_hybrid
{
/*
Convert a TIME value to DAY-TIME interval, e.g. for extraction:
EXTRACT(DAY FROM x), EXTRACT(HOUR FROM x), etc.
Moves full days from ltime->hour to ltime->day.
*/
void
time_to_daytime_interval
()
{
DBUG_ASSERT
(
time_type
==
MYSQL_TIMESTAMP_TIME
);
DBUG_ASSERT
(
has_zero_YYYYMMDD
());
MYSQL_TIME
::
day
=
MYSQL_TIME
::
hour
/
24
;
MYSQL_TIME
::
hour
%=
24
;
}
bool
is_valid_extract_source_slow
()
const
{
return
is_valid_temporal
()
&&
MYSQL_TIME
::
hour
<
24
&&
(
has_zero_YYYYMM
()
||
time_type
!=
MYSQL_TIMESTAMP_TIME
);
}
bool
is_valid_value_slow
()
const
{
return
time_type
==
MYSQL_TIMESTAMP_NONE
||
is_valid_extract_source_slow
();
}
public:
Extract_source
(
THD
*
thd
,
Item
*
item
,
date_mode_t
mode
)
:
Temporal_hybrid
(
thd
,
item
,
mode
)
{
if
(
MYSQL_TIME
::
time_type
==
MYSQL_TIMESTAMP_TIME
)
time_to_daytime_interval
();
DBUG_ASSERT
(
is_valid_value_slow
());
}
inline
const
MYSQL_TIME
*
get_mysql_time
()
const
{
DBUG_ASSERT
(
is_valid_extract_source_slow
());
return
this
;
}
bool
is_valid_extract_source
()
const
{
return
is_valid_temporal
();
}
int
sign
()
const
{
return
get_mysql_time
()
->
neg
?
-
1
:
1
;
}
uint
year
()
const
{
return
get_mysql_time
()
->
year
;
}
uint
month
()
const
{
return
get_mysql_time
()
->
month
;
}
int
day
()
const
{
return
(
int
)
get_mysql_time
()
->
day
*
sign
();
}
int
hour
()
const
{
return
(
int
)
get_mysql_time
()
->
hour
*
sign
();
}
int
minute
()
const
{
return
(
int
)
get_mysql_time
()
->
minute
*
sign
();
}
int
second
()
const
{
return
(
int
)
get_mysql_time
()
->
second
*
sign
();
}
int
microsecond
()
const
{
return
(
int
)
get_mysql_time
()
->
second_part
*
sign
();
}
uint
year_month
()
const
{
return
year
()
*
100
+
month
();
}
uint
quarter
()
const
{
return
(
month
()
+
2
)
/
3
;
}
uint
week
(
THD
*
thd
)
const
;
longlong
second_microsecond
()
const
{
return
(
second
()
*
1000000LL
+
microsecond
());
}
// DAY TO XXX
longlong
day_hour
()
const
{
return
(
longlong
)
day
()
*
100LL
+
hour
();
}
longlong
day_minute
()
const
{
return
day_hour
()
*
100LL
+
minute
();
}
longlong
day_second
()
const
{
return
day_minute
()
*
100LL
+
second
();
}
longlong
day_microsecond
()
const
{
return
day_second
()
*
1000000LL
+
microsecond
();
}
// HOUR TO XXX
int
hour_minute
()
const
{
return
hour
()
*
100
+
minute
();
}
int
hour_second
()
const
{
return
hour_minute
()
*
100
+
second
();
}
longlong
hour_microsecond
()
const
{
return
hour_second
()
*
1000000LL
+
microsecond
();
}
// MINUTE TO XXX
int
minute_second
()
const
{
return
minute
()
*
100
+
second
();
}
longlong
minute_microsecond
()
const
{
return
minute_second
()
*
1000000LL
+
microsecond
();
}
};
/*
This class is used for the "time_interval" argument of these SQL functions:
TIMESTAMP(tm,time_interval)
ADDTIME(tm,time_interval)
Features:
- DATE and DATETIME formats are treated as errors
- Preserves hours for TIME format as is, without limiting to TIME_MAX_HOUR
*/
class
Interval_DDhhmmssff
:
public
Temporal
{
static
const
LEX_CSTRING
m_type_name
;
...
...
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