diff --git a/mysql-test/main/range_notembedded.result b/mysql-test/main/range_notembedded.result index 9cd939031848e..9965969e1170d 100644 --- a/mysql-test/main/range_notembedded.result +++ b/mysql-test/main/range_notembedded.result @@ -124,7 +124,7 @@ left(@json, 2500) "sel_arg_weight_heuristic": { "key1_field": "kp1", - "key2_field": "kp2", + "key2_type": 3, "key1_weight": 10, "key2_weight": 10 } @@ -133,7 +133,7 @@ left(@json, 2500) "sel_arg_weight_heuristic": { "key1_field": "kp1", - "key2_field": "kp3", + "key2_type": 3, "key1_weight": 10, "key2_weight": 10 } @@ -142,7 +142,7 @@ left(@json, 2500) "sel_arg_weight_heuristic": { "key1_field": "kp1", - "key2_field": "kp4", + "key2_type": 3, "key1_weight": 10, "key2_weight": 10 } @@ -308,3 +308,75 @@ json_pretty(json_search(@trace, 'all', 'key1')) "$[0].analyzing_range_alternatives.range_scan_alternatives[0].index" ] drop table t1; +# +# MDEV-37510: Crash in sel_arg_and_weight_heuristic +# +SET @save_optimizer_trace=@@optimizer_trace; +SET @save_optimizer_max_sel_arg_weight=@@optimizer_max_sel_arg_weight; +SET optimizer_trace= 'enabled=on'; +SET optimizer_max_sel_arg_weight=1; +CREATE TABLE t1 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +CREATE TABLE t2 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +INSERT INTO t1 values (2, 'two', 'prime'), (3, 'three', 'prime'); +INSERT INTO t2 values (2, 'two', '2_table'), (4, 'four', '2_table'); +EXPLAIN +SELECT t1.c1, v1.c2 +FROM +( +t1 +JOIN +( +SELECT c1, c2, c3 FROM t2 +UNION SELECT c1, c2, c3 FROM t2 +) v1 +ON ( +(t1.c1 = v1.c1 OR v1.c1 IS NULL) AND +(t1.c2 = v1.c2 OR v1.c3 IS NULL) AND +v1.c3 IN ('2_table', '3_table') +) +) +WHERE t1.c1 NOT IN (5, 6, 7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +2 DERIVED t2 ALL NULL NULL NULL NULL 2 Using where +3 UNION t2 ALL NULL NULL NULL NULL 2 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +set @trace= (select trace from information_schema.optimizer_trace); +set @json= json_detailed(json_extract(@trace, '$**.setup_range_conditions')); +select left(@json, 2500); +left(@json, 2500) +[ + [ + { + "sel_arg_weight_heuristic": + { + "key1_type": 2, + "key2_type": 2, + "key1_weight": 1, + "key2_weight": 1 + } + }, + { + "sel_arg_weight_heuristic": + { + "key1_type": 2, + "key2_type": 3, + "key1_weight": 1, + "key2_weight": 1 + } + }, + { + "enforce_sel_arg_weight_limit": + { + "index": "distinct_key", + "old_weight": 2, + "new_weight": 0 + } + } + ] +] +DROP TABLE t1, t2; +SET optimizer_trace=@save_optimizer_trace; +SET optimizer_max_sel_arg_weight=@save_optimizer_max_sel_arg_weight; +# end of 11.4 tests diff --git a/mysql-test/main/range_notembedded.test b/mysql-test/main/range_notembedded.test index a13bb1d95c79a..47cad12139258 100644 --- a/mysql-test/main/range_notembedded.test +++ b/mysql-test/main/range_notembedded.test @@ -211,3 +211,45 @@ set @trace=json_extract((select trace from information_schema.optimizer_trace), select json_pretty(json_search(@trace, 'all', 'key1')); drop table t1; +--echo # +--echo # MDEV-37510: Crash in sel_arg_and_weight_heuristic +--echo # +SET @save_optimizer_trace=@@optimizer_trace; +SET @save_optimizer_max_sel_arg_weight=@@optimizer_max_sel_arg_weight; + +SET optimizer_trace= 'enabled=on'; +SET optimizer_max_sel_arg_weight=1; + +CREATE TABLE t1 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); +CREATE TABLE t2 (c1 INT, c2 VARCHAR(10), c3 VARCHAR(10)); + +INSERT INTO t1 values (2, 'two', 'prime'), (3, 'three', 'prime'); +INSERT INTO t2 values (2, 'two', '2_table'), (4, 'four', '2_table'); + +EXPLAIN +SELECT t1.c1, v1.c2 + FROM + ( + t1 + JOIN + ( + SELECT c1, c2, c3 FROM t2 + UNION SELECT c1, c2, c3 FROM t2 + ) v1 + ON ( + (t1.c1 = v1.c1 OR v1.c1 IS NULL) AND + (t1.c2 = v1.c2 OR v1.c3 IS NULL) AND + v1.c3 IN ('2_table', '3_table') + ) + ) +WHERE t1.c1 NOT IN (5, 6, 7); + +set @trace= (select trace from information_schema.optimizer_trace); +set @json= json_detailed(json_extract(@trace, '$**.setup_range_conditions')); +select left(@json, 2500); + +DROP TABLE t1, t2; + +SET optimizer_trace=@save_optimizer_trace; +SET optimizer_max_sel_arg_weight=@save_optimizer_max_sel_arg_weight; +--echo # end of 11.4 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ec3623c3e1fe2..b5108b4248587 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11523,11 +11523,15 @@ bool sel_arg_and_weight_heuristic(RANGE_OPT_PARAM *param, SEL_ARG *key1, { Json_writer_object wrapper(param->thd); Json_writer_object obj(param->thd, "sel_arg_weight_heuristic"); - obj. - add("key1_field", key1->field->field_name). - add("key2_field", key2->field->field_name). - add("key1_weight", (longlong)key1->weight). - add("key2_weight", (longlong)key2->weight); + + if (key1->type == SEL_ARG::KEY_RANGE) + obj.add("key1_field", key1->field->field_name); + else + obj.add("key1_type", (uint) key1->type); + + obj.add("key2_type", (uint) key2->type); + obj.add("key1_weight", (longlong) key1->weight); + obj.add("key2_weight", (longlong) key2->weight); } return true; // Discard key2 }