1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-08 00:28:29 +03:00

Merge branch 'bb-11.4-serg' into bb-11.8-serg

This commit is contained in:
Sergei Golubchik
2025-11-04 13:58:23 +01:00
28 changed files with 625 additions and 429 deletions

View File

@@ -46,3 +46,85 @@ REPAIR LOCAL TABLE t1;
DROP TABLE t1;
SET max_session_mem_used=default;
# End of 10.6 tests
#
# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
#
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
ERROR 42000: FUNCTION test.func does not exist
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with func() defined
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x
10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with multiple functions
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
BEGIN
SELECT x, y;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y
10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with function and constant default param
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
BEGIN
SELECT x, y, z;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y z
10 10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
# End of 11.8 tests

View File

@@ -83,3 +83,97 @@ DROP TABLE t1;
SET max_session_mem_used=default;
--echo # End of 10.6 tests
--echo #
--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
--echo #
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
--ERROR ER_SP_DOES_NOT_EXIST
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with func() defined
--DELIMITER //
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with multiple functions
--DELIMITER //
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
BEGIN
SELECT x, y;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with function and constant default param
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
BEGIN
SELECT x, y, z;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
--echo # End of 11.8 tests

View File

@@ -775,8 +775,9 @@ The following specify which files/extra groups are read (specified before remain
Number of seconds to wait for a block to be written to a
connection before aborting the write
--new-mode=name Used to introduce new behavior to existing MariaDB
versions. Any combination of: FIX_DISK_TMPTABLE_COSTS, or
ALL to set all combinations
versions. Any combination of: FIX_DISK_TMPTABLE_COSTS,
FIX_INDEX_STATS_FOR_ALL_NULLS, or ALL to set all
combinations
--note-verbosity=name
Verbosity level for note-warnings given to the user. See
also @@sql_notes. Any combination of: basic,

View File

@@ -0,0 +1,158 @@
SET @session_start_value = @@new_mode;
# Small driving table
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2, 2000),(3,300);
ANALYZE TABLE t1 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
# Table that will be accessed by an index lookup (`ref` access)
CREATE TABLE t2 (a INT, b INT, KEY key_b(b));
# All t11.b values are NULL
INSERT INTO t2 SELECT seq/100, NULL FROM seq_1_to_1000;
ANALYZE TABLE t2 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status Table is already up to date
SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS";
# NULL-rejecting equality t1.b = t2.b will not return any matches
# because all values of t2.b are NULL. So "rows" = 1 for t2 where 1 is
# a special value meaning "very few" rows
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ref key_b key_b 5 test.t1.b 1 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b`
# However, rows estimation for not NULL-rejecting conditions
# must not be affected ("rows" > 1 is expected)
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b <=> t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ref key_b key_b 5 test.t1.b 11 100.00 Using index condition; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t2`.`b`
# Insert some non-NULL values and re-collect the stats
INSERT INTO t2 SELECT 1, 1 FROM seq_1_to_100;
ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (key_b);
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status OK
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ref key_b key_b 5 test.t1.b 100 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b`
# Test composite index for two columns. Key prefix is used for access
CREATE TABLE t3 (a INT, b INT, KEY key_ab(a,b));
# All t3.b values are NULL
INSERT INTO t3 SELECT seq/100, NULL FROM seq_1_to_1000;
ANALYZE TABLE t3 PERSISTENT FOR COLUMNS(b) INDEXES(key_ab);
Table Op Msg_type Msg_text
test.t3 analyze status Engine-independent statistics collected
test.t3 analyze status Table is already up to date
# NULL-rejecting equality t1.b = t3.b, same as above.
# "rows" must be estimated to 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 1 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b`
# Rows estimation for not NULL-rejecting conditions are not affected
# ("rows" > 1 is expected)
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ref key_ab key_ab 5 test.t1.a 90 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a`
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b <=> t3.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 11 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t3`.`b`
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t3.b is NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,const 11 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` is null
# In the old mode (null-aware estimation is not enabled), "rows" > 1
SET @@new_mode = "";
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ref key_b key_b 5 test.t1.b 100 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b`
# Insert some non-NULL values and re-collect the stats
INSERT INTO t3 SELECT 1, 1 FROM seq_1_to_100;
ANALYZE TABLE t3 PERSISTENT FOR COLUMNS (b) INDEXES (key_ab);
Table Op Msg_type Msg_text
test.t3 analyze status Engine-independent statistics collected
test.t3 analyze status OK
SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS";
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 100 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b`
# Test composite index for 3 columns. Key prefix is used for access
CREATE TABLE t4 (a INT, b INT, c INT, KEY key_abc(a,b,c));
# All t3.b values are NULL
INSERT INTO t4 SELECT seq/10, NULL, seq/10 FROM seq_1_to_1000;
ANALYZE TABLE t4 PERSISTENT FOR COLUMNS(b) INDEXES(key_abc);
Table Op Msg_type Msg_text
test.t4 analyze status Engine-independent statistics collected
test.t4 analyze status Table is already up to date
# NULL-rejecting equality t1.b = t3.b, same as above.
# "rows" must be estimated to 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t4 ref key_abc key_abc 10 test.t1.a,test.t1.b 1 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b`
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b and t1.b = t4.c;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t4 ref key_abc key_abc 15 test.t1.a,test.t1.b,test.t1.b 1 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b` and `test`.`t4`.`c` = `test`.`t1`.`b`
# "rows" expected to be > 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a`
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b <=> t4.c;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t4`.`c`
DROP TABLE t1, t2, t3, t4;
# Test for partially covered column
CREATE TABLE t1 (a VARCHAR(10));
INSERT INTO t1 SELECT seq FROM seq_1_to_10;
CREATE TABLE t2 (
a VARCHAR(10),
b VARCHAR(10),
INDEX i1(a, b(5))
);
INSERT INTO t2 SELECT seq, NULL FROM seq_1_to_1000;
ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (i1);
Table Op Msg_type Msg_text
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status Table is already up to date
EXPLAIN SELECT * FROM t1, t2 WHERE t2.a=t1.a AND t2.b=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
1 SIMPLE t2 ref i1 i1 66 test.t1.a,test.t1.a 1 Using where
SET @@new_mode = @session_start_value;
DROP TABLE t1, t2;

View File

@@ -0,0 +1,103 @@
--source include/have_sequence.inc
SET @session_start_value = @@new_mode;
--echo # Small driving table
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2, 2000),(3,300);
ANALYZE TABLE t1 PERSISTENT FOR ALL;
--echo # Table that will be accessed by an index lookup (`ref` access)
CREATE TABLE t2 (a INT, b INT, KEY key_b(b));
--echo # All t11.b values are NULL
INSERT INTO t2 SELECT seq/100, NULL FROM seq_1_to_1000;
ANALYZE TABLE t2 PERSISTENT FOR ALL;
SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS";
--echo # NULL-rejecting equality t1.b = t2.b will not return any matches
--echo # because all values of t2.b are NULL. So "rows" = 1 for t2 where 1 is
--echo # a special value meaning "very few" rows
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
--echo # However, rows estimation for not NULL-rejecting conditions
--echo # must not be affected ("rows" > 1 is expected)
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b <=> t2.b;
--echo # Insert some non-NULL values and re-collect the stats
INSERT INTO t2 SELECT 1, 1 FROM seq_1_to_100;
ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (key_b);
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
--echo # Test composite index for two columns. Key prefix is used for access
CREATE TABLE t3 (a INT, b INT, KEY key_ab(a,b));
--echo # All t3.b values are NULL
INSERT INTO t3 SELECT seq/100, NULL FROM seq_1_to_1000;
ANALYZE TABLE t3 PERSISTENT FOR COLUMNS(b) INDEXES(key_ab);
--echo # NULL-rejecting equality t1.b = t3.b, same as above.
--echo # "rows" must be estimated to 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b;
--echo # Rows estimation for not NULL-rejecting conditions are not affected
--echo # ("rows" > 1 is expected)
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a;
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b <=> t3.b;
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t3.b is NULL;
--echo # In the old mode (null-aware estimation is not enabled), "rows" > 1
SET @@new_mode = "";
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b;
--echo # Insert some non-NULL values and re-collect the stats
INSERT INTO t3 SELECT 1, 1 FROM seq_1_to_100;
ANALYZE TABLE t3 PERSISTENT FOR COLUMNS (b) INDEXES (key_ab);
SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS";
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b;
--echo # Test composite index for 3 columns. Key prefix is used for access
CREATE TABLE t4 (a INT, b INT, c INT, KEY key_abc(a,b,c));
--echo # All t3.b values are NULL
INSERT INTO t4 SELECT seq/10, NULL, seq/10 FROM seq_1_to_1000;
ANALYZE TABLE t4 PERSISTENT FOR COLUMNS(b) INDEXES(key_abc);
--echo # NULL-rejecting equality t1.b = t3.b, same as above.
--echo # "rows" must be estimated to 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b;
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b and t1.b = t4.c;
--echo # "rows" expected to be > 1
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a;
EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b <=> t4.c;
DROP TABLE t1, t2, t3, t4;
--echo # Test for partially covered column
CREATE TABLE t1 (a VARCHAR(10));
INSERT INTO t1 SELECT seq FROM seq_1_to_10;
CREATE TABLE t2 (
a VARCHAR(10),
b VARCHAR(10),
INDEX i1(a, b(5))
);
INSERT INTO t2 SELECT seq, NULL FROM seq_1_to_1000;
ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (i1);
EXPLAIN SELECT * FROM t1, t2 WHERE t2.a=t1.a AND t2.b=t1.a;
SET @@new_mode = @session_start_value;
DROP TABLE t1, t2;

View File

@@ -130,85 +130,4 @@ SET p2 = p2 + 1;
END;
DELIMITER ;$$
ERROR 42000: This version of MariaDB doesn't yet support 'IN sparam1 <type> DEFAULT <expr>, OUT spparam2 <type>'
#
# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
#
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
ERROR 42000: FUNCTION test.func does not exist
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with func() defined
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x
10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with multiple functions
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
BEGIN
SELECT x, y;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y
10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with function and constant default param
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
BEGIN
SELECT x, y, z;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y z
10 10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
# End of 11.8 tests

View File

@@ -139,96 +139,4 @@ BEGIN
END;
DELIMITER ;$$
--echo #
--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
--echo #
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
--ERROR ER_SP_DOES_NOT_EXIST
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with func() defined
--DELIMITER //
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with multiple functions
--DELIMITER //
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
BEGIN
SELECT x, y;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with function and constant default param
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
BEGIN
SELECT x, y, z;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
--echo # End of 11.8 tests

View File

@@ -222,91 +222,4 @@ SET p2 = p2 + 1;
END;
DELIMITER ;$$
ERROR 42000: This version of MariaDB doesn't yet support 'sparam1 IN <type> DEFAULT <expr>, spparam2 OUT <type>'
#
# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
#
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
AS
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
ERROR 42000: FUNCTION test.func does not exist
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with func() defined
CREATE FUNCTION func(x INT DEFAULT 10) RETURN INT
AS
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
AS
BEGIN
SELECT x;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x
10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with multiple functions
CREATE FUNCTION func2(x INT DEFAULT 10) RETURN INT
AS
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
AS
BEGIN
SELECT x, y;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y
10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
# with function and constant default param
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
AS
BEGIN
SELECT x, y, z;
END;
//
SET SESSION max_session_mem_used=8192;
CALL p0();
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
SET @@max_session_mem_used=DEFAULT;
CALL p0();
x y z
10 10 10
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
# End of 11.8 tests

View File

@@ -244,102 +244,4 @@ BEGIN
END;
DELIMITER ;$$
--echo #
--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
--echo #
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
AS
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
--ERROR ER_SP_DOES_NOT_EXIST
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with func() defined
--DELIMITER //
CREATE FUNCTION func(x INT DEFAULT 10) RETURN INT
AS
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
AS
BEGIN
SELECT x;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with multiple functions
--DELIMITER //
CREATE FUNCTION func2(x INT DEFAULT 10) RETURN INT
AS
BEGIN
RETURN x;
END;
//
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
AS
BEGIN
SELECT x, y;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
--echo # with function and constant default param
--DELIMITER //
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
AS
BEGIN
SELECT x, y, z;
END;
//
--DELIMITER ;
SET SESSION max_session_mem_used=8192;
--ERROR ER_OPTION_PREVENTS_STATEMENT
CALL p0();
SET @@max_session_mem_used=DEFAULT;
CALL p0();
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
DROP PROCEDURE p0;
DROP FUNCTION func;
DROP FUNCTION func2;
--echo # End of 11.8 tests

View File

@@ -5,7 +5,7 @@ drop view if exists t1;
connection node_2;
SELECT @@character_set_server, @@collation_server;
@@character_set_server @@collation_server
latin1 latin1_swedish_ci
utf8mb4 utf8mb4_uca1400_ai_ci
SELECT @@character_set_client, @@collation_connection;
@@character_set_client @@collation_connection
latin1 latin1_swedish_ci
@@ -13,7 +13,7 @@ connection node_1;
SET NAMES latin1 COLLATE latin1_bin;
SELECT @@character_set_server, @@collation_server;
@@character_set_server @@collation_server
latin1 latin1_swedish_ci
utf8mb4 utf8mb4_uca1400_ai_ci
SELECT @@character_set_client, @@collation_connection;
@@character_set_client @@collation_connection
latin1 latin1_bin
@@ -27,7 +27,7 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
connection node_2;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -36,7 +36,7 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
connection node_1;
DROP VIEW v1;
DROP TABLE t1;

View File

@@ -37,7 +37,7 @@ Function sql_mode Create Function character_set_client collation_connection Data
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`user1`@`%` FUNCTION `f1`(param INTEGER) RETURNS varchar(200) CHARSET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci
MODIFIES SQL DATA
COMMENT 'f1_comment'
RETURN 'abc' utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
RETURN 'abc' latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
connection node_1;
SHOW CREATE FUNCTION f2;
Function sql_mode Create Function character_set_client collation_connection Database Collation
@@ -53,7 +53,7 @@ f2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_
NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
RETURN 123 utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
RETURN 123 latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
SELECT f1(1) = 'abc';
f1(1) = 'abc'
1

View File

@@ -36,7 +36,7 @@ Procedure sql_mode Create Procedure character_set_client collation_connection Da
p1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`user1`@`%` PROCEDURE `p1`(IN param1 INTEGER, OUT param2 INTEGER, INOUT param3 INTEGER)
MODIFIES SQL DATA
COMMENT 'p1_comment'
INSERT INTO t1 VALUES (1) utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
INSERT INTO t1 VALUES (1) latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
connection node_1;
SHOW CREATE PROCEDURE p2;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
@@ -52,7 +52,7 @@ p2 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_
NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN END utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
BEGIN END latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
CALL p1(@a, @b, @c);
CALL p2('abc');
connection node_1;

View File

@@ -59,10 +59,10 @@ t2_v2 CREATE TABLE `t2_v2` (
PARTITIONS 2
SHOW CREATE VIEW x1;
View Create View character_set_client collation_connection
x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2`,`t1_v2`.`v3` AS `v3` from `t1_v2` utf8mb4 utf8mb4_uca1400_ai_ci
x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2`,`t1_v2`.`v3` AS `v3` from `t1_v2` latin1 latin1_swedish_ci
SHOW CREATE VIEW x2;
View Create View character_set_client collation_connection
x2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x2` AS select `t2_v2`.`v1` AS `v1`,`t2_v2`.`v2` AS `v2`,`t2_v2`.`v3` AS `v3` from `t2_v2` utf8mb4 utf8mb4_uca1400_ai_ci
x2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x2` AS select `t2_v2`.`v1` AS `v1`,`t2_v2`.`v2` AS `v2`,`t2_v2`.`v3` AS `v3` from `t2_v2` latin1 latin1_swedish_ci
SELECT * FROM t1_v2;
v1 v2 v3
SELECT * FROM t2_v2;
@@ -148,7 +148,7 @@ t2 CREATE TABLE `t2` (
PARTITIONS 2
SHOW CREATE VIEW x1;
View Create View character_set_client collation_connection
x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2` from `t1_v2` utf8mb4 utf8mb4_uca1400_ai_ci
x1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `x1` AS select `t1_v2`.`v1` AS `v1`,`t1_v2`.`v2` AS `v2` from `t1_v2` latin1 latin1_swedish_ci
SELECT * FROM t1_v2;
v1 v2
SELECT * FROM t2;

