From 5152905978e5de118792454085800c5348014c21 Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Mon, 8 Jun 2026 09:47:49 +0530 Subject: [PATCH] MDEV-39433: Crash when recording context for a sequence query With optimizer_record_context enabled, a simple query involving sequence such as: create sequence s1; Explain select * from s1; is crashing in store_optimizer_costs(). There are no costs associated with sequence tables, and their fields, and hence when trying to access cost information for them, a crash occurs. Solution ======== Don't try to store stats or cost information for sequences --- .../get_rec_idx_ranges_from_opt_ctx.inc | 24 +- .../main/opt_context_load_stats_basic.result | 75 +--- .../main/opt_context_load_stats_basic.test | 19 +- .../main/opt_context_store_stats.result | 408 +++++++----------- mysql-test/main/opt_context_store_stats.test | 11 + sql/opt_context_store_replay.cc | 4 + 6 files changed, 195 insertions(+), 346 deletions(-) diff --git a/mysql-test/include/get_rec_idx_ranges_from_opt_ctx.inc b/mysql-test/include/get_rec_idx_ranges_from_opt_ctx.inc index 7e0a363c8af34..24ff336242b5e 100644 --- a/mysql-test/include/get_rec_idx_ranges_from_opt_ctx.inc +++ b/mysql-test/include/get_rec_idx_ranges_from_opt_ctx.inc @@ -3,19 +3,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= - (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, - '$[*]' columns(file_stat_records text path '$')) as jt; -set @file_stat_records= - (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, - '$[*]' columns(file_stat_records text path '$')) as jt; -set @indexes= - (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); + +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( - @indexes, '$[*][*]' columns(index_name text path '$.index_name', - rec_per_key json path '$.rec_per_key')) as jt; + @table_contexts, + '$[*]' columns(table_name text path '$.name', + file_stat_records text path '$.file_stat_records', + index_name text path '$**.indexes[*].index_name', + rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; + set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -24,4 +21,5 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', - max_row_blocks int path '$.max_row_blocks')) as jt; + max_row_blocks int path '$.max_row_blocks' + )) as jt; diff --git a/mysql-test/main/opt_context_load_stats_basic.result b/mysql-test/main/opt_context_load_stats_basic.result index 6067be5f00656..00f9b89464258 100644 --- a/mysql-test/main/opt_context_load_stats_basic.result +++ b/mysql-test/main/opt_context_load_stats_basic.result @@ -31,30 +31,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["4"] -t1_idx_b ["3"] -t1_idx_ab [ - "4", - "1" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -63,14 +49,14 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks t1_idx_a ["(NULL) < (a) < (3)"] 12 1 1 t1_idx_b ["(6) < (b)"] 2 1 1 t1_idx_ab ["(NULL) < (a) < (3)"] 12 1 1 set @saved_opt_context_1=@opt_context; -set @saved_records_1=@records; -set @saved_indexes_1=@indexes; +set @saved_table_contexts= @table_contexts; set @saved_list_ranges_1=@list_ranges; # # load stats in JSON format into variable optimizer_replay_context @@ -129,21 +115,8 @@ from information_schema.optimizer_context); select JSON_EQUALS(@saved_opt_context_1, @opt_context); JSON_EQUALS(@saved_opt_context_1, @opt_context) 0 -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -set @saved_records_2 = @records; -set @saved_indexes_2 = @indexes; set @saved_list_ranges_2 = @list_ranges; -select JSON_EQUALS(@saved_records_2, @saved_records_1); -JSON_EQUALS(@saved_records_2, @saved_records_1) -0 -select * from json_table(@records, '$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -40 -select JSON_EQUALS(@saved_indexes_2, @saved_indexes_1); -JSON_EQUALS(@saved_indexes_2, @saved_indexes_1) -1 select JSON_EQUALS(@saved_list_ranges_2, @saved_list_ranges_1); JSON_EQUALS(@saved_list_ranges_2, @saved_list_ranges_1) 0 @@ -240,15 +213,7 @@ from information_schema.optimizer_context); select JSON_EQUALS(@saved_opt_context_1, @opt_context); JSON_EQUALS(@saved_opt_context_1, @opt_context) 0 -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -select JSON_EQUALS(@saved_records_2, @records); -JSON_EQUALS(@saved_records_2, @records) -1 -select JSON_EQUALS(@saved_indexes_2, @indexes); -JSON_EQUALS(@saved_indexes_2, @indexes) -1 select JSON_EQUALS(@saved_list_ranges_2, @list_ranges); JSON_EQUALS(@saved_list_ranges_2, @list_ranges) 1 @@ -273,23 +238,7 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -select JSON_EQUALS(@saved_records_2, @records); -JSON_EQUALS(@saved_records_2, @records) -1 -select JSON_EQUALS(@saved_indexes_2, @indexes); -JSON_EQUALS(@saved_indexes_2, @indexes) -0 -select * from json_table(@indexes, '$[*][*]' columns(index_name text path '$.index_name', rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["8"] -t1_idx_b ["5"] -t1_idx_ab [ - "8", - "2" - ] select JSON_EQUALS(@saved_list_ranges_2, @list_ranges); JSON_EQUALS(@saved_list_ranges_2, @list_ranges) 1 diff --git a/mysql-test/main/opt_context_load_stats_basic.test b/mysql-test/main/opt_context_load_stats_basic.test index e51597c98fae7..64e7710c2a233 100644 --- a/mysql-test/main/opt_context_load_stats_basic.test +++ b/mysql-test/main/opt_context_load_stats_basic.test @@ -34,8 +34,7 @@ select * from t1 where a < 3 and b > 6; --source include/get_rec_idx_ranges_from_opt_ctx.inc set @saved_opt_context_1=@opt_context; -set @saved_records_1=@records; -set @saved_indexes_1=@indexes; +set @saved_table_contexts= @table_contexts; set @saved_list_ranges_1=@list_ranges; --echo # @@ -79,17 +78,10 @@ select * from t1 where a < 3 and b > 6; select JSON_EQUALS(@saved_opt_context_1, @opt_context); -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -set @saved_records_2 = @records; -set @saved_indexes_2 = @indexes; set @saved_list_ranges_2 = @list_ranges; -select JSON_EQUALS(@saved_records_2, @saved_records_1); -select * from json_table(@records, '$[*]' columns(file_stat_records text path '$')) as jt; -select JSON_EQUALS(@saved_indexes_2, @saved_indexes_1); select JSON_EQUALS(@saved_list_ranges_2, @saved_list_ranges_1); select * from json_table( @list_ranges, @@ -153,12 +145,8 @@ select * from t1 where a < 3 and b > 6; select JSON_EQUALS(@saved_opt_context_1, @opt_context); -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -select JSON_EQUALS(@saved_records_2, @records); -select JSON_EQUALS(@saved_indexes_2, @indexes); select JSON_EQUALS(@saved_list_ranges_2, @list_ranges); --echo # @@ -174,13 +162,8 @@ select * from t1 where a < 3 and b > 6; --source include/get_opt_context.inc -set @records= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -set @indexes=(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); -select JSON_EQUALS(@saved_records_2, @records); -select JSON_EQUALS(@saved_indexes_2, @indexes); -select * from json_table(@indexes, '$[*][*]' columns(index_name text path '$.index_name', rec_per_key json path '$.rec_per_key')) as jt; select JSON_EQUALS(@saved_list_ranges_2, @list_ranges); set @saved_opt_context_2 = @opt_context; diff --git a/mysql-test/main/opt_context_store_stats.result b/mysql-test/main/opt_context_store_stats.result index 832e0b2bbcdb9..a760ae98811e5 100644 --- a/mysql-test/main/opt_context_store_stats.result +++ b/mysql-test/main/opt_context_store_stats.result @@ -39,30 +39,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["10"] -t1_idx_b ["7"] -t1_idx_ab [ - "10", - "3" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -71,7 +57,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks # # simple query using join of two tables @@ -84,33 +71,17 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t2_idx_a ["5"] -t1_idx_a ["10"] -t1_idx_b ["7"] -t1_idx_ab [ - "10", - "3" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t2 30 t2_idx_a ["5"] +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -119,7 +90,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks # # negative test @@ -135,22 +107,15 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -159,7 +124,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks set optimizer_record_context=ON; # @@ -172,33 +138,17 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t2_idx_a ["5"] -t1_idx_a ["10"] -t1_idx_b ["7"] -t1_idx_ab [ - "10", - "3" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t2 30 t2_idx_a ["5"] +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -207,7 +157,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks t2_idx_a ["(5) <= (a) <= (5)"] 5 1 1 t2_idx_a ["(5) <= (a) <= (5)"] 5 1 1 @@ -224,30 +175,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["10"] -t1_idx_b ["7"] -t1_idx_ab [ - "10", - "3" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -256,7 +193,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks # # test for insert as select @@ -267,33 +205,17 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -30 -20 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t2_idx_a ["5"] -t1_idx_a ["10"] -t1_idx_b ["7"] -t1_idx_ab [ - "10", - "3" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t2 30 t2_idx_a ["5"] +db1.t1 20 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -302,7 +224,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks analyze table t1 persistent for all; Table Op Msg_type Msg_text @@ -322,30 +245,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["8"] -t1_idx_b ["8"] -t1_idx_ab [ - "8", - "8" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 50 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -354,7 +263,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks t1_idx_a ["(1) <= (a) <= (5)"] 35 1 1 t1_idx_ab ["(1) <= (a) <= (5)"] 35 1 1 @@ -370,30 +280,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["8"] -t1_idx_b ["8"] -t1_idx_ab [ - "8", - "8" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 50 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -402,7 +298,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks t1_idx_a [ "(1) <= (a) <= (5)", @@ -424,22 +321,15 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -448,7 +338,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks set optimizer_record_context=ON; # @@ -463,30 +354,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -50 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -t1_idx_a ["8"] -t1_idx_b ["8"] -t1_idx_ab [ - "8", - "8" - ] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +db1.t1 50 NULL NULL set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -495,7 +372,8 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks t1_idx_a ["(1) <= (a) <= (5)"] 35 1 1 t1_idx_ab ["(1) <= (a) <= (5)"] 35 1 1 @@ -871,25 +749,16 @@ set @opt_context= context, '(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') from information_schema.optimizer_context); -set @records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -3 -set @file_stat_records= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.file_stat_records'))); -select *from json_table(@file_stat_records, -'$[*]' columns(file_stat_records text path '$')) as jt; -file_stat_records -3 -set @indexes= -(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.indexes'))); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); select *from json_table( -@indexes, '$[*][*]' columns(index_name text path '$.index_name', -rec_per_key json path '$.rec_per_key')) as jt; -index_name rec_per_key -a ["1"] +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +test.t1 3 a ["1"] set @list_ranges= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); select *from json_table( @@ -898,8 +767,43 @@ select *from json_table( ranges json path '$.ranges', num_rows int path '$.num_rows', max_index_blocks int path '$.max_index_blocks', -max_row_blocks int path '$.max_row_blocks')) as jt; +max_row_blocks int path '$.max_row_blocks' + )) as jt; index_name ranges num_rows max_index_blocks max_row_blocks drop function add1; DROP TABLE t1; set session use_stat_tables=@saved_use_stat_tables; +# +# MDEV-39433: Crash when selecting from a sequence with optimizer_record_context enabled +# +set optimizer_record_context=ON; +create sequence s1; +EXPLAIN select * from s1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s1 system NULL NULL NULL NULL 1 +set @opt_context= +(select REGEXP_SUBSTR( +context, +'(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') +from information_schema.optimizer_context); +set @table_contexts= (select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_contexts[*]'))); +select *from json_table( +@table_contexts, +'$[*]' columns(table_name text path '$.name', +file_stat_records text path '$.file_stat_records', +index_name text path '$**.indexes[*].index_name', +rec_per_key json path '$**.indexes[*].rec_per_key' + )) as jt; +table_name file_stat_records index_name rec_per_key +set @list_ranges= +(select JSON_DETAILED(JSON_EXTRACT(@opt_context, '$**.list_ranges'))); +select *from json_table( +@list_ranges, +'$[*][*]' columns(index_name text path '$.index_name', +ranges json path '$.ranges', +num_rows int path '$.num_rows', +max_index_blocks int path '$.max_index_blocks', +max_row_blocks int path '$.max_row_blocks' + )) as jt; +index_name ranges num_rows max_index_blocks max_row_blocks +drop table s1; diff --git a/mysql-test/main/opt_context_store_stats.test b/mysql-test/main/opt_context_store_stats.test index e71279c3db95d..0f7e996b3e6cd 100644 --- a/mysql-test/main/opt_context_store_stats.test +++ b/mysql-test/main/opt_context_store_stats.test @@ -421,3 +421,14 @@ explain select * from t1 where b < add1(3); drop function add1; DROP TABLE t1; set session use_stat_tables=@saved_use_stat_tables; + +--echo # +--echo # MDEV-39433: Crash when selecting from a sequence with optimizer_record_context enabled +--echo # +set optimizer_record_context=ON; + +create sequence s1; +EXPLAIN select * from s1; + +--source include/get_rec_idx_ranges_from_opt_ctx.inc +drop table s1; diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index 95cc2ed82b28b..7c67405fa9228 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -762,6 +762,10 @@ bool store_optimizer_context(THD *thd) qry_ctx_script.append(ddl); qry_ctx_script.append(STRING_WITH_LEN(";\n\n")); + // sequence table doesn't contain any stats + if (tbl->table && tbl->table->s && tbl->table->s->sequence) + continue; + if (!tbl->is_view()) { Json_writer_object ctx_wrapper(&ctx_writer);