diff --git a/mysql-test/main/opt_context_load_stats_basic.result b/mysql-test/main/opt_context_load_stats_basic.result index e4ed80a9583..e725036803b 100644 --- a/mysql-test/main/opt_context_load_stats_basic.result +++ b/mysql-test/main/opt_context_load_stats_basic.result @@ -507,4 +507,34 @@ Warning 4270 Failed to match the stats from replay context with the optimizer st Warning 4270 Failed to match the stats from replay context with the optimizer stats: test.t1 with key_number:0, records:10, eq_ref:0 doesn't exist in cost_for_index_read_calls set optimizer_replay_context=''; drop table t1; +# +# rec_per_key out of range +# +create table t1 (a int, b int, key(a)); +insert into t1 select seq%10, seq from seq_1_to_100; +select count(*) from t1 where a=3; +count(*) +10 +set @opt_context= +(select REGEXP_SUBSTR( +context, +'(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') +from information_schema.optimizer_context); +set @opt_context_rpk= json_replace(@opt_context, +'$.tables[0].indexes[0].rec_per_key[0]', -1); +set optimizer_replay_context='opt_context_rpk'; +select count(*) from t1 where a=3; +count(*) +10 +Warnings: +Warning 4269 Failed to parse saved optimizer context: rec_per_key value is out of range at offset 229. +set @opt_context_rpk= json_replace(@opt_context, +'$.tables[0].indexes[0].rec_per_key[0]', 1e300); +select count(*) from t1 where a=3; +count(*) +10 +Warnings: +Warning 4269 Failed to parse saved optimizer context: rec_per_key value is out of range at offset 232. +set optimizer_replay_context=''; +drop table t1; # End of 13.1 tests diff --git a/mysql-test/main/opt_context_load_stats_basic.test b/mysql-test/main/opt_context_load_stats_basic.test index edcefa73f26..d4b15fba405 100644 --- a/mysql-test/main/opt_context_load_stats_basic.test +++ b/mysql-test/main/opt_context_load_stats_basic.test @@ -325,4 +325,21 @@ explain select t1.b from t1, t1 t2 where t1.a = t2.a; set optimizer_replay_context=''; drop table t1; +--echo # +--echo # rec_per_key out of range +--echo # +create table t1 (a int, b int, key(a)); +insert into t1 select seq%10, seq from seq_1_to_100; +select count(*) from t1 where a=3; +--source include/opt_context_save_in_var.inc +set @opt_context_rpk= json_replace(@opt_context, + '$.tables[0].indexes[0].rec_per_key[0]', -1); +set optimizer_replay_context='opt_context_rpk'; +select count(*) from t1 where a=3; +set @opt_context_rpk= json_replace(@opt_context, + '$.tables[0].indexes[0].rec_per_key[0]', 1e300); +select count(*) from t1 where a=3; +set optimizer_replay_context=''; +drop table t1; + --echo # End of 13.1 tests diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index bd93109836c..80eaf89d041 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -1352,6 +1352,14 @@ public: if (read_double(je , name, err_buf, val)) return 1; + /* Index_statistics stores it multiplied by 100000 in a ulonglong */ + if (val < 0 || val > 1e14) + { + err_buf->append(name, strlen(name)); + err_buf->append(STRING_WITH_LEN(" value is out of range")); + return 1; + } + if (list_values->append(val) || json_scan_next(je)) return 1; }