View File

@@ -15,7 +15,7 @@ connection node_2;
SHOW CREATE PROCEDURE p1;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SELECT 1 FROM DUAL utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
SELECT 1 FROM DUAL latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
DROP PROCEDURE p1;
connection node_1;
CREATE PROCEDURE p1 () SELECT 1 FROM DUAL;
@@ -30,7 +30,7 @@ connection node_2;
SHOW CREATE FUNCTION f1;
Function sql_mode Create Function character_set_client collation_connection Database Collation
f1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
RETURN 123 utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
RETURN 123 latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
DROP FUNCTION f1;
connection node_1;
CREATE FUNCTION f1 () RETURNS INTEGER RETURN 123;
@@ -45,12 +45,12 @@ CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f1 = 'a';
connection node_2;
SHOW CREATE TRIGGER tr1;
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f1 = 'a' utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci #
tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f1 = 'a' latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci #
DROP TABLE t1;
connection node_1;
CREATE EVENT event1 ON SCHEDULE AT '2038-01-01 23:59:59' DO SELECT 1;
connection node_2;
SHOW CREATE EVENT event1;
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
event1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `event1` ON SCHEDULE AT '2038-01-01 23:59:59' ON COMPLETION NOT PRESERVE DISABLE ON SLAVE DO SELECT 1 utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
event1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `event1` ON SCHEDULE AT '2038-01-01 23:59:59' ON COMPLETION NOT PRESERVE DISABLE ON SLAVE DO SELECT 1 latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
DROP EVENT event1;

