183 lines
5.8 KiB
Plaintext
183 lines
5.8 KiB
Plaintext
set tidb_cost_model_version=1;
|
|
# Tests of using stored generated column as index and partition column.
|
|
# Most of the cases are ported from other tests to make sure generated columns behaves the same.
|
|
|
|
# Stored generated columns as indices
|
|
|
|
DROP TABLE IF EXISTS person;
|
|
CREATE TABLE person (
|
|
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
address_info JSON,
|
|
city VARCHAR(64) AS (JSON_UNQUOTE(JSON_EXTRACT(address_info, '$.city'))) STORED,
|
|
KEY (city)
|
|
);
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT name, id FROM person WHERE city = 'Beijing';
|
|
|
|
|
|
DROP TABLE IF EXISTS `sgc`;
|
|
CREATE TABLE `sgc` (
|
|
`j1` JSON DEFAULT NULL,
|
|
`j2` JSON DEFAULT NULL,
|
|
`a` int(11) GENERATED ALWAYS AS (JSON_EXTRACT(`j1`, "$.a")) STORED,
|
|
`b` int(2) GENERATED ALWAYS AS (JSON_CONTAINS(j2, '1')) STORED,
|
|
KEY `idx_a` (`a`),
|
|
KEY `idx_b` (`b`),
|
|
KEY `idx_a_b` (`a`,`b`)
|
|
);
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT a FROM sgc where a < 3;
|
|
EXPLAIN format = 'plan_tree' SELECT a, b FROM sgc where a < 3;
|
|
EXPLAIN format = 'plan_tree' SELECT a, b from sgc where b < 3;
|
|
EXPLAIN format = 'plan_tree' SELECT a, b from sgc where a < 3 and b < 3;
|
|
|
|
DROP TABLE IF EXISTS sgc1,
|
|
sgc2;
|
|
|
|
|
|
CREATE TABLE `sgc1` (
|
|
`j1` JSON,
|
|
`j2` JSON,
|
|
`a` INT AS (JSON_EXTRACT(j1, "$.a")) STORED,
|
|
`b` VARCHAR(20) AS (JSON_KEYS(j2)) STORED,
|
|
KEY `idx_a` (`a`),
|
|
KEY `idx_b` (`b`),
|
|
KEY `idx_a_b` (`a`, `b`)
|
|
);
|
|
|
|
CREATE TABLE `sgc2` (
|
|
`j1` JSON,
|
|
`j2` JSON,
|
|
`a` INT AS (JSON_EXTRACT(j1, "$.a")) STORED,
|
|
`b` VARCHAR(20) AS (JSON_KEYS(j2)) STORED,
|
|
KEY `idx_a` (`a`),
|
|
KEY `idx_b` (`b`),
|
|
KEY `idx_a_b` (`a`, `b`)
|
|
);
|
|
|
|
INSERT INTO sgc1(j1, j2)
|
|
VALUES ('{"a": 1}', '{"1": "1"}'),
|
|
('{"a": 1}', '{"1": "1"}'),
|
|
('{"a": 1}', '{"1": "1"}'),
|
|
('{"a": 1}', '{"1": "1"}'),
|
|
('{"a": 1}', '{"1": "1"}');
|
|
|
|
INSERT INTO sgc2(j1, j2)
|
|
VALUES ('{"a": 1}', '{"1": "1"}');
|
|
|
|
# FIXME: With all options on, it got runtime error: index out of range [-1]
|
|
ANALYZE TABLE sgc1, sgc2 predicate columns;
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT /*+ TIDB_INLJ(sgc1, sgc2) */ * from sgc1 join sgc2 on sgc1.a=sgc2.a;
|
|
EXPLAIN format = 'plan_tree' SELECT * from sgc1 join sgc2 on sgc1.a=sgc2.a;
|
|
|
|
|
|
# Stored generated columns as partition columns
|
|
|
|
set @old_prune_mode = @@tidb_partition_prune_mode;
|
|
set @@tidb_partition_prune_mode='static';
|
|
DROP TABLE IF EXISTS sgc3;
|
|
CREATE TABLE sgc3 (
|
|
j JSON,
|
|
a INT AS (JSON_EXTRACT(j, "$.a")) STORED
|
|
)
|
|
PARTITION BY RANGE (a) (
|
|
PARTITION p0 VALUES LESS THAN (1),
|
|
PARTITION p1 VALUES LESS THAN (2),
|
|
PARTITION p2 VALUES LESS THAN (3),
|
|
PARTITION p3 VALUES LESS THAN (4),
|
|
PARTITION p4 VALUES LESS THAN (5),
|
|
PARTITION p5 VALUES LESS THAN (6),
|
|
PARTITION max VALUES LESS THAN MAXVALUE);
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM sgc3 WHERE a <= 1;
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM sgc3 WHERE a < 7;
|
|
|
|
set @@tidb_partition_prune_mode='dynamic';
|
|
DROP TABLE sgc3;
|
|
CREATE TABLE sgc3 (
|
|
j JSON,
|
|
a INT AS (JSON_EXTRACT(j, "$.a")) STORED
|
|
)
|
|
PARTITION BY RANGE (a) (
|
|
PARTITION p0 VALUES LESS THAN (1),
|
|
PARTITION p1 VALUES LESS THAN (2),
|
|
PARTITION p2 VALUES LESS THAN (3),
|
|
PARTITION p3 VALUES LESS THAN (4),
|
|
PARTITION p4 VALUES LESS THAN (5),
|
|
PARTITION p5 VALUES LESS THAN (6),
|
|
PARTITION max VALUES LESS THAN MAXVALUE);
|
|
|
|
analyze table sgc3;
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM sgc3 WHERE a <= 1;
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM sgc3 WHERE a < 7;
|
|
|
|
set @@tidb_partition_prune_mode = @old_prune_mode;
|
|
|
|
# Virtual generated columns as indices
|
|
|
|
DROP TABLE IF EXISTS t1;
|
|
CREATE TABLE t1(a INT, b INT AS (a+1) VIRTUAL, c INT AS (b+1) VIRTUAL, d INT AS (c+1) VIRTUAL, KEY(b), INDEX IDX(c, d));
|
|
INSERT INTO t1 (a) VALUES (0);
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT b FROM t1 WHERE b=1;
|
|
EXPLAIN format = 'plan_tree' SELECT b, c, d FROM t1 WHERE b=1;
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM t1 WHERE b=1;
|
|
EXPLAIN format = 'plan_tree' SELECT c FROM t1 WHERE c=2 AND d=3;
|
|
|
|
DROP TABLE IF EXISTS person;
|
|
CREATE TABLE person (
|
|
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
address_info JSON,
|
|
city_no INT AS (JSON_EXTRACT(address_info, '$.city_no')) VIRTUAL,
|
|
KEY(city_no));
|
|
|
|
INSERT INTO person (name, address_info) VALUES ("John", CAST('{"city_no": 1}' AS JSON));
|
|
EXPLAIN format = 'plan_tree' SELECT name FROM person where city_no=1;
|
|
|
|
# Virtual generated columns in aggregate statement
|
|
# ISSUE https://github.com/pingcap/tidb/issues/14072
|
|
|
|
DROP TABLE IF EXISTS t1;
|
|
CREATE TABLE t1 (a INT,
|
|
b INT GENERATED ALWAYS AS (-a) VIRTUAL,
|
|
c INT GENERATED ALWAYS AS (-a) STORED,
|
|
index (c));
|
|
INSERT INTO t1 (a) VALUES (2), (1), (1), (3), (NULL);
|
|
|
|
EXPLAIN format = 'plan_tree' SELECT sum(a) FROM t1 GROUP BY b;
|
|
EXPLAIN format = 'plan_tree' SELECT sum(a) FROM t1 GROUP BY c;
|
|
EXPLAIN format = 'plan_tree' SELECT sum(b) FROM t1 GROUP BY a;
|
|
EXPLAIN format = 'plan_tree' SELECT sum(b) FROM t1 GROUP BY c;
|
|
EXPLAIN format = 'plan_tree' SELECT sum(c) FROM t1 GROUP BY a;
|
|
EXPLAIN format = 'plan_tree' SELECT sum(c) FROM t1 GROUP BY b;
|
|
|
|
# Virtual generated column for point get and batch point get
|
|
DROP TABLE IF EXISTS tu;
|
|
CREATE TABLE tu (a INT, b INT, c INT GENERATED ALWAYS AS (a + b) VIRTUAL, primary key (a), unique key uk(c));
|
|
INSERT INTO tu(a, b) VALUES(1, 2);
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM tu WHERE c = 1;
|
|
EXPLAIN format = 'plan_tree' SELECT a, c FROM tu WHERE c = 1;
|
|
EXPLAIN format = 'plan_tree' SELECT * FROM tu WHERE c in(1, 2, 3);
|
|
EXPLAIN format = 'plan_tree' SELECT c, a FROM tu WHERE c in(1, 2, 3);
|
|
|
|
# should handle divide zero error for default sql mode
|
|
set @@sql_mode=default;
|
|
drop table if exists t1;
|
|
create table t1(a int);
|
|
insert into t1 values(0);
|
|
--error 1365
|
|
alter table t1 add index i((100/a));
|
|
drop table t1;
|
|
|
|
# should ignore divide zero error for default sql mode
|
|
set @@sql_mode='';
|
|
create table t1(a int);
|
|
insert into t1 values(0);
|
|
alter table t1 add index i((100/a));
|
|
drop table t1;
|
|
set @@sql_mode=default;
|