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
21a58840
Commit
21a58840
authored
Nov 20, 2018
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-17776 CAST(x AS INTERVAL DAY_SECOND(N))
parent
dde2ca4a
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
353 additions
and
86 deletions
+353
-86
include/my_time.h
include/my_time.h
+1
-0
mysql-test/main/func_extract.result
mysql-test/main/func_extract.result
+89
-52
mysql-test/main/func_extract.test
mysql-test/main/func_extract.test
+8
-1
mysql-test/main/type_interval.result
mysql-test/main/type_interval.result
+83
-0
mysql-test/main/type_interval.test
mysql-test/main/type_interval.test
+54
-0
sql-common/my_time.c
sql-common/my_time.c
+42
-33
sql/item_timefunc.h
sql/item_timefunc.h
+18
-0
sql/sql_type.cc
sql/sql_type.cc
+16
-0
sql/sql_type.h
sql/sql_type.h
+34
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+4
-0
sql/sql_yacc_ora.yy
sql/sql_yacc_ora.yy
+4
-0
No files found.
include/my_time.h
View file @
21a58840
...
...
@@ -208,6 +208,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
#define MAX_DATE_STRING_REP_LENGTH 30
#define AUTO_SEC_PART_DIGITS DECIMAL_NOT_SPECIFIED
int
my_interval_DDhhmmssff_to_str
(
const
MYSQL_TIME
*
,
char
*
to
,
uint
digits
);
int
my_time_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
,
uint
digits
);
int
my_date_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
);
int
my_datetime_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
,
uint
digits
);
...
...
mysql-test/main/func_extract.result
View file @
21a58840
This diff is collapsed.
Click to expand it.
mysql-test/main/func_extract.test
View file @
21a58840
...
...
@@ -65,6 +65,7 @@ SELECT a, b, EXTRACT(MICROSECOND FROM a), EXTRACT(MICROSECOND FROM b) FROM t1 WH
--
echo
# Detailed results
SELECT
a
,
CAST
(
a
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cidm
,
EXTRACT
(
DAY
FROM
a
)
*
24
+
EXTRACT
(
HOUR
FROM
a
)
AS
dh
,
EXTRACT
(
DAY_HOUR
FROM
a
),
EXTRACT
(
DAY
FROM
a
),
...
...
@@ -75,6 +76,7 @@ SELECT
FROM
t1
;
SELECT
b
,
CAST
(
b
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cidm
,
EXTRACT
(
DAY
FROM
b
)
*
24
+
EXTRACT
(
HOUR
FROM
b
)
AS
dh
,
EXTRACT
(
DAY_HOUR
FROM
b
),
EXTRACT
(
DAY
FROM
b
),
...
...
@@ -105,6 +107,7 @@ DROP TABLE t1;
CREATE
TABLE
t1
(
a
VARCHAR
(
64
));
INSERT
INTO
t1
VALUES
(
''
);
SELECT
a
,
CAST
(
a
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cidm
,
EXTRACT
(
DAY_HOUR
FROM
a
),
EXTRACT
(
DAY_MINUTE
FROM
a
),
EXTRACT
(
DAY_SECOND
FROM
a
),
...
...
@@ -246,5 +249,9 @@ INSERT INTO t1 VALUES
(
'01:02:03/'
),
(
'20 10:20:30'
);
SELECT
EXTRACT
(
DAY
FROM
a
),
EXTRACT
(
DAY_SECOND
FROM
a
),
a
FROM
t1
;
SELECT
EXTRACT
(
DAY
FROM
a
),
EXTRACT
(
DAY_SECOND
FROM
a
),
a
,
CAST
(
a
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cidm
FROM
t1
;
DROP
TABLE
t1
;
mysql-test/main/type_interval.result
0 → 100644
View file @
21a58840
#
# Start of 10.4 tests
#
#
# MDEV-17776 CAST(x AS INTERVAL DAY_SECOND(N))
#
CREATE TABLE t1 (a VARCHAR(128));
INSERT INTO t1 VALUES
('00:00:00'),
('+00:00:01'),
('-00:00:01'),
('838:59:59'),
('839:00:00'),
('2018:01:02'),
('87649415:59:59'),
('3652058 23:59:59'),
('87649416:00:00'),
('3652059 00:00:00');
SELECT
EXTRACT(DAY FROM a) AS d,
EXTRACT(HOUR FROM a) AS h,
a,
CAST(a AS INTERVAL DAY_SECOND(6)) AS cast_itds
FROM t1;
d h a cast_itds
0 0 00:00:00 00:00:00.000000
0 0 +00:00:01 00:00:01.000000
0 0 -00:00:01 -00:00:01.000000
34 22 838:59:59 34 22:59:59.000000
34 23 839:00:00 34 23:00:00.000000
84 2 2018:01:02 84 02:01:02.000000
3652058 23 87649415:59:59 3652058 23:59:59.000000
3652058 23 3652058 23:59:59 3652058 23:59:59.000000
NULL NULL 87649416:00:00 NULL
NULL NULL 3652059 00:00:00 NULL
Warnings:
Warning 1292 Incorrect interval value: '87649416:00:00'
Warning 1292 Incorrect interval value: '87649416:00:00'
Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649416:00:00'
Warning 1292 Incorrect interval value: '3652059 00:00:00'
Warning 1292 Incorrect interval value: '3652059 00:00:00'
Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '3652059 00:00:00'
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(32,9));
INSERT INTO t1 VALUES
(0),
(1),
(-1),
(8385959),
(8390000),
(20180102),
(876494155959),
(876494160000);
SELECT
EXTRACT(DAY FROM a) AS d,
EXTRACT(HOUR FROM a) AS h,
a,
CAST(a AS INTERVAL DAY_SECOND(6)) AS cast_itds
FROM t1;
d h a cast_itds
0 0 0.000000000 00:00:00.000000
0 0 1.000000000 00:00:01.000000
0 0 -1.000000000 -00:00:01.000000
34 22 8385959.000000000 34 22:59:59.000000
34 23 8390000.000000000 34 23:00:00.000000
84 2 20180102.000000000 84 02:01:02.000000
3652058 23 876494155959.000000000 3652058 23:59:59.000000
NULL NULL 876494160000.000000000 NULL
Warnings:
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '1.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '-1.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8390000.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '20180102.000000000'
Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494155959.000000000'
Warning 1292 Incorrect interval value: '876494160000.000000000' for column 'a' at row 8
Warning 1292 Incorrect interval value: '876494160000.000000000' for column 'a' at row 8
Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '876494160000.000000000'
DROP TABLE t1;
#
# End of 10.4 tests
#
mysql-test/main/type_interval.test
0 → 100644
View file @
21a58840
--
echo
#
--
echo
# Start of 10.4 tests
--
echo
#
--
echo
#
--
echo
# MDEV-17776 CAST(x AS INTERVAL DAY_SECOND(N))
--
echo
#
CREATE
TABLE
t1
(
a
VARCHAR
(
128
));
INSERT
INTO
t1
VALUES
(
'00:00:00'
),
(
'+00:00:01'
),
(
'-00:00:01'
),
(
'838:59:59'
),
(
'839:00:00'
),
(
'2018:01:02'
),
(
'87649415:59:59'
),
(
'3652058 23:59:59'
),
(
'87649416:00:00'
),
(
'3652059 00:00:00'
);
SELECT
EXTRACT
(
DAY
FROM
a
)
AS
d
,
EXTRACT
(
HOUR
FROM
a
)
AS
h
,
a
,
CAST
(
a
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cast_itds
FROM
t1
;
DROP
TABLE
t1
;
CREATE
TABLE
t1
(
a
DECIMAL
(
32
,
9
));
INSERT
INTO
t1
VALUES
(
0
),
(
1
),
(
-
1
),
(
8385959
),
(
8390000
),
(
20180102
),
(
876494155959
),
(
876494160000
);
SELECT
EXTRACT
(
DAY
FROM
a
)
AS
d
,
EXTRACT
(
HOUR
FROM
a
)
AS
h
,
a
,
CAST
(
a
AS
INTERVAL
DAY_SECOND
(
6
))
AS
cast_itds
FROM
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# End of 10.4 tests
--
echo
#
sql-common/my_time.c
View file @
21a58840
...
...
@@ -1465,6 +1465,46 @@ static char* fmt_number(uint val, char *out, uint digits)
}
static
int
my_mmssff_to_str
(
const
MYSQL_TIME
*
ltime
,
char
*
to
,
uint
fsp
)
{
char
*
pos
=
to
;
if
(
fsp
==
AUTO_SEC_PART_DIGITS
)
fsp
=
ltime
->
second_part
?
TIME_SECOND_PART_DIGITS
:
0
;
DBUG_ASSERT
(
fsp
<=
TIME_SECOND_PART_DIGITS
);
pos
=
fmt_number
(
ltime
->
minute
,
pos
,
2
);
*
pos
++=
':'
;
pos
=
fmt_number
(
ltime
->
second
,
pos
,
2
);
if
(
fsp
)
{
*
pos
++=
'.'
;
pos
=
fmt_number
((
uint
)
sec_part_shift
(
ltime
->
second_part
,
fsp
),
pos
,
fsp
);
}
return
(
int
)
(
pos
-
to
);
}
int
my_interval_DDhhmmssff_to_str
(
const
MYSQL_TIME
*
ltime
,
char
*
to
,
uint
fsp
)
{
uint
hour
=
ltime
->
day
*
24
+
ltime
->
hour
;
char
*
pos
=
to
;
DBUG_ASSERT
(
!
ltime
->
year
);
DBUG_ASSERT
(
!
ltime
->
month
);
if
(
ltime
->
neg
)
*
pos
++=
'-'
;
if
(
hour
>=
24
)
{
pos
=
longlong10_to_str
((
longlong
)
hour
/
24
,
pos
,
10
);
*
pos
++=
' '
;
}
pos
=
fmt_number
(
hour
%
24
,
pos
,
2
);
*
pos
++=
':'
;
pos
+=
my_mmssff_to_str
(
ltime
,
pos
,
fsp
);
*
pos
=
0
;
return
(
int
)
(
pos
-
to
);
}
/*
Functions to convert time/date/datetime value to a string,
using default format.
...
...
@@ -1482,11 +1522,6 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
uint
hour
=
day
*
24
+
l_time
->
hour
;
char
*
pos
=
to
;
if
(
digits
==
AUTO_SEC_PART_DIGITS
)
digits
=
l_time
->
second_part
?
TIME_SECOND_PART_DIGITS
:
0
;
DBUG_ASSERT
(
digits
<=
TIME_SECOND_PART_DIGITS
);
if
(
l_time
->
neg
)
*
pos
++=
'-'
;
...
...
@@ -1497,17 +1532,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
pos
=
fmt_number
(
hour
,
pos
,
2
);
*
pos
++=
':'
;
pos
=
fmt_number
(
l_time
->
minute
,
pos
,
2
);
*
pos
++=
':'
;
pos
=
fmt_number
(
l_time
->
second
,
pos
,
2
);
if
(
digits
)
{
*
pos
++=
'.'
;
pos
=
fmt_number
((
uint
)
sec_part_shift
(
l_time
->
second_part
,
digits
),
pos
,
digits
);
}
pos
+=
my_mmssff_to_str
(
l_time
,
pos
,
digits
);
*
pos
=
0
;
return
(
int
)
(
pos
-
to
);
}
...
...
@@ -1529,12 +1554,6 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to)
int
my_datetime_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
,
uint
digits
)
{
char
*
pos
=
to
;
if
(
digits
==
AUTO_SEC_PART_DIGITS
)
digits
=
l_time
->
second_part
?
TIME_SECOND_PART_DIGITS
:
0
;
DBUG_ASSERT
(
digits
<=
TIME_SECOND_PART_DIGITS
);
pos
=
fmt_number
(
l_time
->
year
,
pos
,
4
);
*
pos
++=
'-'
;
pos
=
fmt_number
(
l_time
->
month
,
pos
,
2
);
...
...
@@ -1543,17 +1562,7 @@ int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
*
pos
++=
' '
;
pos
=
fmt_number
(
l_time
->
hour
,
pos
,
2
);
*
pos
++=
':'
;
pos
=
fmt_number
(
l_time
->
minute
,
pos
,
2
);
*
pos
++=
':'
;
pos
=
fmt_number
(
l_time
->
second
,
pos
,
2
);
if
(
digits
)
{
*
pos
++=
'.'
;
pos
=
fmt_number
((
uint
)
sec_part_shift
(
l_time
->
second_part
,
digits
),
pos
,
digits
);
}
pos
+=
my_mmssff_to_str
(
l_time
,
pos
,
digits
);
*
pos
=
0
;
return
(
int
)(
pos
-
to
);
}
...
...
sql/item_timefunc.h
View file @
21a58840
...
...
@@ -1106,6 +1106,24 @@ class Item_char_typecast :public Item_str_func
};
class
Item_interval_DDhhmmssff_typecast
:
public
Item_char_typecast
{
uint
m_fsp
;
public:
Item_interval_DDhhmmssff_typecast
(
THD
*
thd
,
Item
*
a
,
uint
fsp
)
:
Item_char_typecast
(
thd
,
a
,
Interval_DDhhmmssff
::
max_char_length
(
fsp
),
&
my_charset_latin1
),
m_fsp
(
fsp
)
{
}
String
*
val_str
(
String
*
to
)
{
Interval_DDhhmmssff
it
(
current_thd
,
args
[
0
]);
null_value
=
!
it
.
is_valid_interval_DDhhmmssff
();
return
it
.
to_string
(
to
,
m_fsp
);
}
};
class
Item_date_typecast
:
public
Item_datefunc
{
public:
...
...
sql/sql_type.cc
View file @
21a58840
...
...
@@ -68,6 +68,8 @@ Type_handler_long_blob type_handler_long_blob;
Type_handler_blob
type_handler_blob
;
static
Type_handler_blob_compressed
type_handler_blob_compressed
;
Type_handler_interval_DDhhmmssff
type_handler_interval_DDhhmmssff
;
#ifdef HAVE_SPATIAL
Type_handler_geometry
type_handler_geometry
;
#endif
...
...
@@ -6568,6 +6570,20 @@ Item *Type_handler_long_blob::
return
new
(
thd
->
mem_root
)
Item_char_typecast
(
thd
,
item
,
len
,
real_cs
);
}
Item
*
Type_handler_interval_DDhhmmssff
::
create_typecast_item
(
THD
*
thd
,
Item
*
item
,
const
Type_cast_attributes
&
attr
)
const
{
if
(
attr
.
decimals
()
>
MAX_DATETIME_PRECISION
)
{
wrong_precision_error
(
ER_TOO_BIG_PRECISION
,
item
,
attr
.
decimals
(),
MAX_DATETIME_PRECISION
);
return
0
;
}
return
new
(
thd
->
mem_root
)
Item_interval_DDhhmmssff_typecast
(
thd
,
item
,
attr
.
decimals
());
}
/***************************************************************************/
void
Type_handler_string_result
::
Item_param_setup_conversion
(
THD
*
thd
,
...
...
sql/sql_type.h
View file @
21a58840
...
...
@@ -954,6 +954,16 @@ class Interval_DDhhmmssff: public Temporal
{
return
TIME_MAX_INTERVAL_HOUR
;
}
static
uint
max_int_part_char_length
()
{
// e.g. '+3652058 23:59:59'
return
1
/*sign*/
+
TIME_MAX_INTERVAL_DAY_CHAR_LENGTH
+
1
+
8
/*hh:mm:ss*/
;
}
static
uint
max_char_length
(
uint
fsp
)
{
DBUG_ASSERT
(
fsp
<=
TIME_SECOND_PART_DIGITS
);
return
max_int_part_char_length
()
+
(
fsp
?
1
:
0
)
+
fsp
;
}
public:
Interval_DDhhmmssff
(
THD
*
thd
,
Status
*
st
,
bool
push_warnings
,
Item
*
item
,
ulong
max_hour
);
...
...
@@ -975,6 +985,17 @@ class Interval_DDhhmmssff: public Temporal
{
return
time_type
==
MYSQL_TIMESTAMP_NONE
||
is_valid_interval_DDhhmmssff
();
}
String
*
to_string
(
String
*
str
,
uint
dec
)
const
{
if
(
!
is_valid_interval_DDhhmmssff
())
return
NULL
;
str
->
set_charset
(
&
my_charset_numeric
);
if
(
!
str
->
alloc
(
MAX_DATE_STRING_REP_LENGTH
))
str
->
length
(
my_interval_DDhhmmssff_to_str
(
this
,
const_cast
<
char
*>
(
str
->
ptr
()),
dec
));
return
str
;
}
};
...
...
@@ -5311,6 +5332,16 @@ class Type_handler_set: public Type_handler_typelib
};
// A pseudo type handler, mostly for test purposes for now
class
Type_handler_interval_DDhhmmssff
:
public
Type_handler_long_blob
{
public:
Item
*
create_typecast_item
(
THD
*
thd
,
Item
*
item
,
const
Type_cast_attributes
&
attr
)
const
;
};
/**
A handler for hybrid type functions, e.g.
COALESCE(), IF(), IFNULL(), NULLIF(), CASE,
...
...
@@ -5443,6 +5474,9 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob;
extern
MYSQL_PLUGIN_IMPORT
Type_handler_medium_blob
type_handler_medium_blob
;
extern
MYSQL_PLUGIN_IMPORT
Type_handler_long_blob
type_handler_long_blob
;
extern
MYSQL_PLUGIN_IMPORT
Type_handler_interval_DDhhmmssff
type_handler_interval_DDhhmmssff
;
class
Type_aggregator
{
bool
m_is_commutative
;
...
...
sql/sql_yacc.yy
View file @
21a58840
...
...
@@ -11703,6 +11703,10 @@ cast_type_temporal:
DATE_SYM { $$.set(&type_handler_newdate); }
| TIME_SYM opt_field_length { $$.set(&type_handler_time2, 0, $2); }
| DATETIME opt_field_length { $$.set(&type_handler_datetime2, 0, $2); }
| INTERVAL_SYM DAY_SECOND_SYM field_length
{
$$.set(&type_handler_interval_DDhhmmssff, 0, $3);
}
;
opt_expr_list:
...
...
sql/sql_yacc_ora.yy
View file @
21a58840
...
...
@@ -11737,6 +11737,10 @@ cast_type_temporal:
DATE_SYM { $$.set(&type_handler_newdate); }
| TIME_SYM opt_field_length { $$.set(&type_handler_time2, 0, $2); }
| DATETIME opt_field_length { $$.set(&type_handler_datetime2, 0, $2); }
| INTERVAL_SYM DAY_SECOND_SYM field_length
{
$$.set(&type_handler_interval_DDhhmmssff, 0, $3);
}
;
opt_expr_list:
...
...
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