View File

@@ -22,16 +22,16 @@ connection node_2;
USE test;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v2 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v4;
View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
# On node_1
connection node_1;
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
@@ -42,16 +42,16 @@ ALTER ALGORITHM=TEMPTABLE DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM t1;
connection node_2;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v3 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
SHOW CREATE VIEW v4;
View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
# Cleanup
DROP VIEW v1, v2, v3, v4;
DROP TABLE t1;

View File

@@ -1088,13 +1088,8 @@ show create view v;
View Create View character_set_client collation_connection
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `T`.`col1` AS `col1` from JSON_TABLE('{"a": "b"}', '$' COLUMNS (`col1` varchar(32) PATH '$.fooo' DEFAULT 'asdf' ON EMPTY)) `T` latin1 latin1_swedish_ci
drop view v;
#
# End of 10.6 tests
#
#
# Start of 10.9 tests
#
#
# MDEV-27743 Remove Lex::charset
#
SELECT collation(name)
@@ -1214,10 +1209,8 @@ name ENUM('Laptop') CHARACTER SET BINARY PATH '$.name')
) AS jt;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ENUM('Laptop') CHARACTER SET BINARY PATH '$.name')
) AS jt' at line 6
#
# End of 10.9 tests
#
#
# MDEV-27898 CREATE VIEW AS SELECT FROM JSON_TABLE column requires global privileges
#
# Beginning of 10.11 tests
@@ -1383,7 +1376,5 @@ Laptop black 20000.00 2
Jacket brown 5000.00 1
Jeans blue 5000.00 2
drop table t1;
#
# End of 11.0 tests
#
ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci;

