diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index 177f0950a77..aecfb35d284 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -318,7 +318,7 @@ a3 char(3), a4 real, a5 date, key k1(a2,a3), -key k2(a4 desc,a1), +key k2(a4 /*desc*/,a1), key k3(a5,a1) ); create table t2( diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index 2d26861c710..8ff3689f452 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -206,7 +206,7 @@ create table t1( a4 real, a5 date, key k1(a2,a3), - key k2(a4 desc,a1), + key k2(a4 /*desc*/,a1), key k3(a5,a1) ); create table t2( diff --git a/mysql-test/main/key.result b/mysql-test/main/key.result index 5d84068d8af..ff35288a6ea 100644 --- a/mysql-test/main/key.result +++ b/mysql-test/main/key.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; SET SQL_WARNINGS=1; CREATE TABLE t1 ( ID CHAR(32) NOT NULL, @@ -685,3 +684,8 @@ c c 9 10 10 11 drop table t1,t2; +# +# MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +# +create table t1 (a int, b int, key(a), key(a desc)); +drop table t1; diff --git a/mysql-test/main/key.test b/mysql-test/main/key.test index 4e3e02c8add..c95fc017a43 100644 --- a/mysql-test/main/key.test +++ b/mysql-test/main/key.test @@ -1,6 +1,3 @@ ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings --source include/have_sequence.inc SET SQL_WARNINGS=1; @@ -603,3 +600,9 @@ EXPLAIN SELECT t1.c, t2.c FROM t1, t2 WHERE t1.b=t2.a and t1.c=t2.b; SELECT t1.c, t2.c FROM t1, t2 WHERE t1.b=t2.a and t1.c=t2.b; drop table t1,t2; + +--echo # +--echo # MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +--echo # +create table t1 (a int, b int, key(a), key(a desc)); +drop table t1; diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 0d16f47dc8f..b1942a85475 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -1201,8 +1201,8 @@ EXPLAIN SELECT DISTINCT a FROM t1 { }, { "index": "a", - "usable": true, - "key_parts": ["a"] + "key_parts": ["a"], + "usable": true } ], "best_covering_index_scan": { @@ -1384,8 +1384,8 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a { "potential_range_indexes": [ { "index": "a", - "usable": true, - "key_parts": ["a", "b", "c", "d"] + "key_parts": ["a", "b", "c", "d"], + "usable": true } ], "best_covering_index_scan": { @@ -1583,8 +1583,8 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { "potential_range_indexes": [ { "index": "id", - "usable": true, - "key_parts": ["id", "a"] + "key_parts": ["id", "a"], + "usable": true } ], "best_covering_index_scan": { @@ -1771,8 +1771,8 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id { "potential_range_indexes": [ { "index": "id", - "usable": true, - "key_parts": ["id", "a"] + "key_parts": ["id", "a"], + "usable": true } ], "best_covering_index_scan": { @@ -2010,13 +2010,13 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { }, { "index": "a_c", - "usable": true, - "key_parts": ["a", "c"] + "key_parts": ["a", "c"], + "usable": true }, { "index": "a_b", - "usable": true, - "key_parts": ["a", "b"] + "key_parts": ["a", "b"], + "usable": true } ], "setup_range_conditions": [], @@ -2213,8 +2213,8 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 { }, { "index": "a_c", - "usable": true, - "key_parts": ["a", "c"] + "key_parts": ["a", "c"], + "usable": true }, { "index": "a_b", @@ -3233,18 +3233,18 @@ explain select * from t1 where pk = 2 and a=5 and b=1 { "potential_range_indexes": [ { "index": "pk", - "usable": true, - "key_parts": ["pk"] + "key_parts": ["pk"], + "usable": true }, { "index": "pk_a", - "usable": true, - "key_parts": ["pk", "a"] + "key_parts": ["pk", "a"], + "usable": true }, { "index": "pk_a_b", - "usable": true, - "key_parts": ["pk", "a", "b"] + "key_parts": ["pk", "a", "b"], + "usable": true } ], "best_covering_index_scan": { @@ -3751,8 +3751,8 @@ explain delete from t0 where t0.a<3 { "potential_range_indexes": [ { "index": "a", - "usable": true, - "key_parts": ["a"] + "key_parts": ["a"], + "usable": true } ], "setup_range_conditions": [], @@ -3889,8 +3889,8 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "potential_range_indexes": [ { "index": "a", - "usable": true, - "key_parts": ["a"] + "key_parts": ["a"], + "usable": true } ], "best_covering_index_scan": { @@ -3954,8 +3954,8 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 { "potential_range_indexes": [ { "index": "a", - "usable": true, - "key_parts": ["a"] + "key_parts": ["a"], + "usable": true } ], "best_covering_index_scan": { diff --git a/mysql-test/main/opt_trace_index_merge.result b/mysql-test/main/opt_trace_index_merge.result index f1e13586eda..011875762d1 100644 --- a/mysql-test/main/opt_trace_index_merge.result +++ b/mysql-test/main/opt_trace_index_merge.result @@ -78,13 +78,13 @@ explain select * from t1 where a=1 or b=1 { "potential_range_indexes": [ { "index": "a", - "usable": true, - "key_parts": ["a"] + "key_parts": ["a"], + "usable": true }, { "index": "b", - "usable": true, - "key_parts": ["b"] + "key_parts": ["b"], + "usable": true }, { "index": "c", diff --git a/mysql-test/main/opt_trace_index_merge_innodb.result b/mysql-test/main/opt_trace_index_merge_innodb.result index 0ddaaeae89d..d372be85bd8 100644 --- a/mysql-test/main/opt_trace_index_merge_innodb.result +++ b/mysql-test/main/opt_trace_index_merge_innodb.result @@ -93,13 +93,13 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { "potential_range_indexes": [ { "index": "PRIMARY", - "usable": true, - "key_parts": ["pk1", "pk2"] + "key_parts": ["pk1", "pk2"], + "usable": true }, { "index": "key1", - "usable": true, - "key_parts": ["key1"] + "key_parts": ["key1"], + "usable": true }, { "index": "key2", diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 81f173e764d..17234eecc58 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -1,5 +1,4 @@ call mtr.add_suppression("Sort aborted.*"); -drop table if exists t1,t2,t3; call mtr.add_suppression("Out of sort memory; increase server sort buffer size"); CREATE TABLE t1 ( id int(6) DEFAULT '0' NOT NULL, @@ -4487,3 +4486,38 @@ a group_concat(t1.b) 58 1 DROP TABLE t1, t2; # End of 10.6 tests +# +# MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +# +create table t1 (a int, b int, c int, key r (a desc, b asc)); +insert t1 select seq % 10, seq div 10, seq from seq_1_to_55; +insert t1 values (NULL, NULL, NULL), (9, NULL, NULL); +explain select * from t1 force index(r) order by a,b limit 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 57 Using filesort +explain select * from t1 force index(r) order by a desc,b limit 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL r 10 NULL 20 +select * from t1 force index(r) order by a desc,b limit 20; +a b c +9 NULL NULL +9 0 9 +9 1 19 +9 2 29 +9 3 39 +9 4 49 +8 0 8 +8 1 18 +8 2 28 +8 3 38 +8 4 48 +7 0 7 +7 1 17 +7 2 27 +7 3 37 +7 4 47 +6 0 6 +6 1 16 +6 2 26 +6 3 36 +drop table t1; diff --git a/mysql-test/main/order_by.test b/mysql-test/main/order_by.test index 9ad0af1d21f..6944a282e4c 100644 --- a/mysql-test/main/order_by.test +++ b/mysql-test/main/order_by.test @@ -3,11 +3,6 @@ # call mtr.add_suppression("Sort aborted.*"); - ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - call mtr.add_suppression("Out of sort memory; increase server sort buffer size"); --source include/have_sequence.inc @@ -15,8 +10,6 @@ call mtr.add_suppression("Out of sort memory; increase server sort buffer size") # Test old ORDER BY bug # ---source include/have_sequence.inc - CREATE TABLE t1 ( id int(6) DEFAULT '0' NOT NULL, idservice int(5), @@ -2649,3 +2642,14 @@ eval $query; DROP TABLE t1, t2; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +--echo # +create table t1 (a int, b int, c int, key r (a desc, b asc)); +insert t1 select seq % 10, seq div 10, seq from seq_1_to_55; +insert t1 values (NULL, NULL, NULL), (9, NULL, NULL); +explain select * from t1 force index(r) order by a,b limit 20; +explain select * from t1 force index(r) order by a desc,b limit 20; + select * from t1 force index(r) order by a desc,b limit 20; +drop table t1; diff --git a/mysql-test/main/order_by_innodb.result b/mysql-test/main/order_by_innodb.result index 28922ef65f2..2038dd479d2 100644 --- a/mysql-test/main/order_by_innodb.result +++ b/mysql-test/main/order_by_innodb.result @@ -220,6 +220,41 @@ dd.d1, dd.d2, dd.id limit 1 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index 1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where -2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where +2 DEPENDENT SUBQUERY dd index id2,for_latest_sort for_latest_sort 14 NULL # Using where drop table t1,t2; # End of 10.2 tests +# +# MDEV-26938 Support descending indexes internally in InnoDB +# +create table t1 (a int, b int, c int, key r (a desc, b asc)); +insert t1 select seq % 10, seq div 10, seq from seq_1_to_55; +insert t1 values (NULL, NULL, NULL), (9, NULL, NULL); +explain select * from t1 force index(r) order by a,b limit 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 57 Using filesort +explain select * from t1 force index(r) order by a desc,b limit 20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL r 10 NULL 20 +select * from t1 force index(r) order by a desc,b limit 20; +a b c +9 NULL NULL +9 0 9 +9 1 19 +9 2 29 +9 3 39 +9 4 49 +8 0 8 +8 1 18 +8 2 28 +8 3 38 +8 4 48 +7 0 7 +7 1 17 +7 2 27 +7 3 37 +7 4 47 +6 0 6 +6 1 16 +6 2 26 +6 3 36 +drop table t1; diff --git a/mysql-test/main/order_by_innodb.test b/mysql-test/main/order_by_innodb.test index af12644c073..36b2374ba54 100644 --- a/mysql-test/main/order_by_innodb.test +++ b/mysql-test/main/order_by_innodb.test @@ -1,7 +1,8 @@ # # ORDER BY handling (e.g. filesort) tests that require innodb # --- source include/have_innodb.inc +--source include/have_innodb.inc +--source include/have_sequence.inc --disable_warnings drop table if exists t0,t1,t2,t3; @@ -209,3 +210,14 @@ from drop table t1,t2; --echo # End of 10.2 tests + +--echo # +--echo # MDEV-26938 Support descending indexes internally in InnoDB +--echo # +create table t1 (a int, b int, c int, key r (a desc, b asc)); +insert t1 select seq % 10, seq div 10, seq from seq_1_to_55; +insert t1 values (NULL, NULL, NULL), (9, NULL, NULL); +explain select * from t1 force index(r) order by a,b limit 20; +explain select * from t1 force index(r) order by a desc,b limit 20; + select * from t1 force index(r) order by a desc,b limit 20; +drop table t1; diff --git a/mysql-test/main/partition_order.result b/mysql-test/main/partition_order.result index cecfc90eefb..d4a0c133d10 100644 --- a/mysql-test/main/partition_order.result +++ b/mysql-test/main/partition_order.result @@ -1,4 +1,3 @@ -drop table if exists t1; CREATE TABLE t1 ( a int not null, b int not null, @@ -783,3 +782,17 @@ a b c 1 1 1 1 NULL NULL drop table t1; +# +# MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +# +create table t1 (a int, b int, key(a desc)) partition by hash(a) partitions 4; +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6); +explain select * from t1 order by a limit 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 3 +select * from t1 order by a limit 3; +a b +1 1 +2 2 +3 3 +drop table t1; diff --git a/mysql-test/main/partition_order.test b/mysql-test/main/partition_order.test index ad956361d00..f5cd4c25074 100644 --- a/mysql-test/main/partition_order.test +++ b/mysql-test/main/partition_order.test @@ -1,14 +1,9 @@ -#--disable_abort_on_error # # Simple test for the partition storage engine # Focuses on tests of ordered index read # -- source include/have_partition.inc ---disable_warnings -drop table if exists t1; ---enable_warnings - # # Ordered index read, int type # @@ -842,3 +837,12 @@ INSERT into t1 values (1, NULL, NULL), (2, NULL, '10'); select * from t1 where a = 1 order by a desc, b desc; select * from t1 where a = 1 order by b desc; drop table t1; + +--echo # +--echo # MDEV-13756 Implement descending index: KEY (a DESC, b ASC) +--echo # +create table t1 (a int, b int, key(a desc)) partition by hash(a) partitions 4; +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6); +explain select * from t1 order by a limit 3; +select * from t1 order by a limit 3; +drop table t1; diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index e6fa9756b1d..52d0be675e2 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -575,7 +575,7 @@ a 2010-02-01 09:31:02 2010-02-01 09:31:03 2010-02-01 09:31:04 -CREATE TABLE t2 ( a TIMESTAMP, KEY ( a DESC ) ); +CREATE TABLE t2 ( a TIMESTAMP, KEY ( a ) ); INSERT INTO t2 VALUES( '2010-02-01 09:31:01' ); INSERT INTO t2 VALUES( '2010-02-01 09:31:02' ); INSERT INTO t2 VALUES( '2010-02-01 09:31:03' ); diff --git a/mysql-test/main/type_timestamp.test b/mysql-test/main/type_timestamp.test index 9c5b57b8885..80bc0bd0332 100644 --- a/mysql-test/main/type_timestamp.test +++ b/mysql-test/main/type_timestamp.test @@ -386,7 +386,7 @@ EXPLAIN SELECT * FROM t1 WHERE a >= '2010-02-01 09:31:02.0'; SELECT * FROM t1 WHERE a >= '2010-02-01 09:31:02.0'; -CREATE TABLE t2 ( a TIMESTAMP, KEY ( a DESC ) ); +CREATE TABLE t2 ( a TIMESTAMP, KEY ( a ) ); INSERT INTO t2 VALUES( '2010-02-01 09:31:01' ); INSERT INTO t2 VALUES( '2010-02-01 09:31:02' ); diff --git a/mysql-test/suite/innodb/r/autoinc_persist,desc.rdiff b/mysql-test/suite/innodb/r/autoinc_persist,desc.rdiff index eeef34e071d..c732d2c1a1a 100644 --- a/mysql-test/suite/innodb/r/autoinc_persist,desc.rdiff +++ b/mysql-test/suite/innodb/r/autoinc_persist,desc.rdiff @@ -1,4 +1,4 @@ -@@ -13,7 +13,7 @@ +@@ -13,212 +13,212 @@ # # Pre-create several tables SET SQL_MODE='STRICT_ALL_TABLES'; @@ -7,106 +7,347 @@ INSERT INTO t1 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31); SELECT * FROM t1; -@@ -28,7 +28,7 @@ - 20 - 30 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 31 -CREATE TABLE t2(a TINYINT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB; ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t2(a TINYINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t2 VALUES(-5); ERROR 22003: Out of range value for column 'a' at row 1 INSERT INTO t2 VALUES(0), (0), (0), (0), (8), (10), (0), -@@ -45,7 +45,7 @@ - 20 - 30 + (20), (30), (31); + SELECT * FROM t2; + a +-1 +-2 +-3 +-4 +-8 +-10 +-11 +-20 +-30 31 -CREATE TABLE t3(a SMALLINT AUTO_INCREMENT KEY) ENGINE = InnoDB; ++30 ++20 ++11 ++10 ++8 ++4 ++3 ++2 ++1 +CREATE TABLE t3(a SMALLINT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t3 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31), (1024), (4096); SELECT * FROM t3; -@@ -62,7 +62,7 @@ - 31 - 1024 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 +-31 +-1024 4096 -CREATE TABLE t4(a SMALLINT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB; ++1024 ++31 ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t4(a SMALLINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t4 VALUES(-5); ERROR 22003: Out of range value for column 'a' at row 1 INSERT INTO t4 VALUES(0), (0), (0), (0), (8), (10), (0), -@@ -81,7 +81,7 @@ - 31 - 1024 + (20), (30), (31), (1024), (4096); + SELECT * FROM t4; + a +-1 +-2 +-3 +-4 +-8 +-10 +-11 +-20 +-30 +-31 +-1024 4096 -CREATE TABLE t5(a MEDIUMINT AUTO_INCREMENT KEY) ENGINE = InnoDB; ++1024 ++31 ++30 ++20 ++11 ++10 ++8 ++4 ++3 ++2 ++1 +CREATE TABLE t5(a MEDIUMINT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t5 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31), (1000000), (1000005); SELECT * FROM t5; -@@ -98,7 +98,7 @@ - 31 - 1000000 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 +-31 +-1000000 1000005 -CREATE TABLE t6(a MEDIUMINT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB; ++1000000 ++31 ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t6(a MEDIUMINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t6 VALUES(-5); ERROR 22003: Out of range value for column 'a' at row 1 INSERT INTO t6 VALUES(0), (0), (0), (0), (8), (10), (0), -@@ -117,7 +117,7 @@ - 31 - 1000000 + (20), (30), (31), (1000000), (1000005); + SELECT * FROM t6; + a +-1 +-2 +-3 +-4 +-8 +-10 +-11 +-20 +-30 +-31 +-1000000 1000005 -CREATE TABLE t7(a INT AUTO_INCREMENT KEY) ENGINE = InnoDB; ++1000000 ++31 ++30 ++20 ++11 ++10 ++8 ++4 ++3 ++2 ++1 +CREATE TABLE t7(a INT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t7 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31), (100000000), (100000008); SELECT * FROM t7; -@@ -134,7 +134,7 @@ - 31 - 100000000 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 +-31 +-100000000 100000008 -CREATE TABLE t8(a INT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB; ++100000000 ++31 ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t8(a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t8 VALUES(-5); ERROR 22003: Out of range value for column 'a' at row 1 INSERT INTO t8 VALUES(0), (0), (0), (0), (8), (10), (0), -@@ -153,7 +153,7 @@ - 31 - 100000000 + (20), (30), (31), (100000000), (100000008); + SELECT * FROM t8; + a +-1 +-2 +-3 +-4 +-8 +-10 +-11 +-20 +-30 +-31 +-100000000 100000008 -CREATE TABLE t9(a BIGINT AUTO_INCREMENT KEY) ENGINE = InnoDB; ++100000000 ++31 ++30 ++20 ++11 ++10 ++8 ++4 ++3 ++2 ++1 +CREATE TABLE t9(a BIGINT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t9 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31), (100000000000), (100000000006); SELECT * FROM t9; -@@ -170,7 +170,7 @@ - 31 - 100000000000 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 +-31 +-100000000000 100000000006 -CREATE TABLE t10(a BIGINT UNSIGNED AUTO_INCREMENT KEY) ENGINE = InnoDB; ++100000000000 ++31 ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t10(a BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t10 VALUES(-5); ERROR 22003: Out of range value for column 'a' at row 1 INSERT INTO t10 VALUES(0), (0), (0), (0), (8), (10), (0), -@@ -189,7 +189,7 @@ - 31 - 100000000000 + (20), (30), (31), (100000000000), (100000000006); + SELECT * FROM t10; + a +-1 +-2 +-3 +-4 +-8 +-10 +-11 +-20 +-30 +-31 +-100000000000 100000000006 -CREATE TABLE t11(a FLOAT AUTO_INCREMENT KEY) ENGINE = InnoDB; ++100000000000 ++31 ++30 ++20 ++11 ++10 ++8 ++4 ++3 ++2 ++1 +CREATE TABLE t11(a FLOAT AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t11 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31); SELECT * FROM t11; -@@ -204,7 +204,7 @@ - 20 - 30 + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 31 -CREATE TABLE t12(a DOUBLE AUTO_INCREMENT KEY) ENGINE = InnoDB; ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 +CREATE TABLE t12(a DOUBLE AUTO_INCREMENT, PRIMARY KEY(a DESC)) ENGINE = InnoDB; INSERT INTO t12 VALUES(0), (0), (0), (0), (-1), (-10), (0), (20), (30), (31); SELECT * FROM t12; -@@ -242,7 +242,7 @@ + a +--10 +--1 +-1 +-2 +-3 +-4 +-5 +-20 +-30 + 31 ++30 ++20 ++5 ++4 ++3 ++2 ++1 ++-1 ++-10 + # Scenario 1: Normal restart, to test if the counters are persisted + # Scenario 2: Delete some values, to test the counters should not be the + # one which is the largest in current table +@@ -242,14 +242,14 @@ SELECT MAX(a) AS `Expect 100000000000` FROM t9; Expect 100000000000 100000000000 @@ -115,6 +356,333 @@ AUTO_INCREMENT = 1234; # restart SHOW CREATE TABLE t13; + Table Create Table + t13 CREATE TABLE `t13` ( + `a` int(11) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=1234 DEFAULT CHARSET=latin1 + INSERT INTO t13 VALUES(0); + SELECT a AS `Expect 1234` FROM t13; +@@ -464,28 +464,28 @@ + INSERT INTO t1 VALUES(0), (0); + SELECT * FROM t1; + a +-1 + 2 ++1 + INSERT INTO t3 VALUES(0), (0); + SELECT * FROM t3; + a +-1 + 2 ++1 + INSERT INTO t5 VALUES(0), (0); + SELECT * FROM t5; + a +-1 + 2 ++1 + INSERT INTO t7 VALUES(0), (0); + SELECT * FROM t7; + a +-1 + 2 ++1 + INSERT INTO t9 VALUES(0), (0); + SELECT * FROM t9; + a +-1 + 2 ++1 + # Ensure that all changes before the server is killed are persisted. + set global innodb_flush_log_at_trx_commit=1; + TRUNCATE TABLE t1; +@@ -498,63 +498,63 @@ + INSERT INTO t19 VALUES(0), (0); + SELECT * FROM t19; + a +-1 + 2 ++1 + # restart + INSERT INTO t1 VALUES(0), (0); + SELECT * FROM t1; + a +-1 + 2 ++1 + INSERT INTO t3 VALUES(0), (0); + SELECT * FROM t3; + a +-1 + 2 ++1 + INSERT INTO t5 VALUES(0), (0); + SELECT * FROM t5; + a +-1 + 2 ++1 + INSERT INTO t7 VALUES(0), (0); + SELECT * FROM t7; + a +-1 + 2 ++1 + INSERT INTO t19 VALUES(0), (0); + SELECT * FROM t19; + a +-1 +-2 +-3 + 4 ++3 ++2 ++1 + DELETE FROM t19 WHERE a = 4; + RENAME TABLE t19 to t9; + INSERT INTO t9 VALUES(0), (0); + SELECT * FROM t9; + a +-1 +-2 +-3 +-5 + 6 ++5 ++3 ++2 ++1 + TRUNCATE TABLE t9; + INSERT INTO t9 VALUES(0), (0); + SELECT * FROM t9; + a +-1 + 2 ++1 + # Scenario 8: Test ALTER TABLE operations + INSERT INTO t3 VALUES(0), (0), (100), (200), (1000); + SELECT * FROM t3; + a +-1 +-2 +-3 +-4 +-100 +-200 + 1000 ++200 ++100 ++4 ++3 ++2 ++1 + DELETE FROM t3 WHERE a > 300; + SELECT MAX(a) AS `Expect 200` FROM t3; + Expect 200 +@@ -566,7 +566,7 @@ + Table Create Table + t3 CREATE TABLE `t3` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=latin1 + INSERT INTO t3 VALUES(0); + SELECT MAX(a) AS `Expect 201` FROM t3; +@@ -579,7 +579,7 @@ + Table Create Table + t3 CREATE TABLE `t3` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=latin1 + INSERT INTO t3 VALUES(0); + SELECT MAX(a) AS `Expect 500` FROM t3; +@@ -591,13 +591,13 @@ + Table Create Table + t3 CREATE TABLE `t3` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=latin1 + INSERT INTO t3 VALUES(0), (0); + SELECT * FROM t3; + a +-100 + 101 ++100 + INSERT INTO t3 VALUES(150), (180); + UPDATE t3 SET a = 200 WHERE a = 150; + INSERT INTO t3 VALUES(220); +@@ -607,7 +607,7 @@ + Table Create Table + t3 CREATE TABLE `t3` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=221 DEFAULT CHARSET=latin1 + INSERT INTO t3 VALUES(0); + SELECT MAX(a) AS `Expect 221` FROM t3; +@@ -619,7 +619,7 @@ + Table Create Table + t3 CREATE TABLE `t3` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=latin1 + # MDEV-6076: Test adding an AUTO_INCREMENT COLUMN + CREATE TABLE mdev6076a (b INT) ENGINE=InnoDB; +@@ -669,18 +669,18 @@ + INSERT INTO t_inplace SELECT * FROM t3; + SELECT * FROM t_inplace; + a +-100 +-101 +-120 +-121 +-122 +-200 + 210 ++200 ++122 ++121 ++120 ++101 ++100 + SHOW CREATE TABLE t_inplace; + Table Create Table + t_inplace CREATE TABLE `t_inplace` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=211 DEFAULT CHARSET=latin1 + # This will keep the autoinc counter + ALTER TABLE t_inplace AUTO_INCREMENT = 250, ALGORITHM = INPLACE; +@@ -689,7 +689,7 @@ + Table Create Table + t_inplace CREATE TABLE `t_inplace` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 + # This should keep the autoinc counter as well + ALTER TABLE t_inplace ADD COLUMN b INT, ALGORITHM = INPLACE; +@@ -699,16 +699,16 @@ + t_inplace CREATE TABLE `t_inplace` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 + DELETE FROM t_inplace WHERE a > 150; + SELECT * FROM t_inplace; + a b +-100 NULL +-101 NULL +-120 NULL +-121 NULL + 122 NULL ++121 NULL ++120 NULL ++101 NULL ++100 NULL + # This should reset the autoinc counter to the one specified + # Since it's smaller than current one but bigger than existing + # biggest counter in the table +@@ -719,7 +719,7 @@ + t_inplace CREATE TABLE `t_inplace` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=180 DEFAULT CHARSET=latin1 + # This should reset the autoinc counter to the next value of + # current max counter in the table, since the specified value +@@ -730,7 +730,7 @@ + Table Create Table + t_inplace CREATE TABLE `t_inplace` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=123 DEFAULT CHARSET=latin1 + INSERT INTO t_inplace VALUES(0), (0); + SELECT MAX(a) AS `Expect 124` FROM t_inplace; +@@ -757,18 +757,18 @@ + INSERT INTO t_copy SELECT * FROM t3; + SELECT * FROM t_copy; + a +-100 +-101 +-120 +-121 +-122 +-200 + 210 ++200 ++122 ++121 ++120 ++101 ++100 + SHOW CREATE TABLE t_copy; + Table Create Table + t_copy CREATE TABLE `t_copy` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=211 DEFAULT CHARSET=latin1 + # This will keep the autoinc counter + ALTER TABLE t_copy AUTO_INCREMENT = 250, ALGORITHM = COPY; +@@ -777,7 +777,7 @@ + Table Create Table + t_copy CREATE TABLE `t_copy` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 + # This should keep the autoinc counter as well + ALTER TABLE t_copy ADD COLUMN b INT, ALGORITHM = COPY; +@@ -787,16 +787,16 @@ + t_copy CREATE TABLE `t_copy` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 + DELETE FROM t_copy WHERE a > 150; + SELECT * FROM t_copy; + a b +-100 NULL +-101 NULL +-120 NULL +-121 NULL + 122 NULL ++121 NULL ++120 NULL ++101 NULL ++100 NULL + # This should reset the autoinc counter to the one specified + # Since it's smaller than current one but bigger than existing + # biggest counter in the table +@@ -807,7 +807,7 @@ + t_copy CREATE TABLE `t_copy` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=180 DEFAULT CHARSET=latin1 + # This should reset the autoinc counter to the next value of + # current max counter in the table, since the specified value +@@ -818,7 +818,7 @@ + Table Create Table + t_copy CREATE TABLE `t_copy` ( + `a` smallint(6) NOT NULL AUTO_INCREMENT, +- PRIMARY KEY (`a`) ++ PRIMARY KEY (`a` DESC) + ) ENGINE=InnoDB AUTO_INCREMENT=123 DEFAULT CHARSET=latin1 + INSERT INTO t_copy VALUES(0), (0); + SELECT MAX(a) AS `Expect 124` FROM t_copy; @@ -842,7 +842,7 @@ 126 DROP TABLE t_copy, it_copy; @@ -124,7 +692,7 @@ set SQL_MODE = NO_AUTO_VALUE_ON_ZERO; INSERT INTO t30 VALUES(NULL, 1), (200, 2), (0, 3); INSERT INTO t30(b) VALUES(4), (5), (6), (7); -@@ -869,7 +869,7 @@ +@@ -869,20 +869,20 @@ set global innodb_flush_log_at_trx_commit=1; CREATE TABLE t31 (a INT) ENGINE = InnoDB; INSERT INTO t31 VALUES(1), (2); @@ -133,8 +701,17 @@ INSERT INTO t31 VALUES(3, 0), (4, NULL), (5, NULL); INSERT INTO t31 VALUES(6, 0); ERROR 23000: Duplicate entry '0' for key 'PRIMARY' -@@ -882,7 +882,7 @@ + SELECT * FROM t31; + a b +-3 0 +-1 1 +-2 2 +-4 3 5 4 ++4 3 ++2 2 ++1 1 ++3 0 SET SQL_MODE = 0; # Scenario 10: Rollback would not rollback the counter -CREATE TABLE t32 (a BIGINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; @@ -151,6 +728,26 @@ INSERT INTO t33 VALUES(1, NULL); INSERT INTO t33 VALUES(2, NULL); INSERT INTO t33 VALUES(2, NULL); +@@ -920,13 +920,13 @@ + INSERT INTO t31(a) VALUES(6), (0); + SELECT * FROM t31; + a b +-3 0 +-1 1 +-2 2 +-4 3 +-5 4 +-6 5 + 0 6 ++6 5 ++5 4 ++4 3 ++2 2 ++1 1 ++3 0 + DROP TABLE t31; + set SQL_MODE = NO_AUTO_VALUE_ON_ZERO; + DELETE FROM t30 WHERE a = 0; @@ -965,7 +965,7 @@ DROP TABLE t33; CREATE TABLE t33 ( @@ -160,3 +757,13 @@ ALTER TABLE t33 DISCARD TABLESPACE; restore: t33 .ibd and .cfg files ALTER TABLE t33 IMPORT TABLESPACE; +@@ -975,7 +975,7 @@ + 4 + SELECT * FROM t33; + a b +-10 1 +-2 2 + 3 4 ++2 2 ++10 1 + DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t30, t32, t33; diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index b0c0c26afd4..603d4a61a89 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -1969,7 +1969,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `id` int(11) NOT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `id` (`id`) + UNIQUE KEY `id` (`id` DESC) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; # diff --git a/mysql-test/suite/innodb_fts/r/create.result b/mysql-test/suite/innodb_fts/r/create.result index 7be9333e647..9d16bffb1ef 100644 --- a/mysql-test/suite/innodb_fts/r/create.result +++ b/mysql-test/suite/innodb_fts/r/create.result @@ -194,9 +194,20 @@ ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT in CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, UNIQUE KEY FTS_DOC_ID_INDEX(FTS_DOC_ID DESC), FULLTEXT(b)) ENGINE=InnoDB; -DROP TABLE t1; +ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, UNIQUE KEY FTS_DOC_ID_INDEX(FTS_DOC_ID DESC)) ENGINE=InnoDB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` text DEFAULT NULL, + `FTS_DOC_ID` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`a`), + UNIQUE KEY `FTS_DOC_ID_INDEX` (`FTS_DOC_ID` DESC) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; +ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; +ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/create.test b/mysql-test/suite/innodb_fts/t/create.test index 6f5da11a66c..edecef64589 100644 --- a/mysql-test/suite/innodb_fts/t/create.test +++ b/mysql-test/suite/innodb_fts/t/create.test @@ -122,17 +122,16 @@ engine=innodb; --echo # MDEV-26938 Support descending indexes internally in InnoDB --echo # -# Unfortunately, the HA_REVERSE_SORT flag is not being stored in the .frm file. -#FIXME: --error ER_INNODB_FT_WRONG_DOCID_INDEX +--error ER_INNODB_FT_WRONG_DOCID_INDEX CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, UNIQUE KEY FTS_DOC_ID_INDEX(FTS_DOC_ID DESC), FULLTEXT(b)) ENGINE=InnoDB; -DROP TABLE t1; CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, UNIQUE KEY FTS_DOC_ID_INDEX(FTS_DOC_ID DESC)) ENGINE=InnoDB; -#FIXME: --error ER_INNODB_FT_WRONG_DOCID_INDEX +SHOW CREATE TABLE t1; +--error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; -#FIXME: --error ER_INNODB_FT_WRONG_DOCID_INDEX +--error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; DROP TABLE t1; diff --git a/mysql-test/suite/innodb_gis/r/geometry.result b/mysql-test/suite/innodb_gis/r/geometry.result index 437ff23e334..1f5a8aba00c 100644 --- a/mysql-test/suite/innodb_gis/r/geometry.result +++ b/mysql-test/suite/innodb_gis/r/geometry.result @@ -342,7 +342,7 @@ tab CREATE TABLE `tab` ( `c7` geometrycollection DEFAULT NULL, `c8` geometry DEFAULT NULL, UNIQUE KEY `idx2` (`c8`(5)), - KEY `idx1` (`c2`(5)) USING BTREE, + KEY `idx1` (`c2`(5) DESC) USING BTREE, KEY `idx3` (`c3`(5)) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 #check the data after modify @@ -778,7 +778,7 @@ tab3 CREATE TABLE `tab3` ( `c7` geometrycollection DEFAULT NULL, `c8` geometry DEFAULT NULL, UNIQUE KEY `idx2` (`c8`(5)), - KEY `idx1` (`c2`(5)) USING BTREE, + KEY `idx1` (`c2`(5) DESC) USING BTREE, KEY `idx3` (`c3`(5)) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=16 #check index with WKB function diff --git a/sql/key.cc b/sql/key.cc index f2cebfe6d82..bda028a5ab7 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. - Copyright (c) 2018, 2020, MariaDB + Copyright (c) 2018, 2021, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -573,6 +573,9 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec) /* loop over every key part */ do { + const int GREATER= key_part->key_part_flag & HA_REVERSE_SORT ? -1 : +1; + const int LESS= -GREATER; + field= key_part->field; if (key_part->null_bit) @@ -593,12 +596,12 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec) ; /* Fall through, no NULL fields */ else { - DBUG_RETURN(+1); + DBUG_RETURN(GREATER); } } else if (!sec_is_null) { - DBUG_RETURN(-1); + DBUG_RETURN(LESS); } else goto next_loop; /* Both were NULL */ @@ -612,7 +615,7 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec) */ if ((result= field->cmp_prefix(field->ptr+first_diff, field->ptr+sec_diff, key_part->length))) - DBUG_RETURN(result); + DBUG_RETURN(result * GREATER); next_loop: key_part++; key_part_num++; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 37cf054dfb0..1fbaec31636 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2020, MariaDB + Copyright (c) 2008, 2021, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2805,11 +2805,11 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, continue; // ToDo: ft-keys in non-ft ranges, if possible SerG } - trace_idx_details.add("usable", true); param.key[param.keys]=key_parts; key_part_info= key_info->key_part; uint cur_key_len= 0; Json_writer_array trace_keypart(thd, "key_parts"); + bool unusable_has_desc_keyparts= false; for (uint part= 0 ; part < n_key_parts ; part++, key_parts++, key_part_info++) { @@ -2824,8 +2824,17 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW; /* Only HA_PART_KEY_SEG is used */ key_parts->flag= (uint8) key_part_info->key_part_flag; + if (key_part_info->key_part_flag & HA_REVERSE_SORT) + unusable_has_desc_keyparts= true; trace_keypart.add(key_parts->field->field_name); } + trace_keypart.end(); + trace_idx_details.add("usable", !unusable_has_desc_keyparts); + if (unusable_has_desc_keyparts) // TODO MDEV-13756 + { + key_parts= param.key[param.keys]; + continue; + } param.real_keynr[param.keys++]=idx; if (cur_key_len > max_key_len) max_key_len= cur_key_len; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index b3871254e6e..10491d9b45b 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008, 2017, MariaDB Corporation. + Copyright (c) 2008, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -953,6 +953,9 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, part->length < part_field->key_length()) break; + if (part->key_part_flag & HA_REVERSE_SORT) + break; // TODO MDEV-27576 + if (field->eq(part->field)) { ref->key= idx; diff --git a/sql/sql_class.h b/sql/sql_class.h index df9d89b5aff..f998b21856b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -290,9 +290,9 @@ class Key_part_spec :public Sql_alloc { public: LEX_CSTRING field_name; uint length; - bool generated; + bool generated, asc; Key_part_spec(const LEX_CSTRING *name, uint len, bool gen= false) - : field_name(*name), length(len), generated(gen) + : field_name(*name), length(len), generated(gen), asc(1) {} bool operator==(const Key_part_spec& other) const; /** diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d01f84fe7d1..877bfada417 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2369,6 +2369,8 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list, packet->append_parenthesized((long) key_part->length / key_part->field->charset()->mbmaxlen); } + if (key_part->key_part_flag & HA_REVERSE_SORT) + packet->append(STRING_WITH_LEN(" DESC")); } if (key_info->without_overlaps) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f7d8128b396..03f46bdc5ea 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2281,7 +2281,7 @@ void promote_first_timestamp_column(List *column_definitions) static bool key_cmp(const Key_part_spec &a, const Key_part_spec &b) { - return a.length == b.length && + return a.length == b.length && a.asc == b.asc && !lex_string_cmp(system_charset_info, &a.field_name, &b.field_name); } @@ -3328,6 +3328,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_part_info->fieldnr= field; key_part_info->offset= (uint16) sql_field->offset; key_part_info->key_type=sql_field->pack_flag; + key_part_info->key_part_flag= column->asc ? 0 : HA_REVERSE_SORT; uint key_part_length= sql_field->type_handler()-> calc_key_length(*sql_field); @@ -6335,6 +6336,14 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key, return Compare_keys::NotEqual; } + /* + Check the descending flag for index field. + */ + if ((new_part->key_part_flag ^ key_part->key_part_flag) & HA_REVERSE_SORT) + { + return Compare_keys::NotEqual; + } + auto compare= table->file->compare_key_parts( *table->field[key_part->fieldnr - 1], new_field, *key_part, *new_part); result= merge(result, compare); @@ -8386,9 +8395,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key_part_length= 0; // Use whole field } key_part_length /= kfield->charset()->mbmaxlen; - key_parts.push_back(new (thd->mem_root) Key_part_spec(&cfield->field_name, - key_part_length, true), - thd->mem_root); + Key_part_spec *kps= new (thd->mem_root) Key_part_spec(&cfield->field_name, + key_part_length, true); + kps->asc= !(key_part->key_part_flag & HA_REVERSE_SORT); + key_parts.push_back(kps, thd->mem_root); if (!(cfield->invisible == INVISIBLE_SYSTEM && cfield->vers_sys_field())) user_keyparts= true; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8aab6bfd04d..17dc93b426e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6803,10 +6803,12 @@ ignorability: key_list: key_list ',' key_part order_dir { + $3->asc= $4; Lex->last_key->columns.push_back($3, thd->mem_root); } | key_part order_dir { + $1->asc= $2; Lex->last_key->columns.push_back($1, thd->mem_root); } ; diff --git a/sql/unireg.cc b/sql/unireg.cc index 2726b9a68c2..7f120af73d3 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009, 2020, MariaDB Corporation. + Copyright (c) 2009, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -685,6 +685,13 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, DBUG_PRINT("loop", ("flags: %lu key_parts: %d key_part: %p", key->flags, key->user_defined_key_parts, key->key_part)); + + /* For SPATIAL, FULLTEXT and HASH indexes (anything other than B-tree), + ignore the ASC/DESC attribute of columns. */ + const uchar ha_reverse_sort= + key->algorithm > HA_KEY_ALG_BTREE || key->flags & (HA_FULLTEXT|HA_SPATIAL) + ? 0 : HA_REVERSE_SORT; + for (key_part=key->key_part,key_part_end=key_part+key->user_defined_key_parts ; key_part != key_part_end ; key_part++) @@ -697,7 +704,8 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED); offset= (uint) (key_part->offset+data_offset+1); int2store(pos+2, offset); - pos[4]=0; // Sort order + key_part->key_part_flag &= ha_reverse_sort; + pos[4]= (uchar)(key_part->key_part_flag); int2store(pos+5,key_part->key_type); int2store(pos+7,key_part->length); pos+=9;