summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Smirnov <olernov@gmail.com>2023-04-11 11:18:42 +0700
committerOleg Smirnov <olernov@gmail.com>2023-04-25 20:21:36 +0700
commitaf0e0ad18d5295d57696e3d26d5a7b13dca4e420 (patch)
tree3daf3e392ea6d311beefffe4d92967542e714f78
parent9f9a53be4057a1c65478dfd04cd11fe9c079ce59 (diff)
downloadmariadb-git-af0e0ad18d5295d57696e3d26d5a7b13dca4e420.tar.gz
MDEV-30946 Index usage for DATE(datetime_column) = const does not work for DELETE and UPDATEpreview-11.1-mdev-8320
Add date conditions transformation to the execution paths of DELETE and UPDATE commands. Strip excessive prepared statements from the test file
-rw-r--r--mysql-test/main/sargable_date_cond.result1424
-rw-r--r--mysql-test/main/sargable_date_cond.test397
-rw-r--r--sql/sql_delete.cc6
-rw-r--r--sql/sql_update.cc6
4 files changed, 482 insertions, 1351 deletions
diff --git a/mysql-test/main/sargable_date_cond.result b/mysql-test/main/sargable_date_cond.result
index 86dd5cbfe19..11b6684789d 100644
--- a/mysql-test/main/sargable_date_cond.result
+++ b/mysql-test/main/sargable_date_cond.result
@@ -20,6 +20,7 @@ test.t2 analyze status Table is already up to date
select count(*) from t2 where year(a) < 2018;
count(*)
460
+# Compare the results, they must be equal:
select count(*) from t2 where a < '2018-01-01';
count(*)
460
@@ -132,55 +133,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where year(a) <= ?"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 90.30000305,
- "attached_condition": "t2.a <= '2018-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where year(a) <= 2018";
-execute stmt;
-count(*)
-920
-execute stmt;
-count(*)
-920
-create or replace view v1 as select count(*) from t2 where year(a) <= 2018;
-select * from v1;
-count(*)
-920
-create or replace procedure sp() select count(*) from t2 where year(a) <= 2018;
-call sp();
-count(*)
-920
-call sp();
-count(*)
-920
-prepare stmt from "select count(*) from t2 where year(a) <= ?";
-execute stmt using 2018;
-count(*)
-920
-execute stmt using 2017;
-count(*)
-460
select count(*) from t2 where year(a) > 2018;
count(*)
80
@@ -213,58 +165,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where year(a) > ?"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.121025977,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "range",
- "possible_keys": ["a"],
- "key": "a",
- "key_length": "6",
- "used_key_parts": ["a"],
- "loops": 1,
- "rows": 97,
- "cost": 0.121025977,
- "filtered": 100,
- "index_condition": "t2.a > '2018-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where year(a) > 2018";
-execute stmt;
-count(*)
-80
-execute stmt;
-count(*)
-80
-create or replace view v1 as select count(*) from t2 where year(a) > 2018;
-select * from v1;
-count(*)
-80
-create or replace procedure sp() select count(*) from t2 where year(a) > 2018;
-call sp();
-count(*)
-80
-call sp();
-count(*)
-80
-prepare stmt from "select count(*) from t2 where year(a) > ?";
-execute stmt using 2018;
-count(*)
-80
-execute stmt using 2017;
-count(*)
-540
select count(*) from t2 where year(a) >= 2018;
count(*)
540
@@ -297,55 +197,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where year(a) >= ?"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 54.90000153,
- "attached_condition": "t2.a >= '2018-01-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where year(a) >= 2018";
-execute stmt;
-count(*)
-540
-execute stmt;
-count(*)
-540
-create or replace view v1 as select count(*) from t2 where year(a) >= 2018;
-select * from v1;
-count(*)
-540
-create or replace procedure sp() select count(*) from t2 where year(a) >= 2018;
-call sp();
-count(*)
-540
-call sp();
-count(*)
-540
-prepare stmt from "select count(*) from t2 where year(a) >= ?";
-execute stmt using 2018;
-count(*)
-540
-execute stmt using 2019;
-count(*)
-80
select count(*) from t2 where year(a) = 2017;
count(*)
460
@@ -378,55 +229,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where year(a) = ?"
- using 2017;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 45.09999847,
- "attached_condition": "t2.a between '2017-01-01 00:00:00' and '2017-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where year(a) = 2017";
-execute stmt;
-count(*)
-460
-execute stmt;
-count(*)
-460
-create or replace view v1 as select count(*) from t2 where year(a) = 2017;
-select * from v1;
-count(*)
-460
-create or replace procedure sp() select count(*) from t2 where year(a) = 2017;
-call sp();
-count(*)
-460
-call sp();
-count(*)
-460
-prepare stmt from "select count(*) from t2 where year(a) = ?";
-execute stmt using 2017;
-count(*)
-460
-execute stmt using 2019;
-count(*)
-80
#
# "YEAR(datetime_col) CMP year_value", reverse argument order
#
@@ -462,55 +264,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? < year(a)"
- using 2017;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 54.90000153,
- "attached_condition": "t2.a > '2017-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where 2017 < year(a)";
-execute stmt;
-count(*)
-540
-execute stmt;
-count(*)
-540
-create or replace view v1 as select count(*) from t2 where 2017 < year(a);
-select * from v1;
-count(*)
-540
-create or replace procedure sp() select count(*) from t2 where 2017 < year(a);
-call sp();
-count(*)
-540
-call sp();
-count(*)
-540
-prepare stmt from "select count(*) from t2 where ? < year(a)";
-execute stmt using 2017;
-count(*)
-540
-execute stmt using 2018;
-count(*)
-80
select count(*) from t2 where a >= '2018-01-01';
count(*)
540
@@ -540,55 +293,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? <= year(a)"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 54.90000153,
- "attached_condition": "t2.a >= '2018-01-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where 2018 <= year(a)";
-execute stmt;
-count(*)
-540
-execute stmt;
-count(*)
-540
-create or replace view v1 as select count(*) from t2 where 2018 <= year(a);
-select * from v1;
-count(*)
-540
-create or replace procedure sp() select count(*) from t2 where 2018 <= year(a);
-call sp();
-count(*)
-540
-call sp();
-count(*)
-540
-prepare stmt from "select count(*) from t2 where ? <= year(a)";
-execute stmt using 2018;
-count(*)
-540
-execute stmt using 2019;
-count(*)
-80
select count(*) from t2 where 2018 > year(a);
count(*)
460
@@ -621,55 +325,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? > year(a)"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 45.09999847,
- "attached_condition": "t2.a < '2018-01-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where 2018 > year(a)";
-execute stmt;
-count(*)
-460
-execute stmt;
-count(*)
-460
-create or replace view v1 as select count(*) from t2 where 2018 > year(a);
-select * from v1;
-count(*)
-460
-create or replace procedure sp() select count(*) from t2 where 2018 > year(a);
-call sp();
-count(*)
-460
-call sp();
-count(*)
-460
-prepare stmt from "select count(*) from t2 where ? > year(a)";
-execute stmt using 2018;
-count(*)
-460
-execute stmt using 2019;
-count(*)
-920
select count(*) from t2 where a < '2019-01-01';
count(*)
920
@@ -699,55 +354,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? >= year(a)"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 90.30000305,
- "attached_condition": "t2.a <= '2018-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where 2018 >= year(a)";
-execute stmt;
-count(*)
-920
-execute stmt;
-count(*)
-920
-create or replace view v1 as select count(*) from t2 where 2018 >= year(a);
-select * from v1;
-count(*)
-920
-create or replace procedure sp() select count(*) from t2 where 2018 >= year(a);
-call sp();
-count(*)
-920
-call sp();
-count(*)
-920
-prepare stmt from "select count(*) from t2 where ? >= year(a)";
-execute stmt using 2018;
-count(*)
-920
-execute stmt using 2019;
-count(*)
-1000
select count(*) from t2 where 2018 = year(a);
count(*)
460
@@ -780,55 +386,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? = year(a)"
- using 2018;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 45.20000076,
- "attached_condition": "t2.a between '2018-01-01 00:00:00' and '2018-12-31 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where 2018 = year(a)";
-execute stmt;
-count(*)
-460
-execute stmt;
-count(*)
-460
-create or replace view v1 as select count(*) from t2 where 2018 = year(a);
-select * from v1;
-count(*)
-460
-create or replace procedure sp() select count(*) from t2 where 2018 = year(a);
-call sp();
-count(*)
-460
-call sp();
-count(*)
-460
-prepare stmt from "select count(*) from t2 where ? = year(a)";
-execute stmt using 2018;
-count(*)
-460
-execute stmt using 2019;
-count(*)
-80
#
# "DATE(datetime_col) CMP date_value", basic checks
#
@@ -864,55 +421,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where date(a) < ?"
- using '2017-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 18.60000038,
- "attached_condition": "t2.a < '2017-06-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where date(a) < '2017-06-01'";
-execute stmt;
-count(*)
-190
-execute stmt;
-count(*)
-190
-create or replace view v1 as select count(*) from t2 where date(a) < '2017-06-01';
-select * from v1;
-count(*)
-190
-create or replace procedure sp() select count(*) from t2 where date(a) < '2017-06-01';
-call sp();
-count(*)
-190
-call sp();
-count(*)
-190
-prepare stmt from "select count(*) from t2 where date(a) < ?";
-execute stmt using '2017-06-01';
-count(*)
-190
-execute stmt using '2017-06-05';
-count(*)
-200
select count(*) from t2 where date(a) <= '2017-06-03';
count(*)
200
@@ -945,55 +453,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where date(a) <= ?"
- using '2017-06-04';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 19.60000038,
- "attached_condition": "t2.a <= '2017-06-04 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where date(a) <= '2017-06-03'";
-execute stmt;
-count(*)
-200
-execute stmt;
-count(*)
-200
-create or replace view v1 as select count(*) from t2 where date(a) <= '2017-06-03';
-select * from v1;
-count(*)
-200
-create or replace procedure sp() select count(*) from t2 where date(a) <= '2017-06-03';
-call sp();
-count(*)
-200
-call sp();
-count(*)
-200
-prepare stmt from "select count(*) from t2 where date(a) <= ?";
-execute stmt using '2017-06-03';
-count(*)
-200
-execute stmt using '2017-06-10';
-count(*)
-210
select count(*) from t2 where date(a) > '2018-06-01';
count(*)
350
@@ -1026,55 +485,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where date(a) > ?"
- using '2018-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 36.29999924,
- "attached_condition": "t2.a > '2018-06-01 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where date(a) > '2018-06-01'";
-execute stmt;
-count(*)
-350
-execute stmt;
-count(*)
-350
-create or replace view v1 as select count(*) from t2 where date(a) > '2018-06-01';
-select * from v1;
-count(*)
-350
-create or replace procedure sp() select count(*) from t2 where date(a) > '2018-06-01';
-call sp();
-count(*)
-350
-call sp();
-count(*)
-350
-prepare stmt from "select count(*) from t2 where date(a) > ?";
-execute stmt using '2018-06-01';
-count(*)
-350
-execute stmt using '2018-06-05';
-count(*)
-340
select count(*) from t2 where date(a) >= '2018-06-01';
count(*)
350
@@ -1107,55 +517,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where date(a) >= ?"
- using '2018-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 36.29999924,
- "attached_condition": "t2.a >= '2018-06-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where date(a) >= '2018-06-01'";
-execute stmt;
-count(*)
-350
-execute stmt;
-count(*)
-350
-create or replace view v1 as select count(*) from t2 where date(a) >= '2018-06-01';
-select * from v1;
-count(*)
-350
-create or replace procedure sp() select count(*) from t2 where date(a) >= '2018-06-01';
-call sp();
-count(*)
-350
-call sp();
-count(*)
-350
-prepare stmt from "select count(*) from t2 where date(a) >= ?";
-execute stmt using '2018-06-01';
-count(*)
-350
-execute stmt using '2018-06-10';
-count(*)
-340
select count(*) from t2 where date(a) = '2017-06-02';
count(*)
10
@@ -1188,58 +549,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where date(a) = ?"
- using '2017-06-02';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.013679374,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "range",
- "possible_keys": ["a"],
- "key": "a",
- "key_length": "6",
- "used_key_parts": ["a"],
- "loops": 1,
- "rows": 10,
- "cost": 0.013679374,
- "filtered": 100,
- "index_condition": "t2.a between '2017-06-02 00:00:00' and '2017-06-02 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where date(a) = '2017-06-02'";
-execute stmt;
-count(*)
-10
-execute stmt;
-count(*)
-10
-create or replace view v1 as select count(*) from t2 where date(a) = '2017-06-02';
-select * from v1;
-count(*)
-10
-create or replace procedure sp() select count(*) from t2 where date(a) = '2017-06-02';
-call sp();
-count(*)
-10
-call sp();
-count(*)
-10
-prepare stmt from "select count(*) from t2 where date(a) = ?";
-execute stmt using '2017-06-02';
-count(*)
-10
-execute stmt using '2017-06-05';
-count(*)
-0
#
# "DATE(datetime_col) CMP date_value", reverse order
#
@@ -1275,55 +584,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? > date(a)"
- using '2017-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 18.60000038,
- "attached_condition": "t2.a < '2017-06-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where '2017-06-01' > date(a)";
-execute stmt;
-count(*)
-190
-execute stmt;
-count(*)
-190
-create or replace view v1 as select count(*) from t2 where '2017-06-01' > date(a);
-select * from v1;
-count(*)
-190
-create or replace procedure sp() select count(*) from t2 where '2017-06-01' > date(a);
-call sp();
-count(*)
-190
-call sp();
-count(*)
-190
-prepare stmt from "select count(*) from t2 where ? > date(a)";
-execute stmt using '2017-06-01';
-count(*)
-190
-execute stmt using '2017-06-05';
-count(*)
-200
select count(*) from t2 where '2017-06-03' >= date(a);
count(*)
200
@@ -1356,55 +616,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? >= date(a)"
- using '2017-06-03';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 19.60000038,
- "attached_condition": "t2.a <= '2017-06-03 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where '2017-06-03' >= date(a)";
-execute stmt;
-count(*)
-200
-execute stmt;
-count(*)
-200
-create or replace view v1 as select count(*) from t2 where '2017-06-03' >= date(a);
-select * from v1;
-count(*)
-200
-create or replace procedure sp() select count(*) from t2 where '2017-06-03' >= date(a);
-call sp();
-count(*)
-200
-call sp();
-count(*)
-200
-prepare stmt from "select count(*) from t2 where ? >= date(a)";
-execute stmt using '2017-06-03';
-count(*)
-200
-execute stmt using '2017-06-12';
-count(*)
-210
select count(*) from t2 where '2018-06-01' < date(a);
count(*)
350
@@ -1437,55 +648,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? < date(a)"
- using '2017-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 81.40000153,
- "attached_condition": "t2.a > '2017-06-01 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where '2018-06-01' < date(a)";
-execute stmt;
-count(*)
-350
-execute stmt;
-count(*)
-350
-create or replace view v1 as select count(*) from t2 where '2018-06-01' < date(a);
-select * from v1;
-count(*)
-350
-create or replace procedure sp() select count(*) from t2 where '2018-06-01' < date(a);
-call sp();
-count(*)
-350
-call sp();
-count(*)
-350
-prepare stmt from "select count(*) from t2 where ? < date(a)";
-execute stmt using '2018-06-02';
-count(*)
-350
-execute stmt using '2018-06-15';
-count(*)
-330
select count(*) from t2 where '2018-06-01' <= date(a);
count(*)
350
@@ -1518,55 +680,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? <= date(a)"
- using '2017-06-01';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.1671618,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "possible_keys": ["a"],
- "loops": 1,
- "rows": 1000,
- "cost": 0.1671618,
- "filtered": 81.40000153,
- "attached_condition": "t2.a >= '2017-06-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where '2018-06-01' <= date(a)";
-execute stmt;
-count(*)
-350
-execute stmt;
-count(*)
-350
-create or replace view v1 as select count(*) from t2 where '2018-06-01' <= date(a);
-select * from v1;
-count(*)
-350
-create or replace procedure sp() select count(*) from t2 where '2018-06-01' <= date(a);
-call sp();
-count(*)
-350
-call sp();
-count(*)
-350
-prepare stmt from "select count(*) from t2 where ? <= date(a)";
-execute stmt using '2018-06-01';
-count(*)
-350
-execute stmt using '2018-06-15';
-count(*)
-330
select count(*) from t2 where '2017-06-02' = date(a);
count(*)
10
@@ -1599,58 +712,6 @@ EXPLAIN
]
}
}
-execute immediate
-"explain format=json select * from t2 where ? = date(a)"
- using '2017-06-02';
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.013679374,
- "nested_loop": [
- {
- "table": {
- "table_name": "t2",
- "access_type": "range",
- "possible_keys": ["a"],
- "key": "a",
- "key_length": "6",
- "used_key_parts": ["a"],
- "loops": 1,
- "rows": 10,
- "cost": 0.013679374,
- "filtered": 100,
- "index_condition": "t2.a between '2017-06-02 00:00:00' and '2017-06-02 23:59:59'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t2 where '2017-06-02' = date(a)";
-execute stmt;
-count(*)
-10
-execute stmt;
-count(*)
-10
-create or replace view v1 as select count(*) from t2 where '2017-06-02' = date(a);
-select * from v1;
-count(*)
-10
-create or replace procedure sp() select count(*) from t2 where '2017-06-02' = date(a);
-call sp();
-count(*)
-10
-call sp();
-count(*)
-10
-prepare stmt from "select count(*) from t2 where ? = date(a)";
-execute stmt using '2017-06-03';
-count(*)
-0
-execute stmt using '2017-06-10';
-count(*)
-10
# Check rewrite of a more complicated query
explain format=json select * from t2 as t21 force index(a),
t2 as t22 force index(a)
@@ -1892,31 +953,6 @@ EXPLAIN
]
}
}
-prepare stmt from "select count(*) from t2 where date(b)< '2017-06-03'";
-execute stmt;
-count(*)
-220
-execute stmt;
-count(*)
-220
-create or replace view v1 as select count(*) from t2 where date(b)< '2017-06-03';
-select * from v1;
-count(*)
-220
-create or replace procedure sp() select count(*) from t2 where date(b)< '2017-06-03';
-call sp();
-count(*)
-220
-call sp();
-count(*)
-220
-prepare stmt from "select count(*) from t2 where date(b) < ?";
-execute stmt using '2017-06-03';
-count(*)
-220
-execute stmt using '2017-06-10';
-count(*)
-230
select count(*) from t2 where date(b)= '2017-06-04';
count(*)
10
@@ -1949,31 +985,6 @@ EXPLAIN
]
}
}
-prepare stmt from "select count(*) from t2 where date(b)= '2017-06-04'";
-execute stmt;
-count(*)
-10
-execute stmt;
-count(*)
-10
-create or replace view v1 as select count(*) from t2 where date(b)= '2017-06-04';
-select * from v1;
-count(*)
-10
-create or replace procedure sp() select count(*) from t2 where date(b)= '2017-06-04';
-call sp();
-count(*)
-10
-call sp();
-count(*)
-10
-prepare stmt from "select count(*) from t2 where date(b) = ?";
-execute stmt using '2017-06-04';
-count(*)
-10
-execute stmt using '2017-06-10';
-count(*)
-0
#
# Check actual query results
#
@@ -2047,6 +1058,8 @@ pk a b
# Test the TIMESTAMP column
#
create table t3 (a timestamp, b date, key(a));
+# Insert data starting from 2016 since that year had a leap second
+# (https://en.wikipedia.org/wiki/Leap_second)
set time_zone="UTC";
insert into t3
select
@@ -2089,60 +1102,6 @@ EXPLAIN
]
}
}
-# Check rewrite for a prepared statement:
-execute immediate
-"explain format=json select * from t3 force index(a) where year(a) < ?"
- using 2017;
-EXPLAIN
-{
- "query_block": {
- "select_id": 1,
- "cost": 0.562991479,
- "nested_loop": [
- {
- "table": {
- "table_name": "t3",
- "access_type": "range",
- "possible_keys": ["a"],
- "key": "a",
- "key_length": "5",
- "used_key_parts": ["a"],
- "loops": 1,
- "rows": 455,
- "cost": 0.562991479,
- "filtered": 100,
- "index_condition": "t3.a < '2017-01-01 00:00:00'"
- }
- }
- ]
- }
-}
-prepare stmt from "select count(*) from t3 force index(a) where year(a)= 2016";
-execute stmt;
-count(*)
-460
-execute stmt;
-count(*)
-460
-create or replace view v1 as select count(*) from t3 force index(a) where year(a)= 2016;
-select * from v1;
-count(*)
-460
-create or replace procedure sp() select count(*) from t3 force index(a) where year(a)= 2016;
-call sp();
-count(*)
-460
-call sp();
-count(*)
-460
-# Prepared statement with a placeholder
-prepare stmt from "select count(*) from t3 where year(a) < ?";
-execute stmt using 2017;
-count(*)
-460
-execute stmt using 2018;
-count(*)
-920
set time_zone= @@global.time_zone;
#
# Incorrect const values processing (no rewrite is possible)
@@ -2669,3 +1628,380 @@ EXPLAIN
drop table t0,t1,t2,t3,t4,t5,t6;
drop view v1;
drop procedure sp;
+#
+# MDEV-30946 Index usage for DATE(datetime_column) = const
+# does not work for DELETE and UPDATE
+#
+create table t1 (pk int primary key, a datetime, c int, key(a));
+insert into t1 (pk,a,c) values (1,'2009-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (2,'2009-11-29 03:23:32', 2);
+insert into t1 (pk,a,c) values (3,'2009-10-16 05:56:32', 2);
+insert into t1 (pk,a,c) values (4,'2010-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (5,'2010-10-16 05:56:32', 2);
+insert into t1 (pk,a,c) values (6,'2011-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (7,'2012-10-16 05:56:32', 2);
+# YEAR() conditions, UPDATE
+explain format=json update t1 set c = 0 where year(a) = 2010;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "update": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 2,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'"
+ }
+ }
+}
+update t1 set c = 0 where year(a) = 2010;
+select * from t1;
+pk a c
+1 2009-11-29 13:43:32 2
+2 2009-11-29 03:23:32 2
+3 2009-10-16 05:56:32 2
+4 2010-11-29 13:43:32 0
+5 2010-10-16 05:56:32 0
+6 2011-11-29 13:43:32 2
+7 2012-10-16 05:56:32 2
+explain format=json update t1 set c = 1
+where c < (select count(*) from t1 where year(a) = 2010);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "cost": 0.011130435,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "loops": 1,
+ "rows": 7,
+ "cost": 0.011130435,
+ "filtered": 100,
+ "attached_condition": "t1.c < (subquery#2)"
+ }
+ }
+ ],
+ "subqueries": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "cost": 0.001617224,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "loops": 1,
+ "rows": 2,
+ "cost": 0.001617224,
+ "filtered": 100,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'",
+ "using_index": true
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
+explain format=json update t1 set c = 0
+where year(a) = 2010 and c < (select count(*) from t1 where year(a) = 2010);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "cost": 0.003808422,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "loops": 1,
+ "rows": 2,
+ "cost": 0.003808422,
+ "filtered": 100,
+ "index_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'",
+ "attached_condition": "t1.c < (subquery#2)"
+ }
+ }
+ ],
+ "subqueries": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "cost": 0.001617224,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "loops": 1,
+ "rows": 2,
+ "cost": 0.001617224,
+ "filtered": 100,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'",
+ "using_index": true
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
+# Multi-table update
+create table t2 (a int);
+insert into t2 values (4),(5),(6);
+explain format=json update t1, t2 set c = 0
+where year(t1.a) = 2010 and t1.c = t2.a;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "cost": 0.014992165,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "loops": 1,
+ "rows": 2,
+ "cost": 0.003808422,
+ "filtered": 100,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'"
+ }
+ },
+ {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "loops": 2,
+ "rows": 3,
+ "cost": 0.011183743,
+ "filtered": 100,
+ "attached_condition": "t2.a = t1.c"
+ }
+ }
+ ]
+ }
+}
+prepare stmt from "update t1 set c = 0 where year(a) = 2010";
+execute stmt;
+execute stmt;
+# YEAR() conditions, DELETE
+explain format=json delete from t1 where year(a) = 2010;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "delete": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 2,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'"
+ }
+ }
+}
+delete from t1 where year(a) = 2010;
+select * from t1;
+pk a c
+1 2009-11-29 13:43:32 2
+2 2009-11-29 03:23:32 2
+3 2009-10-16 05:56:32 2
+6 2011-11-29 13:43:32 2
+7 2012-10-16 05:56:32 2
+explain format=json delete from t1
+where c < (select count(*) from t1 where year(a) = 2010);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "cost": 0.010817625,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "loops": 1,
+ "rows": 5,
+ "cost": 0.010817625,
+ "filtered": 100,
+ "attached_condition": "t1.c < (subquery#2)"
+ }
+ }
+ ],
+ "subqueries": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "cost": 0.001478954,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "loops": 1,
+ "rows": 1,
+ "cost": 0.001478954,
+ "filtered": 100,
+ "attached_condition": "t1.a between '2010-01-01 00:00:00' and '2010-12-31 23:59:59'",
+ "using_index": true
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
+delete from t1 where c < (select count(*) from t1 where year(a) = 2010);
+prepare stmt from "delete from t1 where year(a) = 2009";
+execute stmt;
+execute stmt;
+select * from t1;
+pk a c
+6 2011-11-29 13:43:32 2
+7 2012-10-16 05:56:32 2
+# DATE() conditions, UPDATE
+explain format=json update t1 set c = 0 where date(a) = '2010-10-16';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "update": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "attached_condition": "t1.a between '2010-10-16 00:00:00' and '2010-10-16 23:59:59'"
+ }
+ }
+}
+explain format=json update t1 set c = 0 where date(a) <= '2011-10-16';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "update": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "attached_condition": "t1.a <= '2011-10-16 23:59:59'"
+ }
+ }
+}
+prepare stmt from "update t1 set c = 3 where date(a) = '2011-11-29'";
+execute stmt;
+execute stmt;
+select * from t1;
+pk a c
+6 2011-11-29 13:43:32 3
+7 2012-10-16 05:56:32 2
+# DATE() conditions, DELETE
+explain format=json delete from t1 where date(a) = '2010-10-16';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "delete": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "attached_condition": "t1.a between '2010-10-16 00:00:00' and '2010-10-16 23:59:59'"
+ }
+ }
+}
+explain format=json delete from t1 where date(a) <= '2011-10-16';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "delete": 1,
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["a"],
+ "key": "a",
+ "key_length": "6",
+ "used_key_parts": ["a"],
+ "rows": 1,
+ "attached_condition": "t1.a <= '2011-10-16 23:59:59'"
+ }
+ }
+}
+prepare stmt from "delete from t1 where date(a) <= '2012-01-01'";
+execute stmt;
+execute stmt;
+select * from t1;
+pk a c
+7 2012-10-16 05:56:32 2
+# Test partition pruning
+create table t3 (
+a datetime,
+key(a)
+) partition by range(year(a)) (
+partition p0 values less than (2022),
+partition p1 values less than (MAXVALUE)
+);
+insert into t3
+select date_add('2020-01-01', interval seq*10 day)
+from seq_1_to_100;
+# Must be only "p0" partition
+explain partitions select * from t3 where year(a) = 2020;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 p0 range a a 6 NULL 36 Using where; Using index
+explain partitions delete from t3 where year(a) = 2020;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 p0 ALL a NULL NULL NULL 73 Using where
+explain partitions update t3 set a = a + 1 where year(a) = 2020;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 p0 ALL a NULL NULL NULL 73 Using where; Using buffer
+drop tables t1,t2,t3;
diff --git a/mysql-test/main/sargable_date_cond.test b/mysql-test/main/sargable_date_cond.test
index 3f1622c590b..e1fa08177d8 100644
--- a/mysql-test/main/sargable_date_cond.test
+++ b/mysql-test/main/sargable_date_cond.test
@@ -1,3 +1,6 @@
+--source include/have_partition.inc
+--source include/have_sequence.inc
+
#
# MDEV-8320: Allow index usage for DATE(datetime_column) = const
#
@@ -27,6 +30,7 @@ analyze table t2;
--echo #
let $q= select count(*) from t2 where year(a) < 2018;
eval $q;
+--echo # Compare the results, they must be equal:
select count(*) from t2 where a < '2018-01-01';
eval explain format=json $q;
--echo # Check rewrite for a prepared statement:
@@ -50,78 +54,21 @@ let $q= select count(*) from t2 where year(a) <= 2018;
eval $q;
select count(*) from t2 where a < '2019-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where year(a) <= ?"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where year(a) <= ?";
-execute stmt using 2018;
-execute stmt using 2017;
-
let $q= select count(*) from t2 where year(a) > 2018;
eval $q;
select count(*) from t2 where a > '2018-12-31 23:59:59.999999';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where year(a) > ?"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where year(a) > ?";
-execute stmt using 2018;
-execute stmt using 2017;
let $q= select count(*) from t2 where year(a) >= 2018;
eval $q;
select count(*) from t2 where a >= '2018-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where year(a) >= ?"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where year(a) >= ?";
-execute stmt using 2018;
-execute stmt using 2019;
let $q= select count(*) from t2 where year(a) = 2017;
eval $q;
select count(*) from t2 where a >= '2017-01-01' and a < '2018-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where year(a) = ?"
- using 2017;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where year(a) = ?";
-execute stmt using 2017;
-execute stmt using 2019;
--echo #
--echo # "YEAR(datetime_col) CMP year_value", reverse argument order
@@ -130,94 +77,24 @@ let $q= select count(*) from t2 where 2017 < year(a);
eval $q;
select count(*) from t2 where a >= '2018-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? < year(a)"
- using 2017;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? < year(a)";
-execute stmt using 2017;
-execute stmt using 2018;
let $q= select count(*) from t2 where 2018 <= year(a);
select count(*) from t2 where a >= '2018-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? <= year(a)"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? <= year(a)";
-execute stmt using 2018;
-execute stmt using 2019;
let $q= select count(*) from t2 where 2018 > year(a);
eval $q;
select count(*) from t2 where a < '2018-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? > year(a)"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? > year(a)";
-execute stmt using 2018;
-execute stmt using 2019;
let $q= select count(*) from t2 where 2018 >= year(a);
select count(*) from t2 where a < '2019-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? >= year(a)"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? >= year(a)";
-execute stmt using 2018;
-execute stmt using 2019;
let $q= select count(*) from t2 where 2018 = year(a);
eval $q;
select count(*) from t2 where a >= '2018-01-01' and a < '2019-01-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? = year(a)"
- using 2018;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? = year(a)";
-execute stmt using 2018;
-execute stmt using 2019;
--echo #
--echo # "DATE(datetime_col) CMP date_value", basic checks
@@ -226,96 +103,26 @@ let $q= select count(*) from t2 where date(a) < '2017-06-01';
eval $q;
select count(*) from t2 where a < '2017-06-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where date(a) < ?"
- using '2017-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(a) < ?";
-execute stmt using '2017-06-01';
-execute stmt using '2017-06-05';
let $q= select count(*) from t2 where date(a) <= '2017-06-03';
eval $q;
select count(*) from t2 where a < '2017-06-04';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where date(a) <= ?"
- using '2017-06-04';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(a) <= ?";
-execute stmt using '2017-06-03';
-execute stmt using '2017-06-10';
let $q= select count(*) from t2 where date(a) > '2018-06-01';
eval $q;
select count(*) from t2 where a >= '2018-06-02';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where date(a) > ?"
- using '2018-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(a) > ?";
-execute stmt using '2018-06-01';
-execute stmt using '2018-06-05';
let $q= select count(*) from t2 where date(a) >= '2018-06-01';
eval $q;
select count(*) from t2 where a >= '2018-06-01';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where date(a) >= ?"
- using '2018-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(a) >= ?";
-execute stmt using '2018-06-01';
-execute stmt using '2018-06-10';
let $q= select count(*) from t2 where date(a) = '2017-06-02';
eval $q;
select count(*) from t2 where a >= '2017-06-02' and a < '2017-06-03';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where date(a) = ?"
- using '2017-06-02';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(a) = ?";
-execute stmt using '2017-06-02';
-execute stmt using '2017-06-05';
--echo #
--echo # "DATE(datetime_col) CMP date_value", reverse order
@@ -324,96 +131,26 @@ let $q= select count(*) from t2 where '2017-06-01' > date(a);
eval $q;
select count(*) from t2 where '2017-06-01' > a;
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? > date(a)"
- using '2017-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? > date(a)";
-execute stmt using '2017-06-01';
-execute stmt using '2017-06-05';
let $q= select count(*) from t2 where '2017-06-03' >= date(a);
eval $q;
select count(*) from t2 where '2017-06-03' >= a;
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? >= date(a)"
- using '2017-06-03';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? >= date(a)";
-execute stmt using '2017-06-03';
-execute stmt using '2017-06-12';
let $q= select count(*) from t2 where '2018-06-01' < date(a);
eval $q;
select count(*) from t2 where '2018-06-02' <= a;
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? < date(a)"
- using '2017-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? < date(a)";
-execute stmt using '2018-06-02';
-execute stmt using '2018-06-15';
let $q= select count(*) from t2 where '2018-06-01' <= date(a);
eval $q;
select count(*) from t2 where '2018-06-01' <= a;
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? <= date(a)"
- using '2017-06-01';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? <= date(a)";
-execute stmt using '2018-06-01';
-execute stmt using '2018-06-15';
let $q= select count(*) from t2 where '2017-06-02' = date(a);
eval $q;
select count(*) from t2 where a >= '2017-06-02' and a < '2017-06-03';
eval explain format=json $q;
-execute immediate
- "explain format=json select * from t2 where ? = date(a)"
- using '2017-06-02';
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where ? = date(a)";
-execute stmt using '2017-06-03';
-execute stmt using '2017-06-10';
--echo # Check rewrite of a more complicated query
explain format=json select * from t2 as t21 force index(a),
@@ -439,33 +176,11 @@ let $q= select count(*) from t2 where date(b)< '2017-06-03';
eval $q;
select count(*) from t2 where b < '2017-06-03';
eval explain format=json $q;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(b) < ?";
-execute stmt using '2017-06-03';
-execute stmt using '2017-06-10';
let $q= select count(*) from t2 where date(b)= '2017-06-04';
eval $q;
select count(*) from t2 where b >= '2017-06-04' and b < '2017-06-05';
eval explain format=json $q;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
-prepare stmt from "select count(*) from t2 where date(b) = ?";
-execute stmt using '2017-06-04';
-execute stmt using '2017-06-10';
--echo #
--echo # Check actual query results
@@ -490,8 +205,8 @@ select * from t2 force index(a) where date(a)='2006-12-31';
--echo # Test the TIMESTAMP column
--echo #
create table t3 (a timestamp, b date, key(a));
-# Insert data starting from 2016 since that year had a leap second
-# (https://en.wikipedia.org/wiki/Leap_second)
+--echo # Insert data starting from 2016 since that year had a leap second
+--echo # (https://en.wikipedia.org/wiki/Leap_second)
set time_zone="UTC"; # To make sure we avoid daylight saving time shifts
insert into t3
select
@@ -507,22 +222,6 @@ select count(*) from t3 force index(a) where a >= '2016-01-01 00:00:00'
and a <= '2016-12-31 23:59:59.999999';
explain format=json
select count(*) from t3 force index(a) where year(a)= 2016;
---echo # Check rewrite for a prepared statement:
-execute immediate
- "explain format=json select * from t3 force index(a) where year(a) < ?"
- using 2017;
-eval prepare stmt from "$q";
-execute stmt;
-execute stmt;
-eval create or replace view v1 as $q;
-select * from v1;
-eval create or replace procedure sp() $q;
-call sp();
-call sp();
---echo # Prepared statement with a placeholder
-prepare stmt from "select count(*) from t3 where year(a) < ?";
-execute stmt using 2017;
-execute stmt using 2018;
set time_zone= @@global.time_zone;
--echo #
@@ -578,3 +277,87 @@ explain format=json select * from t6 where date(a) = '2009-12-01';
drop table t0,t1,t2,t3,t4,t5,t6;
drop view v1;
drop procedure sp;
+
+--echo #
+--echo # MDEV-30946 Index usage for DATE(datetime_column) = const
+--echo # does not work for DELETE and UPDATE
+--echo #
+create table t1 (pk int primary key, a datetime, c int, key(a));
+
+insert into t1 (pk,a,c) values (1,'2009-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (2,'2009-11-29 03:23:32', 2);
+insert into t1 (pk,a,c) values (3,'2009-10-16 05:56:32', 2);
+insert into t1 (pk,a,c) values (4,'2010-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (5,'2010-10-16 05:56:32', 2);
+insert into t1 (pk,a,c) values (6,'2011-11-29 13:43:32', 2);
+insert into t1 (pk,a,c) values (7,'2012-10-16 05:56:32', 2);
+
+--echo # YEAR() conditions, UPDATE
+explain format=json update t1 set c = 0 where year(a) = 2010;
+update t1 set c = 0 where year(a) = 2010;
+select * from t1;
+explain format=json update t1 set c = 1
+ where c < (select count(*) from t1 where year(a) = 2010);
+explain format=json update t1 set c = 0
+ where year(a) = 2010 and c < (select count(*) from t1 where year(a) = 2010);
+
+--echo # Multi-table update
+create table t2 (a int);
+insert into t2 values (4),(5),(6);
+explain format=json update t1, t2 set c = 0
+ where year(t1.a) = 2010 and t1.c = t2.a;
+
+prepare stmt from "update t1 set c = 0 where year(a) = 2010";
+execute stmt;
+execute stmt;
+
+--echo # YEAR() conditions, DELETE
+explain format=json delete from t1 where year(a) = 2010;
+delete from t1 where year(a) = 2010;
+select * from t1;
+explain format=json delete from t1
+ where c < (select count(*) from t1 where year(a) = 2010);
+delete from t1 where c < (select count(*) from t1 where year(a) = 2010);
+
+prepare stmt from "delete from t1 where year(a) = 2009";
+execute stmt;
+execute stmt;
+select * from t1;
+
+--echo # DATE() conditions, UPDATE
+explain format=json update t1 set c = 0 where date(a) = '2010-10-16';
+explain format=json update t1 set c = 0 where date(a) <= '2011-10-16';
+prepare stmt from "update t1 set c = 3 where date(a) = '2011-11-29'";
+execute stmt;
+execute stmt;
+select * from t1;
+
+--echo # DATE() conditions, DELETE
+explain format=json delete from t1 where date(a) = '2010-10-16';
+explain format=json delete from t1 where date(a) <= '2011-10-16';
+prepare stmt from "delete from t1 where date(a) <= '2012-01-01'";
+execute stmt;
+execute stmt;
+select * from t1;
+
+--echo # Test partition pruning
+create table t3 (
+ a datetime,
+ key(a)
+) partition by range(year(a)) (
+partition p0 values less than (2022),
+partition p1 values less than (MAXVALUE)
+);
+
+insert into t3
+select date_add('2020-01-01', interval seq*10 day)
+from seq_1_to_100;
+
+--echo # Must be only "p0" partition
+explain partitions select * from t3 where year(a) = 2020;
+
+explain partitions delete from t3 where year(a) = 2020;
+
+explain partitions update t3 set a = a + 1 where year(a) = 2020;
+
+drop tables t1,t2,t3;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 93ec11ca063..dcf61e9b085 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -464,6 +464,12 @@ bool Sql_cmd_delete::delete_from_single_table(THD *thd)
goto produce_explain_and_leave;
}
}
+ if (conds && thd->lex->are_date_funcs_used())
+ {
+ /* Rewrite datetime comparison conditions into sargable */
+ conds= conds->top_level_transform(thd, &Item::date_conds_transformer,
+ (uchar *) 0);
+ }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (prune_partitions(thd, table, conds))
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index ff1d70e7f8e..2be2a85b889 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -433,6 +433,12 @@ bool Sql_cmd_update::update_single_table(THD *thd)
goto produce_explain_and_leave;
}
}
+ if (conds && thd->lex->are_date_funcs_used())
+ {
+ /* Rewrite datetime comparison conditions into sargable */
+ conds= conds->top_level_transform(thd, &Item::date_conds_transformer,
+ (uchar *) 0);
+ }
// Don't count on usage of 'only index' when calculating which key to use
table->covering_keys.clear_all();