View File

@@ -920,13 +920,7 @@ show create view v;
drop view v;
--echo #
--echo # End of 10.6 tests
--echo #
--echo #
--echo # Start of 10.9 tests
--echo #
--echo #
--echo # MDEV-27743 Remove Lex::charset
@@ -1041,9 +1035,7 @@ COLUMNS
name ENUM('Laptop') CHARACTER SET BINARY PATH '$.name')
) AS jt;
--echo #
--echo # End of 10.9 tests
--echo #
--echo #
--echo # MDEV-27898 CREATE VIEW AS SELECT FROM JSON_TABLE column requires global privileges
@@ -1198,8 +1190,6 @@ select * from t1;
drop table t1;
--echo #
--echo # End of 11.0 tests
--echo #
--source include/test_db_charset_restore.inc

View File

@@ -32,7 +32,7 @@ ERROR 42000: Variable 'new_mode' can't be set to the value of 'TEST_WARNING3'
SET @@session.new_mode = "ALL";
select @@session.new_mode;
@@session.new_mode
FIX_DISK_TMPTABLE_COSTS
FIX_DISK_TMPTABLE_COSTS,FIX_INDEX_STATS_FOR_ALL_NULLS
SET @@global.new_mode = NULL;
ERROR 42000: Variable 'new_mode' can't be set to the value of 'NULL'
SET @@global.new_mode = '';

