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
34eb9838
Commit
34eb9838
authored
6 years ago
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-13995 MAX(timestamp) returns a wrong result near DST change
parent
5b3db871
Changes
26
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1850 additions
and
16 deletions
+1850
-16
mysql-test/main/old-mode.result
mysql-test/main/old-mode.result
+41
-0
mysql-test/main/old-mode.test
mysql-test/main/old-mode.test
+29
-0
mysql-test/main/timezone2.result
mysql-test/main/timezone2.result
+189
-0
mysql-test/main/timezone2.test
mysql-test/main/timezone2.test
+167
-0
mysql-test/main/type_timestamp.result
mysql-test/main/type_timestamp.result
+50
-0
mysql-test/main/type_timestamp.test
mysql-test/main/type_timestamp.test
+50
-0
mysql-test/main/type_timestamp_round.result
mysql-test/main/type_timestamp_round.result
+27
-0
mysql-test/main/type_timestamp_round.test
mysql-test/main/type_timestamp_round.test
+22
-0
sql/compat56.h
sql/compat56.h
+9
-0
sql/field.cc
sql/field.cc
+59
-0
sql/field.h
sql/field.h
+19
-0
sql/filesort.cc
sql/filesort.cc
+31
-0
sql/item.cc
sql/item.cc
+122
-0
sql/item.h
sql/item.h
+182
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+199
-0
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+41
-0
sql/item_func.cc
sql/item_func.cc
+30
-0
sql/item_func.h
sql/item_func.h
+23
-0
sql/item_subselect.cc
sql/item_subselect.cc
+18
-0
sql/item_subselect.h
sql/item_subselect.h
+1
-0
sql/item_sum.cc
sql/item_sum.cc
+9
-0
sql/item_sum.h
sql/item_sum.h
+1
-0
sql/item_timefunc.cc
sql/item_timefunc.cc
+6
-8
sql/sql_type.cc
sql/sql_type.cc
+325
-7
sql/sql_type.h
sql/sql_type.h
+198
-1
sql/structs.h
sql/structs.h
+2
-0
No files found.
mysql-test/main/old-mode.result
View file @
34eb9838
...
...
@@ -180,3 +180,44 @@ a unix_timestamp(a)
2010-10-31 02:25:26 1288481126
drop table t1, t2;
set time_zone=DEFAULT;
#
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
#
SET global mysql56_temporal_format=false;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP(0));
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Moscow*/);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526+3599) /*winter time in Moscow*/);
SET time_zone='Europe/Moscow';
SELECT a, COALESCE(a), UNIX_TIMESTAMP(a) FROM t1;
a COALESCE(a) UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 2010-10-31 02:25:26 1288477526
2010-10-31 02:25:25 2010-10-31 02:25:25 1288481125
SELECT MIN(a), UNIX_TIMESTAMP(MIN(a)) AS a FROM t1;
MIN(a) a
2010-10-31 02:25:26 1288477526
SELECT MAX(a), UNIX_TIMESTAMP(MAX(a)) AS a FROM t1;
MAX(a) a
2010-10-31 02:25:25 1288481125
SELECT t1.a, UNIX_TIMESTAMP(t1.a), t2.a, UNIX_TIMESTAMP(t2.a) FROM t1 t1, t1 t2 WHERE t1.a=t2.a;
a UNIX_TIMESTAMP(t1.a) a UNIX_TIMESTAMP(t2.a)
2010-10-31 02:25:26 1288477526 2010-10-31 02:25:26 1288477526
2010-10-31 02:25:25 1288481125 2010-10-31 02:25:25 1288481125
ALTER TABLE t1 MODIFY a TIMESTAMP(1);
SELECT a, COALESCE(a), UNIX_TIMESTAMP(a) FROM t1;
a COALESCE(a) UNIX_TIMESTAMP(a)
2010-10-31 02:25:26.0 2010-10-31 02:25:26.0 1288477526.0
2010-10-31 02:25:25.0 2010-10-31 02:25:25.0 1288481125.0
SELECT MIN(a), UNIX_TIMESTAMP(MIN(a)) AS a FROM t1;
MIN(a) a
2010-10-31 02:25:26.0 1288477526.0
SELECT MAX(a), UNIX_TIMESTAMP(MAX(a)) AS a FROM t1;
MAX(a) a
2010-10-31 02:25:25.0 1288481125.0
SELECT t1.a, UNIX_TIMESTAMP(t1.a), t2.a, UNIX_TIMESTAMP(t2.a) FROM t1 t1, t1 t2 WHERE t1.a=t2.a;
a UNIX_TIMESTAMP(t1.a) a UNIX_TIMESTAMP(t2.a)
2010-10-31 02:25:26.0 1288477526.0 2010-10-31 02:25:26.0 1288477526.0
2010-10-31 02:25:25.0 1288481125.0 2010-10-31 02:25:25.0 1288481125.0
DROP TABLE t1;
SET time_zone=DEFAULT;
SET global mysql56_temporal_format=true;
This diff is collapsed.
Click to expand it.
mysql-test/main/old-mode.test
View file @
34eb9838
...
...
@@ -119,3 +119,32 @@ insert t2 select a from t1;
select
a
,
unix_timestamp
(
a
)
from
t2
;
drop
table
t1
,
t2
;
set
time_zone
=
DEFAULT
;
--
echo
#
--
echo
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
--
echo
#
# This tests:
# Field_timestamp::val_native()
# Field_timestamp_hires::val_native()
# Type_handler_timestamp_common::type_handler_for_native_format()
SET
global
mysql56_temporal_format
=
false
;
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
(
0
));
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Moscow*/
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
+
3599
)
/*winter time in Moscow*/
);
SET
time_zone
=
'Europe/Moscow'
;
SELECT
a
,
COALESCE
(
a
),
UNIX_TIMESTAMP
(
a
)
FROM
t1
;
SELECT
MIN
(
a
),
UNIX_TIMESTAMP
(
MIN
(
a
))
AS
a
FROM
t1
;
SELECT
MAX
(
a
),
UNIX_TIMESTAMP
(
MAX
(
a
))
AS
a
FROM
t1
;
SELECT
t1
.
a
,
UNIX_TIMESTAMP
(
t1
.
a
),
t2
.
a
,
UNIX_TIMESTAMP
(
t2
.
a
)
FROM
t1
t1
,
t1
t2
WHERE
t1
.
a
=
t2
.
a
;
ALTER
TABLE
t1
MODIFY
a
TIMESTAMP
(
1
);
SELECT
a
,
COALESCE
(
a
),
UNIX_TIMESTAMP
(
a
)
FROM
t1
;
SELECT
MIN
(
a
),
UNIX_TIMESTAMP
(
MIN
(
a
))
AS
a
FROM
t1
;
SELECT
MAX
(
a
),
UNIX_TIMESTAMP
(
MAX
(
a
))
AS
a
FROM
t1
;
SELECT
t1
.
a
,
UNIX_TIMESTAMP
(
t1
.
a
),
t2
.
a
,
UNIX_TIMESTAMP
(
t2
.
a
)
FROM
t1
t1
,
t1
t2
WHERE
t1
.
a
=
t2
.
a
;
DROP
TABLE
t1
;
SET
time_zone
=
DEFAULT
;
SET
global
mysql56_temporal_format
=
true
;
This diff is collapsed.
Click to expand it.
mysql-test/main/timezone2.result
View file @
34eb9838
...
...
@@ -353,5 +353,194 @@ Warning 1292 Truncated incorrect datetime value: '00:00:00'
SET old_mode=DEFAULT;
SET timestamp=DEFAULT;
#
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
#
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Moscow*/);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526+3599) /*winter time in Moscow*/);
SET time_zone='Europe/Moscow';
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:25 1288481125
SELECT UNIX_TIMESTAMP(MAX(a)) AS a FROM t1;
a
1288481125
CREATE TABLE t2 (a TIMESTAMP);
INSERT INTO t2 SELECT MAX(a) AS a FROM t1;
SELECT a, UNIX_TIMESTAMP(a) FROM t2;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:25 1288481125
DROP TABLE t2;
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP);
CREATE TABLE t2 (a TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Moscow*/);
INSERT INTO t2 VALUES (FROM_UNIXTIME(1288477526+3599) /*winter time in Moscow*/);
SET time_zone='Europe/Moscow';
SELECT UNIX_TIMESTAMP(t1.a), UNIX_TIMESTAMP(t2.a) FROM t1,t2;
UNIX_TIMESTAMP(t1.a) UNIX_TIMESTAMP(t2.a)
1288477526 1288481125
SELECT * FROM t1,t2 WHERE t1.a < t2.a;
a a
2010-10-31 02:25:26 2010-10-31 02:25:25
DROP TABLE t1,t2;
BEGIN NOT ATOMIC
DECLARE a,b TIMESTAMP;
SET time_zone='+00:00';
SET a=FROM_UNIXTIME(1288477526);
SET b=FROM_UNIXTIME(1288481125);
SELECT a < b;
SET time_zone='Europe/Moscow';
SELECT a < b;
END;
$$
a < b
1
a < b
1
CREATE OR REPLACE FUNCTION f1(uts INT) RETURNS TIMESTAMP
BEGIN
DECLARE ts TIMESTAMP;
DECLARE tz VARCHAR(64) DEFAULT @@time_zone;
SET time_zone='+00:00';
SET ts=FROM_UNIXTIME(uts);
SET time_zone=tz;
RETURN ts;
END;
$$
SET time_zone='+00:00';
SELECT f1(1288477526) < f1(1288481125);
f1(1288477526) < f1(1288481125)
1
SET time_zone='Europe/Moscow';
SELECT f1(1288477526) < f1(1288481125);
f1(1288477526) < f1(1288481125)
1
DROP FUNCTION f1;
CREATE TABLE t1 (a TIMESTAMP,b TIMESTAMP);
SET time_zone='+00:00';
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Mowcow*/,
FROM_UNIXTIME(1288481125) /*winter time in Moscow*/);
SELECT *, LEAST(a,b) FROM t1;
a b LEAST(a,b)
2010-10-30 22:25:26 2010-10-30 23:25:25 2010-10-30 22:25:26
SET time_zone='Europe/Moscow';
SELECT *, LEAST(a,b) FROM t1;
a b LEAST(a,b)
2010-10-31 02:25:26 2010-10-31 02:25:25 2010-10-31 02:25:26
SELECT UNIX_TIMESTAMP(a), UNIX_TIMESTAMP(b), UNIX_TIMESTAMP(LEAST(a,b)) FROM t1;
UNIX_TIMESTAMP(a) UNIX_TIMESTAMP(b) UNIX_TIMESTAMP(LEAST(a,b))
1288477526 1288481125 1288477526
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP,b TIMESTAMP,c TIMESTAMP);
SET time_zone='+00:00';
INSERT INTO t1 VALUES (
FROM_UNIXTIME(1288477526) /*summer time in Moscow*/,
FROM_UNIXTIME(1288481125) /*winter time in Moscow*/,
FROM_UNIXTIME(1288481126) /*winter time in Moscow*/);
SELECT b BETWEEN a AND c FROM t1;
b BETWEEN a AND c
1
SET time_zone='Europe/Moscow';
SELECT b BETWEEN a AND c FROM t1;
b BETWEEN a AND c
1
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Mowcow*/);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288481125) /*winter time in Moscow*/);
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
a UNIX_TIMESTAMP(a)
2010-10-30 22:25:26 1288477526
2010-10-30 23:25:25 1288481125
SELECT COALESCE(a) AS a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
a UNIX_TIMESTAMP(a)
2010-10-30 22:25:26 1288477526
2010-10-30 23:25:25 1288481125
SET time_zone='Europe/Moscow';
SELECT a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:25 1288481125
SELECT COALESCE(a) AS a, UNIX_TIMESTAMP(a) FROM t1 ORDER BY a;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:25 1288481125
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526) /*summer time in Mowcow*/);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288481126) /*winter time in Moscow*/);
SET time_zone='Europe/Moscow';
SELECT a, UNIX_TIMESTAMP(a) FROM t1 GROUP BY a;
a UNIX_TIMESTAMP(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288481126
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP, b TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526),FROM_UNIXTIME(1288481126));
SELECT UNIX_TIMESTAMP(a),UNIX_TIMESTAMP(b),CASE a WHEN b THEN 'eq' ELSE 'ne' END AS x FROM t1;
UNIX_TIMESTAMP(a) UNIX_TIMESTAMP(b) x
1288477526 1288481126 ne
SET time_zone='Europe/Moscow';
SELECT UNIX_TIMESTAMP(a),UNIX_TIMESTAMP(b),CASE a WHEN b THEN 'eq' ELSE 'ne' END AS x FROM t1;
UNIX_TIMESTAMP(a) UNIX_TIMESTAMP(b) x
1288477526 1288481126 ne
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP, b TIMESTAMP,c TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526),FROM_UNIXTIME(1288481126),FROM_UNIXTIME(1288481127));
SELECT UNIX_TIMESTAMP(a),UNIX_TIMESTAMP(b),a IN (b,c) AS x FROM t1;
UNIX_TIMESTAMP(a) UNIX_TIMESTAMP(b) x
1288477526 1288481126 0
SET time_zone='Europe/Moscow';
SELECT UNIX_TIMESTAMP(a),UNIX_TIMESTAMP(b),a IN (b,c) AS x FROM t1;
UNIX_TIMESTAMP(a) UNIX_TIMESTAMP(b) x
1288477526 1288481126 0
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP, b TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526),FROM_UNIXTIME(1288481126));
SELECT * FROM t1 WHERE a = (SELECT MAX(b) FROM t1);
a b
SELECT * FROM t1 WHERE a = (SELECT MIN(b) FROM t1);
a b
SELECT * FROM t1 WHERE a IN ((SELECT MAX(b) FROM t1), (SELECT MIN(b) FROM t1));
a b
SET time_zone='Europe/Moscow';
SELECT * FROM t1 WHERE a = (SELECT MAX(b) FROM t1);
a b
SELECT * FROM t1 WHERE a = (SELECT MIN(b) FROM t1);
a b
SELECT * FROM t1 WHERE a IN ((SELECT MAX(b) FROM t1), (SELECT MIN(b) FROM t1));
a b
DROP TABLE t1;
SET time_zone='+00:00';
CREATE TABLE t1 (a TIMESTAMP, b TIMESTAMP);
INSERT INTO t1 VALUES (FROM_UNIXTIME(1100000000),FROM_UNIXTIME(1200000000));
INSERT INTO t1 VALUES (FROM_UNIXTIME(1100000001),FROM_UNIXTIME(1200000001));
INSERT INTO t1 VALUES (FROM_UNIXTIME(1288477526),FROM_UNIXTIME(1288481126));
INSERT INTO t1 VALUES (FROM_UNIXTIME(1300000000),FROM_UNIXTIME(1400000000));
INSERT INTO t1 VALUES (FROM_UNIXTIME(1300000001),FROM_UNIXTIME(1400000001));
SELECT * FROM t1 WHERE a = (SELECT MAX(b) FROM t1);
a b
SELECT * FROM t1 WHERE a = (SELECT MIN(b) FROM t1);
a b
SELECT * FROM t1 WHERE a IN ((SELECT MAX(b) FROM t1), (SELECT MIN(b) FROM t1));
a b
SET time_zone='Europe/Moscow';
SELECT * FROM t1 WHERE a = (SELECT MAX(b) FROM t1);
a b
SELECT * FROM t1 WHERE a = (SELECT MIN(b) FROM t1);
a b
SELECT * FROM t1 WHERE a IN ((SELECT MAX(b) FROM t1), (SELECT MIN(b) FROM t1));
a b
DROP TABLE t1;
#
# End of 10.4 tests
#
This diff is collapsed.
Click to expand it.
mysql-test/main/timezone2.test
View file @
34eb9838
...
...
@@ -324,6 +324,173 @@ SELECT CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5');
SET
old_mode
=
DEFAULT
;
SET
timestamp
=
DEFAULT
;
--
echo
#
--
echo
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
--
echo
#
# MAX()
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Moscow*/
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
+
3599
)
/*winter time in Moscow*/
);
SET
time_zone
=
'Europe/Moscow'
;
SELECT
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
;
SELECT
UNIX_TIMESTAMP
(
MAX
(
a
))
AS
a
FROM
t1
;
CREATE
TABLE
t2
(
a
TIMESTAMP
);
INSERT
INTO
t2
SELECT
MAX
(
a
)
AS
a
FROM
t1
;
SELECT
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t2
;
DROP
TABLE
t2
;
DROP
TABLE
t1
;
# Comparison
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
);
CREATE
TABLE
t2
(
a
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Moscow*/
);
INSERT
INTO
t2
VALUES
(
FROM_UNIXTIME
(
1288477526
+
3599
)
/*winter time in Moscow*/
);
SET
time_zone
=
'Europe/Moscow'
;
SELECT
UNIX_TIMESTAMP
(
t1
.
a
),
UNIX_TIMESTAMP
(
t2
.
a
)
FROM
t1
,
t2
;
SELECT
*
FROM
t1
,
t2
WHERE
t1
.
a
<
t2
.
a
;
DROP
TABLE
t1
,
t2
;
# SP variable comparison
DELIMITER
$$
;
BEGIN
NOT
ATOMIC
DECLARE
a
,
b
TIMESTAMP
;
SET
time_zone
=
'+00:00'
;
SET
a
=
FROM_UNIXTIME
(
1288477526
);
SET
b
=
FROM_UNIXTIME
(
1288481125
);
SELECT
a
<
b
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
a
<
b
;
END
;
$$
DELIMITER
;
$$
# SP function comparison
DELIMITER
$$
;
CREATE
OR
REPLACE
FUNCTION
f1
(
uts
INT
)
RETURNS
TIMESTAMP
BEGIN
DECLARE
ts
TIMESTAMP
;
DECLARE
tz
VARCHAR
(
64
)
DEFAULT
@@
time_zone
;
SET
time_zone
=
'+00:00'
;
SET
ts
=
FROM_UNIXTIME
(
uts
);
SET
time_zone
=
tz
;
RETURN
ts
;
END
;
$$
DELIMITER
;
$$
SET
time_zone
=
'+00:00'
;
SELECT
f1
(
1288477526
)
<
f1
(
1288481125
);
SET
time_zone
=
'Europe/Moscow'
;
SELECT
f1
(
1288477526
)
<
f1
(
1288481125
);
DROP
FUNCTION
f1
;
# LEAST()
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
);
SET
time_zone
=
'+00:00'
;
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Mowcow*/
,
FROM_UNIXTIME
(
1288481125
)
/*winter time in Moscow*/
);
SELECT
*
,
LEAST
(
a
,
b
)
FROM
t1
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
*
,
LEAST
(
a
,
b
)
FROM
t1
;
SELECT
UNIX_TIMESTAMP
(
a
),
UNIX_TIMESTAMP
(
b
),
UNIX_TIMESTAMP
(
LEAST
(
a
,
b
))
FROM
t1
;
DROP
TABLE
t1
;
# BETWEEN
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
,
c
TIMESTAMP
);
SET
time_zone
=
'+00:00'
;
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Moscow*/
,
FROM_UNIXTIME
(
1288481125
)
/*winter time in Moscow*/
,
FROM_UNIXTIME
(
1288481126
)
/*winter time in Moscow*/
);
SELECT
b
BETWEEN
a
AND
c
FROM
t1
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
b
BETWEEN
a
AND
c
FROM
t1
;
DROP
TABLE
t1
;
# ORDER BY
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Mowcow*/
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288481125
)
/*winter time in Moscow*/
);
SELECT
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
ORDER
BY
a
;
SELECT
COALESCE
(
a
)
AS
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
ORDER
BY
a
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
ORDER
BY
a
;
SELECT
COALESCE
(
a
)
AS
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
ORDER
BY
a
;
DROP
TABLE
t1
;
# GROUP BY
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
)
/*summer time in Mowcow*/
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288481126
)
/*winter time in Moscow*/
);
SET
time_zone
=
'Europe/Moscow'
;
SELECT
a
,
UNIX_TIMESTAMP
(
a
)
FROM
t1
GROUP
BY
a
;
DROP
TABLE
t1
;
# CASE
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
),
FROM_UNIXTIME
(
1288481126
));
SELECT
UNIX_TIMESTAMP
(
a
),
UNIX_TIMESTAMP
(
b
),
CASE
a
WHEN
b
THEN
'eq'
ELSE
'ne'
END
AS
x
FROM
t1
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
UNIX_TIMESTAMP
(
a
),
UNIX_TIMESTAMP
(
b
),
CASE
a
WHEN
b
THEN
'eq'
ELSE
'ne'
END
AS
x
FROM
t1
;
DROP
TABLE
t1
;
# IN
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
,
c
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
),
FROM_UNIXTIME
(
1288481126
),
FROM_UNIXTIME
(
1288481127
));
SELECT
UNIX_TIMESTAMP
(
a
),
UNIX_TIMESTAMP
(
b
),
a
IN
(
b
,
c
)
AS
x
FROM
t1
;
SET
time_zone
=
'Europe/Moscow'
;
SELECT
UNIX_TIMESTAMP
(
a
),
UNIX_TIMESTAMP
(
b
),
a
IN
(
b
,
c
)
AS
x
FROM
t1
;
DROP
TABLE
t1
;
# Comparison and IN in combination with a subquery (with one row)
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
),
FROM_UNIXTIME
(
1288481126
));
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MAX
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MIN
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
IN
((
SELECT
MAX
(
b
)
FROM
t1
),
(
SELECT
MIN
(
b
)
FROM
t1
));
SET
time_zone
=
'Europe/Moscow'
;
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MAX
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MIN
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
IN
((
SELECT
MAX
(
b
)
FROM
t1
),
(
SELECT
MIN
(
b
)
FROM
t1
));
DROP
TABLE
t1
;
# Comparison and IN in combinarion with a subquery (with multiple rows)
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1100000000
),
FROM_UNIXTIME
(
1200000000
));
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1100000001
),
FROM_UNIXTIME
(
1200000001
));
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1288477526
),
FROM_UNIXTIME
(
1288481126
));
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1300000000
),
FROM_UNIXTIME
(
1400000000
));
INSERT
INTO
t1
VALUES
(
FROM_UNIXTIME
(
1300000001
),
FROM_UNIXTIME
(
1400000001
));
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MAX
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MIN
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
IN
((
SELECT
MAX
(
b
)
FROM
t1
),
(
SELECT
MIN
(
b
)
FROM
t1
));
SET
time_zone
=
'Europe/Moscow'
;
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MAX
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
=
(
SELECT
MIN
(
b
)
FROM
t1
);
SELECT
*
FROM
t1
WHERE
a
IN
((
SELECT
MAX
(
b
)
FROM
t1
),
(
SELECT
MIN
(
b
)
FROM
t1
));
DROP
TABLE
t1
;
--
echo
#
--
echo
# End of 10.4 tests
--
echo
#
This diff is collapsed.
Click to expand it.
mysql-test/main/type_timestamp.result
View file @
34eb9838
...
...
@@ -1068,5 +1068,55 @@ DROP PROCEDURE p1;
SET timestamp=DEFAULT;
SET time_zone=DEFAULT;
#
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
#
# Testing Item_func_rollup_const::val_native()
# There is a bug in the below output (MDEV-16612)
# Please remove this comment when MDEV-16612 is fixed and results are re-recorded
CREATE TABLE t1 (id INT);
INSERT INTO t1 VALUES (1),(2);
BEGIN NOT ATOMIC
DECLARE v TIMESTAMP DEFAULT '2001-01-01 10:20:30'; -- "v" will be wrapped into Item_func_rollup_const
SELECT id, v AS v, COUNT(*) FROM t1 GROUP BY id,v WITH ROLLUP;
END;
$$
id v COUNT(*)
1 2001-01-01 10:20:30 1
1 2001-01-01 10:20:30 1
2 2001-01-01 10:20:30 1
2 2001-01-01 10:20:30 1
NULL 2001-01-01 10:20:30 2
DROP TABLE t1;
#
# Testing Type_handler_timestamp_common::Item_save_in_field()
# "txt" is expected to have three fractional digits
SET time_zone='+00:00';
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30.123456');
CREATE TABLE t1 (ts1 TIMESTAMP(1) NOT NULL, ts2 TIMESTAMP(3) NOT NULL, txt TEXT);
INSERT INTO t1 VALUES ('0000-00-00 00:00:00', '0000-00-00 00:00:00',COALESCE(ts1,ts2));
INSERT INTO t1 VALUES (NOW(),NOW(),COALESCE(ts1,ts2));
INSERT INTO t1 VALUES (NOW(1),NOW(3),COALESCE(ts1,ts2));
SELECT * FROM t1;
ts1 ts2 txt
0000-00-00 00:00:00.0 0000-00-00 00:00:00.000 0000-00-00 00:00:00.000
2001-01-01 10:20:30.0 2001-01-01 10:20:30.000 2001-01-01 10:20:30.000
2001-01-01 10:20:30.1 2001-01-01 10:20:30.123 2001-01-01 10:20:30.100
DROP TABLE t1;
SET timestamp=DEFAULT;
SET time_zone=DEFAULT;
#
# Testing Field_timestamp::store_native
#
SET sql_mode='';
CREATE TABLE t1 (a TIMESTAMP, b TIMESTAMP);
INSERT INTO t1 VALUES ('0000-00-00 00:00:00','0000-00-00 00:00:00');
SET sql_mode='STRICT_ALL_TABLES,NO_ZERO_DATE';
UPDATE t1 SET a=b;
ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'a' at row 1
UPDATE t1 SET a=COALESCE(b);
ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'a' at row 1
DROP TABLE t1;
SET sql_mode=DEFAULT;
#
# End of 10.4 tests
#
This diff is collapsed.
Click to expand it.
mysql-test/main/type_timestamp.test
View file @
34eb9838
...
...
@@ -660,6 +660,56 @@ DROP PROCEDURE p1;
SET
timestamp
=
DEFAULT
;
SET
time_zone
=
DEFAULT
;
--
echo
#
--
echo
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
--
echo
#
--
echo
# Testing Item_func_rollup_const::val_native()
--
echo
# There is a bug in the below output (MDEV-16612)
--
echo
# Please remove this comment when MDEV-16612 is fixed and results are re-recorded
CREATE
TABLE
t1
(
id
INT
);
INSERT
INTO
t1
VALUES
(
1
),(
2
);
DELIMITER
$$
;
BEGIN
NOT
ATOMIC
DECLARE
v
TIMESTAMP
DEFAULT
'2001-01-01 10:20:30'
;
--
"v"
will
be
wrapped
into
Item_func_rollup_const
SELECT
id
,
v
AS
v
,
COUNT
(
*
)
FROM
t1
GROUP
BY
id
,
v
WITH
ROLLUP
;
END
;
$$
DELIMITER
;
$$
DROP
TABLE
t1
;
--
echo
#
--
echo
# Testing Type_handler_timestamp_common::Item_save_in_field()
--
echo
# "txt" is expected to have three fractional digits
SET
time_zone
=
'+00:00'
;
SET
timestamp
=
UNIX_TIMESTAMP
(
'2001-01-01 10:20:30.123456'
);
CREATE
TABLE
t1
(
ts1
TIMESTAMP
(
1
)
NOT
NULL
,
ts2
TIMESTAMP
(
3
)
NOT
NULL
,
txt
TEXT
);
INSERT
INTO
t1
VALUES
(
'0000-00-00 00:00:00'
,
'0000-00-00 00:00:00'
,
COALESCE
(
ts1
,
ts2
));
INSERT
INTO
t1
VALUES
(
NOW
(),
NOW
(),
COALESCE
(
ts1
,
ts2
));
INSERT
INTO
t1
VALUES
(
NOW
(
1
),
NOW
(
3
),
COALESCE
(
ts1
,
ts2
));
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
SET
timestamp
=
DEFAULT
;
SET
time_zone
=
DEFAULT
;
--
echo
#
--
echo
# Testing Field_timestamp::store_native
--
echo
#
SET
sql_mode
=
''
;
CREATE
TABLE
t1
(
a
TIMESTAMP
,
b
TIMESTAMP
);
INSERT
INTO
t1
VALUES
(
'0000-00-00 00:00:00'
,
'0000-00-00 00:00:00'
);
SET
sql_mode
=
'STRICT_ALL_TABLES,NO_ZERO_DATE'
;
--
error
ER_TRUNCATED_WRONG_VALUE
UPDATE
t1
SET
a
=
b
;
--
error
ER_TRUNCATED_WRONG_VALUE
UPDATE
t1
SET
a
=
COALESCE
(
b
);
DROP
TABLE
t1
;
SET
sql_mode
=
DEFAULT
;
--
echo
#
--
echo
# End of 10.4 tests
--
echo
#
This diff is collapsed.
Click to expand it.
mysql-test/main/type_timestamp_round.result
View file @
34eb9838
...
...
@@ -162,3 +162,30 @@ SELECT * FROM t1,t2 WHERE COALESCE(t1.a)=t2.a;
a a
20010101235959.9999999 2001-01-02 00:00:00
DROP TABLE t1,t2;
#
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
#
# Test Field_timestamp::store_native()
#
SET sql_mode=@default_sql_mode;
SET time_zone='+00:00';
CREATE TABLE t1 (ts0 TIMESTAMP, ts1 TIMESTAMP(1));
INSERT INTO t1 VALUES ('2001-01-01 10:20:30', '2001-01-01 10:20:30.9');
SELECT * FROM t1;
ts0 ts1
2001-01-01 10:20:30 2001-01-01 10:20:30.9
# This should round
UPDATE t1 SET ts0=COALESCE(ts1);
SELECT * FROM t1;
ts0 ts1
2001-01-01 10:20:31 2001-01-01 10:20:30.9
# Corner case
UPDATE t1 SET ts1=FROM_UNIXTIME(2147483647.9);
UPDATE t1 SET ts0=COALESCE(ts1);
Warnings:
Warning 1264 Out of range value for column 'ts0' at row 1
SELECT * FROM t1;
ts0 ts1
2038-01-19 03:14:07 2038-01-19 03:14:07.9
DROP TABLE t1;
SET time_zone=DEFAULT;
This diff is collapsed.
Click to expand it.
mysql-test/main/type_timestamp_round.test
View file @
34eb9838
...
...
@@ -136,3 +136,25 @@ INSERT INTO t2 VALUES ('2001-01-02 00:00:00');
SELECT
*
FROM
t1
,
t2
WHERE
t1
.
a
=
t2
.
a
;
SELECT
*
FROM
t1
,
t2
WHERE
COALESCE
(
t1
.
a
)
=
t2
.
a
;
DROP
TABLE
t1
,
t2
;
--
echo
#
--
echo
# MDEV-13995 MAX(timestamp) returns a wrong result near DST change
--
echo
#
--
echo
# Test Field_timestamp::store_native()
--
echo
#
SET
sql_mode
=@
default_sql_mode
;
SET
time_zone
=
'+00:00'
;
CREATE
TABLE
t1
(
ts0
TIMESTAMP
,
ts1
TIMESTAMP
(
1
));
INSERT
INTO
t1
VALUES
(
'2001-01-01 10:20:30'
,
'2001-01-01 10:20:30.9'
);
SELECT
*
FROM
t1
;
--
echo
# This should round
UPDATE
t1
SET
ts0
=
COALESCE
(
ts1
);
SELECT
*
FROM
t1
;
--
echo
# Corner case
UPDATE
t1
SET
ts1
=
FROM_UNIXTIME
(
2147483647.9
);
UPDATE
t1
SET
ts0
=
COALESCE
(
ts1
);
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
SET
time_zone
=
DEFAULT
;
This diff is collapsed.
Click to expand it.
sql/compat56.h
View file @
34eb9838
...
...
@@ -19,6 +19,15 @@
/** MySQL56 routines and macros **/
/*
Buffer size for a native TIMESTAMP representation, for use with NativBuffer.
4 bytes for seconds
3 bytes for microseconds
1 byte for the trailing '\0' (class Native reserves extra 1 byte for '\0')
*/
#define STRING_BUFFER_TIMESTAMP_BINARY_SIZE 8
/* 4 + 3 + 1 */
#define MY_PACKED_TIME_GET_INT_PART(x) ((x) >> 24)
#define MY_PACKED_TIME_GET_FRAC_PART(x) ((x) % (1LL << 24))
#define MY_PACKED_TIME_MAKE(i, f) ((((longlong) (i)) << 24) + (f))
...
...
This diff is collapsed.
Click to expand it.
sql/field.cc
View file @
34eb9838
...
...
@@ -5023,6 +5023,15 @@ my_time_t Field_timestamp::get_timestamp(const uchar *pos,
}
bool
Field_timestamp
::
val_native
(
Native
*
to
)
{
ASSERT_COLUMN_MARKED_FOR_READ
;
my_time_t
sec
=
(
my_time_t
)
sint4korr
(
ptr
);
return
Timestamp_or_zero_datetime
(
Timestamp
(
sec
,
0
),
sec
==
0
).
to_native
(
to
,
0
);
}
int
Field_timestamp
::
store_TIME_with_warning
(
THD
*
thd
,
const
Datetime
*
dt
,
const
ErrConv
*
str
,
int
was_cut
)
{
...
...
@@ -5143,6 +5152,14 @@ int Field_timestamp::store_timestamp_dec(const timeval &ts, uint dec)
}
if
(
ts
.
tv_sec
==
0
&&
ts
.
tv_usec
==
0
&&
get_thd
()
->
variables
.
sql_mode
&
(
ulonglong
)
TIME_NO_ZERO_DATE
)
return
zero_time_stored_return_code_with_warning
();
return
0
;
}
int
Field_timestamp
::
zero_time_stored_return_code_with_warning
()
{
if
(
get_thd
()
->
variables
.
sql_mode
&
(
ulonglong
)
TIME_NO_ZERO_DATE
)
{
ErrConvString
s
(
STRING_WITH_LEN
(
"0000-00-00 00:00:00.000000"
)
-
(
decimals
()
?
6
-
decimals
()
:
7
),
...
...
@@ -5151,6 +5168,23 @@ int Field_timestamp::store_timestamp_dec(const timeval &ts, uint dec)
return
1
;
}
return
0
;
}
int
Field_timestamp
::
store_native
(
const
Native
&
value
)
{
if
(
!
value
.
length
())
// Zero datetime
{
reset
();
return
zero_time_stored_return_code_with_warning
();
}
/*
The exact second precision is not important here.
Field_timestamp*::store_timestamp_dec() do not use the "dec" parameter.
Passing TIME_SECOND_PART_DIGITS is OK.
*/
return
store_timestamp_dec
(
Timestamp
(
value
).
tv
(),
TIME_SECOND_PART_DIGITS
);
}
...
...
@@ -5410,6 +5444,18 @@ my_time_t Field_timestamp_hires::get_timestamp(const uchar *pos,
return
mi_uint4korr
(
pos
);
}
bool
Field_timestamp_hires
::
val_native
(
Native
*
to
)
{
ASSERT_COLUMN_MARKED_FOR_READ
;
struct
timeval
tm
;
tm
.
tv_sec
=
mi_uint4korr
(
ptr
);
tm
.
tv_usec
=
(
ulong
)
sec_part_unshift
(
read_bigendian
(
ptr
+
4
,
sec_part_bytes
(
dec
)),
dec
);
return
Timestamp_or_zero_datetime
(
Timestamp
(
tm
),
tm
.
tv_sec
==
0
).
to_native
(
to
,
dec
);
}
double
Field_timestamp_with_dec
::
val_real
(
void
)
{
MYSQL_TIME
ltime
;
...
...
@@ -5516,6 +5562,19 @@ my_time_t Field_timestampf::get_timestamp(const uchar *pos,
}
bool
Field_timestampf
::
val_native
(
Native
*
to
)
{
ASSERT_COLUMN_MARKED_FOR_READ
;
// Check if it's '0000-00-00 00:00:00' rather than a real timestamp
if
(
ptr
[
0
]
==
0
&&
ptr
[
1
]
==
0
&&
ptr
[
2
]
==
0
&&
ptr
[
3
]
==
0
)
{
to
->
length
(
0
);
return
false
;
}
return
Field
::
val_native
(
to
);
}
/*************************************************************/
uint
Field_temporal
::
is_equal
(
Create_field
*
new_field
)
{
...
...
This diff is collapsed.
Click to expand it.
sql/field.h
View file @
34eb9838
...
...
@@ -790,6 +790,15 @@ class Field: public Value_source
return
store_timestamp_dec
(
Timeval
(
timestamp
,
sec_part
),
TIME_SECOND_PART_DIGITS
);
}
/**
Store a value represented in native format
*/
virtual
int
store_native
(
const
Native
&
value
)
{
DBUG_ASSERT
(
0
);
reset
();
return
0
;
}
int
store_time
(
const
MYSQL_TIME
*
ltime
)
{
return
store_time_dec
(
ltime
,
TIME_SECOND_PART_DIGITS
);
}
int
store
(
const
char
*
to
,
size_t
length
,
CHARSET_INFO
*
cs
,
...
...
@@ -836,6 +845,11 @@ class Field: public Value_source
This trickery is used to decrease a number of malloc calls.
*/
virtual
String
*
val_str
(
String
*
,
String
*
)
=
0
;
virtual
bool
val_native
(
Native
*
to
)
{
DBUG_ASSERT
(
!
is_null
());
return
to
->
copy
((
const
char
*
)
ptr
,
pack_length
());
}
String
*
val_int_as_str
(
String
*
val_buffer
,
bool
unsigned_flag
);
/*
Return the field value as a LEX_CSTRING, without padding to full length
...
...
@@ -2735,6 +2749,7 @@ class Field_timestamp :public Field_temporal {
{
store_TIMEVAL
(
ts
.
tv
());
}
int
zero_time_stored_return_code_with_warning
();
public:
Field_timestamp
(
uchar
*
ptr_arg
,
uint32
len_arg
,
uchar
*
null_ptr_arg
,
uchar
null_bit_arg
,
...
...
@@ -2785,6 +2800,8 @@ class Field_timestamp :public Field_temporal {
store_TIMESTAMP
(
Timestamp
(
ts
,
sec_part
).
round
(
decimals
(),
mode
,
&
warn
));
}
bool
get_date
(
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
int
store_native
(
const
Native
&
value
);
bool
val_native
(
Native
*
to
);
uchar
*
pack
(
uchar
*
to
,
const
uchar
*
from
,
uint
max_length
__attribute__
((
unused
)))
{
...
...
@@ -2864,6 +2881,7 @@ class Field_timestamp_hires :public Field_timestamp_with_dec {
{
DBUG_ASSERT
(
dec
);
}
bool
val_native
(
Native
*
to
);
my_time_t
get_timestamp
(
const
uchar
*
pos
,
ulong
*
sec_part
)
const
;
int
cmp
(
const
uchar
*
,
const
uchar
*
);
uint32
pack_length
()
const
{
return
4
+
sec_part_bytes
(
dec
);
}
...
...
@@ -2914,6 +2932,7 @@ class Field_timestampf :public Field_timestamp_with_dec {
{
return
get_timestamp
(
ptr
,
sec_part
);
}
bool
val_native
(
Native
*
to
);
uint
size_of
()
const
{
return
sizeof
(
*
this
);
}
};
...
...
This diff is collapsed.
Click to expand it.
sql/filesort.cc
View file @
34eb9838
...
...
@@ -1067,6 +1067,28 @@ Type_handler_temporal_result::make_sort_key(uchar *to, Item *item,
}
void
Type_handler_timestamp_common
::
make_sort_key
(
uchar
*
to
,
Item
*
item
,
const
SORT_FIELD_ATTR
*
sort_field
,
Sort_param
*
param
)
const
{
uint
binlen
=
my_timestamp_binary_length
(
item
->
decimals
);
Timestamp_or_zero_datetime_native_null
native
(
current_thd
,
item
);
if
(
native
.
is_null
()
||
native
.
is_zero_datetime
())
{
// NULL or '0000-00-00 00:00:00'
bzero
(
to
,
item
->
maybe_null
?
binlen
+
1
:
binlen
);
}
else
{
DBUG_ASSERT
(
native
.
length
()
==
binlen
);
if
(
item
->
maybe_null
)
*
to
++=
1
;
memcpy
((
char
*
)
to
,
native
.
ptr
(),
binlen
);
}
}
void
Type_handler
::
make_sort_key_longlong
(
uchar
*
to
,
bool
maybe_null
,
...
...
@@ -1873,6 +1895,15 @@ Type_handler_temporal_result::sortlength(THD *thd,
}
void
Type_handler_timestamp_common
::
sortlength
(
THD
*
thd
,
const
Type_std_attributes
*
item
,
SORT_FIELD_ATTR
*
sortorder
)
const
{
sortorder
->
length
=
my_timestamp_binary_length
(
item
->
decimals
);
}
void
Type_handler_int_result
::
sortlength
(
THD
*
thd
,
const
Type_std_attributes
*
item
,
...
...
This diff is collapsed.
Click to expand it.
sql/item.cc
View file @
34eb9838
...
...
@@ -1526,6 +1526,12 @@ String *Item_sp_variable::val_str(String *sp)
}
bool
Item_sp_variable
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_item
(
thd
,
this_item
(),
to
);
}
my_decimal
*
Item_sp_variable
::
val_decimal
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
fixed
);
...
...
@@ -3178,6 +3184,18 @@ bool Item_field::get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzyd
}
bool
Item_field
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_field
(
field
,
to
);
}
bool
Item_field
::
val_native_result
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_field
(
result_field
,
to
);
}
void
Item_field
::
save_result
(
Field
*
to
)
{
save_field_in_field
(
result_field
,
&
null_value
,
to
,
TRUE
);
...
...
@@ -4843,6 +4861,12 @@ String* Item_ref_null_helper::val_str(String* s)
}
bool
Item_ref_null_helper
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
(
owner
->
was_null
|=
val_native_from_item
(
thd
,
*
ref
,
to
));
}
bool
Item_ref_null_helper
::
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
return
(
owner
->
was_null
|=
null_value
=
(
*
ref
)
->
get_date_result
(
thd
,
ltime
,
fuzzydate
));
...
...
@@ -8103,6 +8127,14 @@ String *Item_ref::str_result(String* str)
}
bool
Item_ref
::
val_native_result
(
THD
*
thd
,
Native
*
to
)
{
return
result_field
?
val_native_from_field
(
result_field
,
to
)
:
val_native
(
thd
,
to
);
}
my_decimal
*
Item_ref
::
val_decimal_result
(
my_decimal
*
decimal_value
)
{
if
(
result_field
)
...
...
@@ -8197,6 +8229,12 @@ bool Item_ref::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
}
bool
Item_ref
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_item
(
thd
,
*
ref
,
to
);
}
my_decimal
*
Item_ref
::
val_decimal
(
my_decimal
*
decimal_value
)
{
my_decimal
*
val
=
(
*
ref
)
->
val_decimal_result
(
decimal_value
);
...
...
@@ -8334,6 +8372,12 @@ bool Item_direct_ref::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydat
}
bool
Item_direct_ref
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_item
(
thd
,
*
ref
,
to
);
}
Item_cache_wrapper
::~
Item_cache_wrapper
()
{
DBUG_ASSERT
(
expr_cache
==
0
);
...
...
@@ -8622,6 +8666,28 @@ String *Item_cache_wrapper::val_str(String* str)
}
/**
Get the native value of the possibly cached item
*/
bool
Item_cache_wrapper
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
Item
*
cached_value
;
DBUG_ENTER
(
"Item_cache_wrapper::val_native"
);
if
(
!
expr_cache
)
DBUG_RETURN
(
val_native_from_item
(
thd
,
orig_item
,
to
));
if
((
cached_value
=
check_cache
()))
DBUG_RETURN
(
val_native_from_item
(
thd
,
cached_value
,
to
));
cache
();
if
((
null_value
=
expr_value
->
null_value
))
DBUG_RETURN
(
true
);
DBUG_RETURN
(
expr_value
->
val_native
(
thd
,
to
));
}
/**
Get the decimal value of the possibly cached item
*/
...
...
@@ -9794,6 +9860,62 @@ Item *Item_cache_time::make_literal(THD *thd)
return
new
(
thd
->
mem_root
)
Item_time_literal
(
thd
,
&
ltime
,
decimals
);
}
int
Item_cache_timestamp
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
if
(
!
has_value
())
return
set_field_to_null_with_conversions
(
field
,
no_conversions
);
return
m_native
.
save_in_field
(
field
,
decimals
);
}
bool
Item_cache_timestamp
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
if
(
!
has_value
())
{
null_value
=
true
;
return
true
;
}
return
null_value
=
to
->
copy
(
m_native
);
}
Datetime
Item_cache_timestamp
::
to_datetime
(
THD
*
thd
)
{
DBUG_ASSERT
(
is_fixed
()
==
1
);
if
(
!
has_value
())
{
null_value
=
true
;
return
Datetime
();
}
return
Datetime
(
thd
,
Timestamp_or_zero_datetime
(
m_native
).
tv
());
}
bool
Item_cache_timestamp
::
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
if
(
!
has_value
())
{
set_zero_time
(
ltime
,
MYSQL_TIMESTAMP_DATETIME
);
return
true
;
}
Timestamp_or_zero_datetime
tm
(
m_native
);
return
(
null_value
=
tm
.
to_TIME
(
thd
,
ltime
,
fuzzydate
));
}
bool
Item_cache_timestamp
::
cache_value
()
{
if
(
!
example
)
return
false
;
value_cached
=
true
;
null_value
=
example
->
val_native_with_conversion_result
(
current_thd
,
&
m_native
,
type_handler
());
return
true
;
}
bool
Item_cache_real
::
cache_value
()
{
if
(
!
example
)
...
...
This diff is collapsed.
Click to expand it.
sql/item.h
View file @
34eb9838
...
...
@@ -855,6 +855,25 @@ class Item: public Value_source,
res
=
NULL
;
return
res
;
}
bool
val_native_from_item
(
THD
*
thd
,
Item
*
item
,
Native
*
to
)
{
DBUG_ASSERT
(
is_fixed
());
null_value
=
item
->
val_native
(
thd
,
to
);
DBUG_ASSERT
(
null_value
==
item
->
null_value
);
return
null_value
;
}
bool
val_native_from_field
(
Field
*
field
,
Native
*
to
)
{
if
((
null_value
=
field
->
is_null
()))
return
true
;
return
(
null_value
=
field
->
val_native
(
to
));
}
bool
val_native_with_conversion_from_item
(
THD
*
thd
,
Item
*
item
,
Native
*
to
,
const
Type_handler
*
handler
)
{
DBUG_ASSERT
(
is_fixed
());
return
null_value
=
item
->
val_native_with_conversion
(
thd
,
to
,
handler
);
}
my_decimal
*
val_decimal_from_item
(
Item
*
item
,
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
is_fixed
());
...
...
@@ -1276,6 +1295,60 @@ class Item: public Value_source,
*/
virtual
String
*
val_str
(
String
*
str
)
=
0
;
bool
val_native_with_conversion
(
THD
*
thd
,
Native
*
to
,
const
Type_handler
*
th
)
{
return
th
->
Item_val_native_with_conversion
(
thd
,
this
,
to
);
}
bool
val_native_with_conversion_result
(
THD
*
thd
,
Native
*
to
,
const
Type_handler
*
th
)
{
return
th
->
Item_val_native_with_conversion_result
(
thd
,
this
,
to
);
}
virtual
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
/*
The default implementation for the Items that do not need native format:
- Item_basic_value
- Item_ident_for_show
- Item_copy
- Item_exists_subselect
- Item_sum_field
- Item_sum_or_func (default implementation)
- Item_proc
- Item_type_holder (as val_xxx() are never called for it);
- TODO: Item_name_const will need val_native() in the future,
when we add this syntax:
TIMESTAMP WITH LOCAL TIMEZONE'2001-01-01 00:00:00'
These hybrid Item types override val_native():
- Item_field
- Item_param
- Item_sp_variable
- Item_ref
- Item_cache_wrapper
- Item_direct_ref
- Item_direct_view_ref
- Item_ref_null_helper
- Item_sum_or_func
Note, these hybrid type Item_sum_or_func descendants
override the default implementation:
* Item_sum_hybrid
* Item_func_hybrid_field_type
* Item_func_min_max
* Item_func_sp
* Item_func_last_value
* Item_func_rollup_const
*/
DBUG_ASSERT
(
0
);
return
null_value
=
true
;
}
virtual
bool
val_native_result
(
THD
*
thd
,
Native
*
to
)
{
return
val_native
(
thd
,
to
);
}
/*
Returns string representation of this item in ASCII format.
...
...
@@ -2689,6 +2762,7 @@ class Item_sp_variable :public Item_fixed_hybrid
String
*
val_str
(
String
*
sp
);
my_decimal
*
val_decimal
(
my_decimal
*
decimal_value
);
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
bool
is_null
();
public:
...
...
@@ -3229,6 +3303,8 @@ class Item_field :public Item_ident,
void
save_result
(
Field
*
to
);
double
val_result
();
longlong
val_int_result
();
bool
val_native
(
THD
*
thd
,
Native
*
to
);
bool
val_native_result
(
THD
*
thd
,
Native
*
to
);
String
*
str_result
(
String
*
tmp
);
my_decimal
*
val_decimal_result
(
my_decimal
*
);
bool
val_bool_result
();
...
...
@@ -3815,6 +3891,11 @@ class Item_param :public Item_basic_value,
return
can_return_value
()
?
value
.
val_str
(
str
,
this
)
:
NULL
;
}
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
tm
,
date_mode_t
fuzzydate
);
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
Item_param
::
type_handler
()
->
Item_param_val_native
(
thd
,
this
,
to
);
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
void
set_default
();
...
...
@@ -4614,6 +4695,54 @@ class Item_bin_string: public Item_hex_hybrid
};
class
Item_timestamp_literal
:
public
Item_literal
{
Timestamp_or_zero_datetime
m_value
;
public:
Item_timestamp_literal
(
THD
*
thd
)
:
Item_literal
(
thd
)
{
}
const
Type_handler
*
type_handler
()
const
{
return
&
type_handler_timestamp2
;
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
Timestamp_or_zero_datetime_native
native
(
m_value
,
decimals
);
return
native
.
save_in_field
(
field
,
decimals
);
}
longlong
val_int
()
{
return
m_value
.
to_datetime
(
current_thd
).
to_longlong
();
}
double
val_real
()
{
return
m_value
.
to_datetime
(
current_thd
).
to_double
();
}
String
*
val_str
(
String
*
to
)
{
return
m_value
.
to_datetime
(
current_thd
).
to_string
(
to
,
decimals
);
}
my_decimal
*
val_decimal
(
my_decimal
*
to
)
{
return
m_value
.
to_datetime
(
current_thd
).
to_decimal
(
to
);
}
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
bool
res
=
m_value
.
to_TIME
(
thd
,
ltime
,
fuzzydate
);
DBUG_ASSERT
(
!
res
);
return
res
;
}
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
m_value
.
to_native
(
to
,
decimals
);
}
void
set_value
(
const
Timestamp_or_zero_datetime
&
value
)
{
m_value
=
value
;
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_timestamp_literal
>
(
thd
,
this
);
}
};
class
Item_temporal_literal
:
public
Item_literal
{
protected:
...
...
@@ -5062,11 +5191,13 @@ class Item_ref :public Item_ident,
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
String
*
val_str
(
String
*
tmp
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
bool
is_null
();
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
double
val_result
();
longlong
val_int_result
();
String
*
str_result
(
String
*
tmp
);
bool
val_native_result
(
THD
*
thd
,
Native
*
to
);
my_decimal
*
val_decimal_result
(
my_decimal
*
);
bool
val_bool_result
();
bool
is_null_result
();
...
...
@@ -5271,6 +5402,7 @@ class Item_direct_ref :public Item_ref
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
tmp
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
bool
is_null
();
...
...
@@ -5367,6 +5499,7 @@ class Item_cache_wrapper :public Item_result_field,
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
tmp
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
bool
is_null
();
...
...
@@ -5563,6 +5696,12 @@ class Item_direct_view_ref :public Item_direct_ref
else
return
Item_direct_ref
::
val_str
(
tmp
);
}
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
if
(
check_null_ref
())
return
true
;
return
Item_direct_ref
::
val_native
(
thd
,
to
);
}
my_decimal
*
val_decimal
(
my_decimal
*
tmp
)
{
if
(
check_null_ref
())
...
...
@@ -5708,6 +5847,7 @@ class Item_ref_null_helper: public Item_ref
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
virtual
void
print
(
String
*
str
,
enum_query_type
query_type
);
table_map
used_tables
()
const
;
Item
*
get_copy
(
THD
*
thd
)
...
...
@@ -6531,6 +6671,48 @@ class Item_cache_date: public Item_cache_temporal
};
class
Item_cache_timestamp
:
public
Item_cache
{
Timestamp_or_zero_datetime_native
m_native
;
Datetime
to_datetime
(
THD
*
thd
);
public:
Item_cache_timestamp
(
THD
*
thd
)
:
Item_cache
(
thd
,
&
type_handler_timestamp2
)
{
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_cache_timestamp
>
(
thd
,
this
);
}
bool
cache_value
();
String
*
val_str
(
String
*
to
)
{
return
to_datetime
(
current_thd
).
to_string
(
to
,
decimals
);
}
my_decimal
*
val_decimal
(
my_decimal
*
to
)
{
return
to_datetime
(
current_thd
).
to_decimal
(
to
);
}
longlong
val_int
()
{
return
to_datetime
(
current_thd
).
to_longlong
();
}
double
val_real
()
{
return
to_datetime
(
current_thd
).
to_double
();
}
longlong
val_datetime_packed
(
THD
*
thd
)
{
DBUG_ASSERT
(
0
);
return
0
;
}
longlong
val_time_packed
(
THD
*
thd
)
{
DBUG_ASSERT
(
0
);
return
0
;
}
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
bool
val_native
(
THD
*
thd
,
Native
*
to
);
};
class
Item_cache_real
:
public
Item_cache
{
double
value
;
...
...
This diff is collapsed.
Click to expand it.
sql/item_cmpfunc.cc
View file @
34eb9838
...
...
@@ -567,6 +567,18 @@ bool Arg_comparator::set_cmp_func_datetime()
}
bool
Arg_comparator
::
set_cmp_func_native
()
{
THD
*
thd
=
current_thd
;
m_compare_collation
=
&
my_charset_numeric
;
func
=
is_owner_equal_func
()
?
&
Arg_comparator
::
compare_e_native
:
&
Arg_comparator
::
compare_native
;
a
=
cache_converted_constant
(
thd
,
a
,
&
a_cache
,
compare_type_handler
());
b
=
cache_converted_constant
(
thd
,
b
,
&
b_cache
,
compare_type_handler
());
return
false
;
}
bool
Arg_comparator
::
set_cmp_func_int
()
{
THD
*
thd
=
current_thd
;
...
...
@@ -770,6 +782,39 @@ int Arg_comparator::compare_e_string()
}
int
Arg_comparator
::
compare_native
()
{
THD
*
thd
=
current_thd
;
if
(
!
(
*
a
)
->
val_native_with_conversion
(
thd
,
&
m_native1
,
compare_type_handler
()))
{
if
(
!
(
*
b
)
->
val_native_with_conversion
(
thd
,
&
m_native2
,
compare_type_handler
()))
{
if
(
set_null
)
owner
->
null_value
=
0
;
return
compare_type_handler
()
->
cmp_native
(
m_native1
,
m_native2
);
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
int
Arg_comparator
::
compare_e_native
()
{
THD
*
thd
=
current_thd
;
bool
res1
=
(
*
a
)
->
val_native_with_conversion
(
thd
,
&
m_native1
,
compare_type_handler
());
bool
res2
=
(
*
b
)
->
val_native_with_conversion
(
thd
,
&
m_native2
,
compare_type_handler
());
if
(
res1
||
res2
)
return
MY_TEST
(
res1
==
res2
);
return
MY_TEST
(
compare_type_handler
()
->
cmp_native
(
m_native1
,
m_native2
)
==
0
);
}
int
Arg_comparator
::
compare_real
()
{
/*
...
...
@@ -2121,6 +2166,29 @@ longlong Item_func_between::val_int_cmp_time()
}
longlong
Item_func_between
::
val_int_cmp_native
()
{
THD
*
thd
=
current_thd
;
const
Type_handler
*
h
=
m_comparator
.
type_handler
();
NativeBuffer
<
STRING_BUFFER_USUAL_SIZE
>
value
,
a
,
b
;
if
(
val_native_with_conversion_from_item
(
thd
,
args
[
0
],
&
value
,
h
))
return
0
;
bool
ra
=
args
[
1
]
->
val_native_with_conversion
(
thd
,
&
a
,
h
);
bool
rb
=
args
[
2
]
->
val_native_with_conversion
(
thd
,
&
b
,
h
);
if
(
!
ra
&&
!
rb
)
return
(
longlong
)
((
h
->
cmp_native
(
value
,
a
)
>=
0
&&
h
->
cmp_native
(
value
,
b
)
<=
0
)
!=
negated
);
if
(
ra
&&
rb
)
null_value
=
true
;
else
if
(
ra
)
null_value
=
h
->
cmp_native
(
value
,
b
)
<=
0
;
else
null_value
=
h
->
cmp_native
(
value
,
a
)
>=
0
;
return
(
longlong
)
(
!
null_value
&&
negated
);
}
longlong
Item_func_between
::
val_int_cmp_string
()
{
String
*
value
,
*
a
,
*
b
;
...
...
@@ -2306,6 +2374,15 @@ Item_func_ifnull::str_op(String *str)
}
bool
Item_func_ifnull
::
native_op
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
val_native_with_conversion_from_item
(
thd
,
args
[
0
],
to
,
type_handler
()))
return
false
;
return
val_native_with_conversion_from_item
(
thd
,
args
[
1
],
to
,
type_handler
());
}
bool
Item_func_ifnull
::
date_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
DBUG_ASSERT
(
fixed
==
1
);
...
...
@@ -2828,6 +2905,16 @@ Item_func_nullif::time_op(THD *thd, MYSQL_TIME *ltime)
}
bool
Item_func_nullif
::
native_op
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
compare
())
return
(
null_value
=
true
);
return
val_native_with_conversion_from_item
(
thd
,
args
[
2
],
to
,
type_handler
());
}
bool
Item_func_nullif
::
is_null
()
{
...
...
@@ -3002,6 +3089,16 @@ bool Item_func_case::time_op(THD *thd, MYSQL_TIME *ltime)
}
bool
Item_func_case
::
native_op
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
item
=
find_item
();
if
(
!
item
)
return
(
null_value
=
true
);
return
val_native_with_conversion_from_item
(
thd
,
item
,
to
,
type_handler
());
}
bool
Item_func_case
::
fix_fields
(
THD
*
thd
,
Item
**
ref
)
{
bool
res
=
Item_func
::
fix_fields
(
thd
,
ref
);
...
...
@@ -3360,6 +3457,18 @@ bool Item_func_coalesce::time_op(THD *thd, MYSQL_TIME *ltime)
}
bool
Item_func_coalesce
::
native_op
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
!
val_native_with_conversion_from_item
(
thd
,
args
[
i
],
to
,
type_handler
()))
return
false
;
}
return
(
null_value
=
true
);
}
my_decimal
*
Item_func_coalesce
::
decimal_op
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
fixed
==
1
);
...
...
@@ -3637,6 +3746,53 @@ Item *in_longlong::create_item(THD *thd)
}
static
int
cmp_timestamp
(
void
*
cmp_arg
,
Timestamp_or_zero_datetime
*
a
,
Timestamp_or_zero_datetime
*
b
)
{
return
a
->
cmp
(
*
b
);
}
in_timestamp
::
in_timestamp
(
THD
*
thd
,
uint
elements
)
:
in_vector
(
thd
,
elements
,
sizeof
(
Value
),
(
qsort2_cmp
)
cmp_timestamp
,
0
)
{}
void
in_timestamp
::
set
(
uint
pos
,
Item
*
item
)
{
Timestamp_or_zero_datetime
*
buff
=
&
((
Timestamp_or_zero_datetime
*
)
base
)[
pos
];
Timestamp_or_zero_datetime_native_null
native
(
current_thd
,
item
,
true
);
if
(
native
.
is_null
())
*
buff
=
Timestamp_or_zero_datetime
();
else
*
buff
=
Timestamp_or_zero_datetime
(
native
);
}
uchar
*
in_timestamp
::
get_value
(
Item
*
item
)
{
Timestamp_or_zero_datetime_native_null
native
(
current_thd
,
item
,
true
);
if
(
native
.
is_null
())
return
0
;
tmp
=
Timestamp_or_zero_datetime
(
native
);
return
(
uchar
*
)
&
tmp
;
}
Item
*
in_timestamp
::
create_item
(
THD
*
thd
)
{
return
new
(
thd
->
mem_root
)
Item_timestamp_literal
(
thd
);
}
void
in_timestamp
::
value_to_item
(
uint
pos
,
Item
*
item
)
{
const
Timestamp_or_zero_datetime
&
buff
=
(((
Timestamp_or_zero_datetime
*
)
base
)[
pos
]);
static_cast
<
Item_timestamp_literal
*>
(
item
)
->
set_value
(
buff
);
}
void
in_datetime
::
set
(
uint
pos
,
Item
*
item
)
{
struct
packed_longlong
*
buff
=
&
((
packed_longlong
*
)
base
)[
pos
];
...
...
@@ -4044,6 +4200,49 @@ cmp_item *cmp_item_time::make_same()
}
void
cmp_item_timestamp
::
store_value
(
Item
*
item
)
{
item
->
val_native_with_conversion
(
current_thd
,
&
m_native
,
&
type_handler_timestamp2
);
m_null_value
=
item
->
null_value
;
}
int
cmp_item_timestamp
::
cmp_not_null
(
const
Value
*
val
)
{
/*
This method will be implemented when we add this syntax:
SELECT TIMESTAMP WITH LOCAL TIME ZONE '2001-01-01 10:20:30'
For now TIMESTAMP is compared to non-TIMESTAMP using DATETIME.
*/
DBUG_ASSERT
(
0
);
return
0
;
}
int
cmp_item_timestamp
::
cmp
(
Item
*
arg
)
{
THD
*
thd
=
current_thd
;
Timestamp_or_zero_datetime_native_null
tmp
(
thd
,
arg
,
true
);
return
m_null_value
||
tmp
.
is_null
()
?
UNKNOWN
:
type_handler_timestamp2
.
cmp_native
(
m_native
,
tmp
)
!=
0
;
}
int
cmp_item_timestamp
::
compare
(
cmp_item
*
arg
)
{
cmp_item_timestamp
*
tmp
=
static_cast
<
cmp_item_timestamp
*>
(
arg
);
return
type_handler_timestamp2
.
cmp_native
(
m_native
,
tmp
->
m_native
);
}
cmp_item
*
cmp_item_timestamp
::
make_same
()
{
return
new
cmp_item_timestamp
();
}
bool
Item_func_in
::
count_sargable_conds
(
void
*
arg
)
{
((
SELECT_LEX
*
)
arg
)
->
cond_count
++
;
...
...
This diff is collapsed.
Click to expand it.
sql/item_cmpfunc.h
View file @
34eb9838
...
...
@@ -68,6 +68,7 @@ class Arg_comparator: public Sql_alloc
if
(
val1
==
val2
)
return
0
;
return
1
;
}
NativeBuffer
<
STRING_BUFFER_USUAL_SIZE
>
m_native1
,
m_native2
;
public:
/* Allow owner function to use string buffers. */
String
value1
,
value2
;
...
...
@@ -89,6 +90,7 @@ class Arg_comparator: public Sql_alloc
bool
set_cmp_func_string
();
bool
set_cmp_func_time
();
bool
set_cmp_func_datetime
();
bool
set_cmp_func_native
();
bool
set_cmp_func_int
();
bool
set_cmp_func_real
();
bool
set_cmp_func_decimal
();
...
...
@@ -121,6 +123,8 @@ class Arg_comparator: public Sql_alloc
int
compare_e_datetime
();
int
compare_time
();
int
compare_e_time
();
int
compare_native
();
int
compare_e_native
();
int
compare_json_str_basic
(
Item
*
j
,
Item
*
s
);
int
compare_json_str
();
int
compare_str_json
();
...
...
@@ -935,6 +939,7 @@ class Item_func_between :public Item_func_opt_neg
longlong
val_int_cmp_string
();
longlong
val_int_cmp_datetime
();
longlong
val_int_cmp_time
();
longlong
val_int_cmp_native
();
longlong
val_int_cmp_int
();
longlong
val_int_cmp_real
();
longlong
val_int_cmp_decimal
();
...
...
@@ -1013,6 +1018,7 @@ class Item_func_coalesce :public Item_func_case_expression
my_decimal
*
decimal_op
(
my_decimal
*
);
bool
date_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
time_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
);
bool
native_op
(
THD
*
thd
,
Native
*
to
);
bool
fix_length_and_dec
()
{
if
(
aggregate_for_result
(
func_name
(),
args
,
arg_count
,
true
))
...
...
@@ -1092,6 +1098,7 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
my_decimal
*
decimal_op
(
my_decimal
*
);
bool
date_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
time_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
);
bool
native_op
(
THD
*
thd
,
Native
*
to
);
bool
fix_length_and_dec
()
{
if
(
Item_func_case_abbreviation2
::
fix_length_and_dec2
(
args
))
...
...
@@ -1150,6 +1157,11 @@ class Item_func_case_abbreviation2_switch: public Item_func_case_abbreviation2
{
return
val_str_from_item
(
find_item
(),
str
);
}
bool
native_op
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_with_conversion_from_item
(
thd
,
find_item
(),
to
,
type_handler
());
}
};
...
...
@@ -1249,6 +1261,7 @@ class Item_func_nullif :public Item_func_case_expression
longlong
int_op
();
String
*
str_op
(
String
*
str
);
my_decimal
*
decimal_op
(
my_decimal
*
);
bool
native_op
(
THD
*
thd
,
Native
*
to
);
bool
fix_length_and_dec
();
bool
walk
(
Item_processor
processor
,
bool
walk_subquery
,
void
*
arg
);
const
char
*
func_name
()
const
{
return
"nullif"
;
}
...
...
@@ -1412,6 +1425,19 @@ class in_longlong :public in_vector
};
class
in_timestamp
:
public
in_vector
{
Timestamp_or_zero_datetime
tmp
;
public:
in_timestamp
(
THD
*
thd
,
uint
elements
);
void
set
(
uint
pos
,
Item
*
item
);
uchar
*
get_value
(
Item
*
item
);
Item
*
create_item
(
THD
*
thd
);
void
value_to_item
(
uint
pos
,
Item
*
item
);
const
Type_handler
*
type_handler
()
const
{
return
&
type_handler_timestamp2
;
}
};
/*
Class to represent a vector of constant DATE/DATETIME values.
*/
...
...
@@ -1666,6 +1692,20 @@ class cmp_item_time: public cmp_item_temporal
cmp_item
*
make_same
();
};
class
cmp_item_timestamp
:
public
cmp_item_scalar
{
Timestamp_or_zero_datetime_native
m_native
;
public:
cmp_item_timestamp
()
:
cmp_item_scalar
()
{
}
void
store_value
(
Item
*
item
);
int
cmp_not_null
(
const
Value
*
val
);
int
cmp
(
Item
*
arg
);
int
compare
(
cmp_item
*
ci
);
cmp_item
*
make_same
();
};
class
cmp_item_real
:
public
cmp_item_scalar
{
double
value
;
...
...
@@ -2132,6 +2172,7 @@ class Item_func_case :public Item_func_case_expression
my_decimal
*
decimal_op
(
my_decimal
*
);
bool
date_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
time_op
(
THD
*
thd
,
MYSQL_TIME
*
ltime
);
bool
native_op
(
THD
*
thd
,
Native
*
to
);
bool
fix_fields
(
THD
*
thd
,
Item
**
ref
);
table_map
not_null_tables
()
const
{
return
0
;
}
const
char
*
func_name
()
const
{
return
"case"
;
}
...
...
This diff is collapsed.
Click to expand it.
sql/item_func.cc
View file @
34eb9838
...
...
@@ -2730,6 +2730,28 @@ my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
}
bool
Item_func_min_max
::
val_native
(
THD
*
thd
,
Native
*
native
)
{
DBUG_ASSERT
(
fixed
==
1
);
const
Type_handler
*
handler
=
Item_hybrid_func
::
type_handler
();
NativeBuffer
<
STRING_BUFFER_USUAL_SIZE
>
cur
;
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
val_native_with_conversion_from_item
(
thd
,
args
[
i
],
i
==
0
?
native
:
&
cur
,
handler
))
return
true
;
if
(
i
>
0
)
{
int
cmp
=
handler
->
cmp_native
(
*
native
,
cur
);
if
((
cmp_sign
<
0
?
cmp
:
-
cmp
)
<
0
&&
native
->
copy
(
cur
))
return
null_value
=
true
;
}
}
return
null_value
=
false
;
}
longlong
Item_func_bit_length
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
...
...
@@ -6453,6 +6475,14 @@ String *Item_func_last_value::val_str(String *str)
return
tmp
;
}
bool
Item_func_last_value
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
evaluate_sideeffects
();
return
val_native_from_item
(
thd
,
last_value
,
to
);
}
longlong
Item_func_last_value
::
val_int
()
{
longlong
tmp
;
...
...
This diff is collapsed.
Click to expand it.
sql/item_func.h
View file @
34eb9838
...
...
@@ -768,6 +768,12 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
Item_func_hybrid_field_type_get_date_with_warn
(
thd
,
this
,
to
,
mode
);
}
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
);
return
native_op
(
thd
,
to
);
}
/**
@brief Performs the operation that this functions implements when the
result type is INT.
...
...
@@ -838,6 +844,7 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
*/
virtual
bool
time_op
(
THD
*
thd
,
MYSQL_TIME
*
res
)
=
0
;
virtual
bool
native_op
(
THD
*
thd
,
Native
*
native
)
=
0
;
};
...
...
@@ -905,6 +912,11 @@ class Item_func_numhybrid: public Item_func_hybrid_field_type
DBUG_ASSERT
(
0
);
return
true
;
}
bool
native_op
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
0
);
return
true
;
}
};
...
...
@@ -1771,6 +1783,7 @@ class Item_func_min_max :public Item_hybrid_func
return
Item_func_min_max
::
type_handler
()
->
Item_func_min_max_get_date
(
thd
,
this
,
res
,
fuzzydate
);
}
bool
val_native
(
THD
*
thd
,
Native
*
to
);
void
aggregate_attributes_real
(
Item
**
items
,
uint
nitems
)
{
/*
...
...
@@ -1834,6 +1847,8 @@ class Item_func_rollup_const :public Item_func
double
val_real
()
{
return
val_real_from_item
(
args
[
0
]);
}
longlong
val_int
()
{
return
val_int_from_item
(
args
[
0
]);
}
String
*
val_str
(
String
*
str
)
{
return
val_str_from_item
(
args
[
0
],
str
);
}
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
return
val_native_from_item
(
thd
,
args
[
0
],
to
);
}
my_decimal
*
val_decimal
(
my_decimal
*
dec
)
{
return
val_decimal_from_item
(
args
[
0
],
dec
);
}
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
...
...
@@ -3153,6 +3168,13 @@ class Item_func_sp :public Item_func,
return
str
;
}
bool
val_native
(
THD
*
thd
,
Native
*
to
)
{
if
(
execute
())
return
true
;
return
null_value
=
sp_result_field
->
val_native
(
to
);
}
void
update_null_value
()
{
execute
();
...
...
@@ -3282,6 +3304,7 @@ class Item_func_last_value :public Item_func
String
*
val_str
(
String
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
val_native
(
THD
*
thd
,
Native
*
);
bool
fix_length_and_dec
();
const
char
*
func_name
()
const
{
return
"last_value"
;
}
const
Type_handler
*
type_handler
()
const
{
return
last_value
->
type_handler
();
}
...
...
This diff is collapsed.
Click to expand it.
sql/item_subselect.cc
View file @
34eb9838
...
...
@@ -1352,6 +1352,24 @@ String *Item_singlerow_subselect::val_str(String *str)
}
bool
Item_singlerow_subselect
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
forced_const
)
return
value
->
val_native
(
thd
,
to
);
if
(
!
exec
()
&&
!
value
->
null_value
)
{
null_value
=
false
;
return
value
->
val_native
(
thd
,
to
);
}
else
{
reset
();
return
true
;
}
}
my_decimal
*
Item_singlerow_subselect
::
val_decimal
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
fixed
==
1
);
...
...
This diff is collapsed.
Click to expand it.
sql/item_subselect.h
View file @
34eb9838
...
...
@@ -306,6 +306,7 @@ class Item_singlerow_subselect :public Item_subselect
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
);
bool
val_native
(
THD
*
thd
,
Native
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
...
...
This diff is collapsed.
Click to expand it.
sql/item_sum.cc
View file @
34eb9838
...
...
@@ -2381,6 +2381,15 @@ Item_sum_hybrid::val_str(String *str)
}
bool
Item_sum_hybrid
::
val_native
(
THD
*
thd
,
Native
*
to
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
return
true
;
return
val_native_from_item
(
thd
,
value
,
to
);
}
void
Item_sum_hybrid
::
cleanup
()
{
DBUG_ENTER
(
"Item_sum_hybrid::cleanup"
);
...
...
This diff is collapsed.
Click to expand it.
sql/item_sum.h
View file @
34eb9838
...
...
@@ -1072,6 +1072,7 @@ class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
void
reset_field
();
String
*
val_str
(
String
*
);
bool
val_native
(
THD
*
thd
,
Native
*
);
const
Type_handler
*
real_type_handler
()
const
{
return
get_arg
(
0
)
->
real_type_handler
();
...
...
This diff is collapsed.
Click to expand it.
sql/item_timefunc.cc
View file @
34eb9838
...
...
@@ -1217,15 +1217,13 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
}
}
THD
*
thd
=
current_thd
;
Datetime
dt
(
thd
,
args
[
0
],
Datetime
::
Options
(
TIME_NO_ZERO_IN_DATE
,
thd
));
if
((
null_value
=
!
dt
.
is_valid_datetime
()))
Timestamp_or_zero_datetime_native_null
native
(
current_thd
,
args
[
0
],
true
);
if
((
null_value
=
native
.
is_null
()
||
native
.
is_zero_datetime
()))
return
true
;
uint
error_code
;
*
seconds
=
TIME_to_timestamp
(
thd
,
dt
.
get_mysql_time
(),
&
error_code
);
*
second_part
=
dt
.
get_mysql_time
()
->
second_part
;
return
(
null_value
=
(
error_code
==
ER_WARN_DATA_OUT_OF_RANGE
));
Timestamp_or_zero_datetime
tm
(
native
);
*
seconds
=
tm
.
tv
().
tv_sec
;
*
second_part
=
tm
.
tv
().
tv_usec
;
return
false
;
}
...
...
This diff is collapsed.
Click to expand it.
sql/sql_type.cc
View file @
34eb9838
This diff is collapsed.
Click to expand it.
sql/sql_type.h
View file @
34eb9838
This diff is collapsed.
Click to expand it.
sql/structs.h
View file @
34eb9838
...
...
@@ -847,6 +847,8 @@ class Load_data_outvar
class
Timeval
:
public
timeval
{
protected:
Timeval
()
{
}
public:
Timeval
(
my_time_t
sec
,
ulong
usec
)
{
...
...
This diff is collapsed.
Click to expand it.
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