View File

@@ -2399,7 +2399,7 @@ VARIABLE_COMMENT Used to introduce new behavior to existing MariaDB versions
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS,FIX_INDEX_STATS_FOR_ALL_NULLS
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NOTE_VERBOSITY

View File

@@ -2609,7 +2609,7 @@ VARIABLE_COMMENT Used to introduce new behavior to existing MariaDB versions
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS
ENUM_VALUE_LIST FIX_DISK_TMPTABLE_COSTS,FIX_INDEX_STATS_FOR_ALL_NULLS
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME NOTE_VERBOSITY

View File

@@ -222,8 +222,9 @@ void old_mode_deprecated_warnings(ulonglong v);
See sys_vars.cc /new_mode_all_names
*/
#define NEW_MODE_FIX_DISK_TMPTABLE_COSTS (1 << 0)
#define NEW_MODE_MAX 1
#define NEW_MODE_FIX_DISK_TMPTABLE_COSTS (1ULL << 0)
#define NEW_MODE_FIX_INDEX_STATS_FOR_ALL_NULLS (1ULL << 1)
#define NEW_MODE_MAX 2
/* Definitions above that have transitioned from new behaviour to default */

View File

@@ -8777,7 +8777,26 @@ best_access_path(JOIN *join,
ulong key_flags;
uint key_parts;
key_part_map found_part= 0;
/* key parts which won't have NULL in lookup tuple */
/*
Bitmap indicating which key parts are used with NULL-rejecting
conditions.
A bit is set to 1 for a key part if it's used with a
NULL-rejecting condition (i.e., the condition will never be
satisfied when the indexed column contains NULL). A bit is 0 if
the key part is used with a non-NULL-rejecting condition (i.e.,
the condition can be satisfied even when the indexed column
contains NULL, e.g., is NULL or <=>).
Example: for condition
t1.keypart1 = t2.col1 AND t1.keypart2 <=> t2.col2 AND
t1.keypart3 = t2.col3
the notnull_part bitmap will be 101 (binary), because:
- keypart1: '=' is NULL-rejecting (bit 1)
- keypart2: '<=>' is NOT NULL-rejecting (bit 0)
- keypart3: '=' is NULL-rejecting (bit 1)
*/
key_part_map notnull_part=0;
table_map found_ref= 0;
uint key= keyuse->key;
@@ -9032,7 +9051,8 @@ best_access_path(JOIN *join,
}
else
{
if (!(records= keyinfo->actual_rec_per_key(key_parts-1)))
if (!(records=
keyinfo->rec_per_key_null_aware(key_parts-1, notnull_part)))
{ /* Prefer longer keys */
trace_access_idx.add("rec_per_key_stats_missing", true);
records=
@@ -9164,7 +9184,9 @@ best_access_path(JOIN *join,
else
{
/* Check if we have statistic about the distribution */
if ((records= keyinfo->actual_rec_per_key(max_key_part-1)))
if ((records=
keyinfo->rec_per_key_null_aware(max_key_part-1,
notnull_part)))
{
/*
Fix for the case where the index statistics is too
@@ -13505,6 +13527,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
keyinfo->flags= HA_GENERATED_KEY;
keyinfo->is_statistics_from_stat_tables= FALSE;
keyinfo->all_nulls_key_parts= 0;
keyinfo->name.str= "$hj";
keyinfo->name.length= 3;
keyinfo->rec_per_key= thd->calloc<ulong>(key_parts);
@@ -22494,6 +22517,7 @@ bool Create_tmp_table::finalize(THD *thd,
keyinfo->collected_stats= NULL;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
keyinfo->is_statistics_from_stat_tables= FALSE;
keyinfo->all_nulls_key_parts= 0;
keyinfo->name= group_key;
keyinfo->comment.str= 0;
ORDER *cur_group= m_group;
@@ -22615,6 +22639,7 @@ bool Create_tmp_table::finalize(THD *thd,
keyinfo->name= distinct_key;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
keyinfo->is_statistics_from_stat_tables= FALSE;
keyinfo->all_nulls_key_parts= 0;
keyinfo->read_stats= NULL;
keyinfo->collected_stats= NULL;

View File

@@ -3122,7 +3122,10 @@ read_statistics_for_table(THD *thd, TABLE *table,
found|= index_stat.get_stat_values(index_statistics);
}
if (found)
{
new_stats_cb->stats_available|= TABLE_STAT_INDEX;
index_statistics->mark_stats_as_read();
}
key_part_map ext_key_part_map= key_info->ext_key_part_map;
if (key_info->user_defined_key_parts != key_info->ext_key_parts &&
@@ -4156,11 +4159,35 @@ void set_statistics_for_table(THD *thd, TABLE *table)
for (key_info= table->key_info, key_info_end= key_info+table->s->keys;
key_info < key_info_end; key_info++)
{
key_info->all_nulls_key_parts= 0;
key_info->is_statistics_from_stat_tables=
(check_eits_preferred(thd) &&
table->stats_is_read &&
key_info->read_stats->avg_frequency_is_inited() &&
key_info->read_stats->get_avg_frequency(0) > 0.5);
key_info->read_stats->has_stats(thd));
// Fill out `all_nulls_key_parts` bitmap
if (TEST_NEW_MODE_FLAG(thd, NEW_MODE_FIX_INDEX_STATS_FOR_ALL_NULLS) &&
key_info->is_statistics_from_stat_tables)
{
for (uint part_idx= 0; part_idx < key_info->usable_key_parts; part_idx++)
{
Field *field=
table->field[key_info->key_part[part_idx].field->field_index];
if (!field->read_stats)
{
// No column statistics available
continue;
}
// Check if all values in this column are NULL according to statistics
double nulls_ratio= field->read_stats->get_nulls_ratio();
if (nulls_ratio == 1.0)
{
key_info->all_nulls_key_parts |= (1 << part_idx);
}
}
}
}
}

View File

@@ -603,10 +603,24 @@ private:
k-component prefixes among them
*/
ulonglong *avg_frequency;
bool stats_were_read;
public:
void init_avg_frequency(ulonglong *ptr)
{
avg_frequency= ptr;
stats_were_read= false;
}
void init_avg_frequency(ulonglong *ptr) { avg_frequency= ptr; }
void mark_stats_as_read() { stats_were_read= true; }
bool has_stats(THD *thd) const
{
if (TEST_NEW_MODE_FLAG(thd, NEW_MODE_FIX_INDEX_STATS_FOR_ALL_NULLS))
return stats_were_read;
else
return get_avg_frequency(0) > 0.5;
}
bool avg_frequency_is_inited() { return avg_frequency != NULL; }

View File

@@ -173,7 +173,17 @@ typedef struct st_key {
engine_option_value *option_list;
ha_index_option_struct *option_struct; /* structure with parsed options */
double actual_rec_per_key(uint i) const;
/*
Bitmap of key parts where all values are NULL (nulls_ratio == 1.0).
Bit N set means key part N has all NULLs in the corresponding column.
Used for NULL-aware cardinality estimation.
It is computed based on EITS data, otherwise it is 0.
*/
key_part_map all_nulls_key_parts;
double actual_rec_per_key(uint last_key_part_in_prefix) const;
double rec_per_key_null_aware(uint last_key_part_in_prefix,
key_part_map notnull_part) const;
} KEY;

View File

@@ -4113,6 +4113,7 @@ static Sys_var_set Sys_old_behavior(
static const char *new_mode_all_names[]=
{
"FIX_DISK_TMPTABLE_COSTS",
"FIX_INDEX_STATS_FOR_ALL_NULLS",
"TEST_WARNING1", // Default from here, See NEW_MODE_MAX
"TEST_WARNING2",
0
@@ -4120,8 +4121,8 @@ static const char *new_mode_all_names[]=
static int new_mode_hidden_names[] =
{
1, // TEST_WARNING1
2, // TEST_WARNING2
2, // TEST_WARNING1
3, // TEST_WARNING2
-1 // End of list
};

View File

@@ -8701,6 +8701,7 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
keyinfo->read_stats= NULL;
keyinfo->collected_stats= NULL;
keyinfo->all_nulls_key_parts= 0;
for (i= 0; i < key_parts; i++)
{
@@ -10436,12 +10437,68 @@ uint TABLE_SHARE::actual_n_key_parts(THD *thd)
}
double KEY::actual_rec_per_key(uint i) const
/**
Get records-per-key estimate for an index prefix.
Returns average number of records per key value for the given index prefix.
Prefers engine-independent statistics (EITS) if available and falls back
to engine-dependent statistics otherwise.
@param last_key_part_in_prefix Index of the last key part
in the prefix (0-based)
@return Estimated records per key value:
- 0.0 if no statistics available
- avg_frequency from EITS if available
- rec_per_key from engine statistics if EITS is not available
*/
double KEY::actual_rec_per_key(uint last_key_part_in_prefix) const
{
if (rec_per_key == 0)
return 0;
return (is_statistics_from_stat_tables ?
read_stats->get_avg_frequency(i) : (double) rec_per_key[i]);
if (is_statistics_from_stat_tables)
{
// Use engine-independent statistics (EITS)
return read_stats->get_avg_frequency(last_key_part_in_prefix);
}
// Fall back to engine-dependent statistics if EITS is not available
return rec_per_key ? (double) rec_per_key[last_key_part_in_prefix] : 0.0;
}
/**
Get records-per-key estimate for an index prefix with NULL-aware optimization.
Returns average number of records per key value for the given index prefix.
When EITS statistics show avg_frequency == 0 (typically all NULL values) and
the query uses NULL-rejecting conditions (e.g., =), returns 1.0 to indicate
high selectivity since NULL = NULL never matches.
@param last_key_part_in_prefix Index of the last key part
in the prefix (0-based)
@param notnull_part Bitmap indicating which key parts have NULL-rejecting
conditions (bit N set means key part N uses =, not <=>)
@return Estimated records per key value:
- 0.0 if no statistics available
- avg_frequency from EITS if available
- 1.0 if all values are NULL with NULL-rejecting condition
- rec_per_key from engine statistics if EITS is not available
*/
double KEY::rec_per_key_null_aware(uint last_key_part_in_prefix,
key_part_map notnull_part) const
{
if (notnull_part & all_nulls_key_parts)
{
/*
For NULL-rejecting conditions like `t1.key_col = t2.col`, we know
there will be no matches (since NULL = NULL is never true).
If at least one NULL-rejecting condition is present, and all
corresponding key part values are NULL, return number of records 1.0
(highly selective), indicating no expected matches.
*/
return 1.0;
}
return actual_rec_per_key(last_key_part_in_prefix);
}
/*

View File

@@ -9,7 +9,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -144,7 +144,7 @@ col_a col_dt col_ts unix_timestamp(col_ts)
@@ -144,7 +144,7 @@
connection child2_1;
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument
@@ -18,7 +18,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -170,7 +170,7 @@ col_a col_dt col_ts unix_timestamp(col_ts)
@@ -170,7 +170,7 @@
connection child2_1;
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument
@@ -27,7 +27,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -198,7 +198,7 @@ connection child2_1;
@@ -198,7 +198,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument
select `col_a`,`col_dt`,`col_ts` from `ts_test_remote`.`tbl_a` for update
@@ -36,7 +36,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -256,13 +256,13 @@ col_a col_dt col_ts unix_timestamp(col_ts)
@@ -256,13 +256,13 @@
connection child2_1;
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument
@@ -57,7 +57,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -343,13 +343,13 @@ col_a col_dt col_ts unix_timestamp(col_ts)
@@ -343,13 +343,13 @@
connection child2_1;
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument
@@ -78,7 +78,7 @@
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'
SELECT col_a, col_dt, col_ts, unix_timestamp(col_ts) FROM tbl_a ORDER BY col_a;
col_a col_dt col_ts unix_timestamp(col_ts)
@@ -396,11 +396,11 @@ TIMESTAMP('2018-06-25', '10:43:21')
@@ -396,11 +396,11 @@
connection child2_1;
SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %';
argument