Skip to content

Commit 509e40e

Browse files
committed
MDEV-30518: JSON functions cannot be killed on big-endian
The json_engine killed_ptr was of type uchar however the enum in the server is dependant on the architecture. On big-endian architectures like IBM Z, retreiving a uchar* retreived the unmodifed part of the THD->kill enum location and was always 0. As C++11 allows enums to inherit a type, used uint32_t as the base class of killed_state type in the server and used uint32_t in the json library. reload_acl_and_cache required an expression change to avoid the compile error: sql/sql_reload.cc:472:24: error: enumerated and non-enumerated type in conditional expression [-Werror=enum-conversion] 472 | return result || (thd ? thd->killed : 0); Added the kill_ptr assignment the following functions can be killed: * Item_func_json_depth::val_int * Item_func_json_type::val_str * Item_func_json_length::val_int Item_func_json_array_append::val_str, check_killed() only applied to json_error: label and not return_null. Item_func_json_overlaps::val_bool ensure check_killed() is called. Item_func_json_format::val_str(), corresponding to the SQL, json_compact, json_detailed, json_loose - add debug instrumentation for the func_json_notembedded test. MDEV-26726 (fcd345d) added a json_pause_execution sync point however the test case used debug_max_statement_time, which doesn't exist. Fix the sync point name in the test.
1 parent c3f9ddf commit 509e40e

7 files changed

Lines changed: 34 additions & 23 deletions

File tree

include/json_lib.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define JSON_LIB_INCLUDED
33

44
#include <my_sys.h>
5+
#include <stdint.h>
56

67
#ifdef __cplusplus
78
extern "C" {
@@ -228,7 +229,7 @@ typedef struct st_json_engine_t
228229

229230
int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */
230231
int stack_p; /* The 'stack' pointer. */
231-
volatile uchar *killed_ptr;
232+
volatile const uint32_t *killed_ptr;
232233
} json_engine_t;
233234

234235

mysql-test/main/func_json_notembedded.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ length(@obj) length(@arr)
1111
5000009 5000009
1212
set max_statement_time=0.0001;
1313
SET @old_debug= @@debug_dbug;
14-
SET debug_dbug='+d,debug_max_statement_time exceeded';
14+
SET debug_dbug='+d,json_pause_execution';
1515
select json_array_append(@arr, '$[0]', 1);
1616
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
1717
select json_array_insert(@arr, '$[0]', 1);

mysql-test/main/func_json_notembedded.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ select length(@obj), length(@arr);
1818
set max_statement_time=0.0001;
1919
disable_abort_on_error;
2020
SET @old_debug= @@debug_dbug;
21-
SET debug_dbug='+d,debug_max_statement_time exceeded';
21+
SET debug_dbug='+d,json_pause_execution';
2222
select json_array_append(@arr, '$[0]', 1);
2323
select json_array_insert(@arr, '$[0]', 1);
2424
select json_insert(@obj, '$.meta', 1);

sql/item_jsonfunc.cc

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,7 +2119,7 @@ String *Item_func_json_array_append::val_str(String *str)
21192119

21202120
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
21212121
(const uchar *) js->ptr() + js->length());
2122-
je.killed_ptr= (uchar*)&thd->killed;
2122+
je.killed_ptr= (uint32_t *) &thd->killed;
21232123

21242124
c_path->cur_step= c_path->p.steps;
21252125

@@ -2200,17 +2200,17 @@ String *Item_func_json_array_append::val_str(String *str)
22002200

22012201
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
22022202
(const uchar *) js->ptr() + js->length());
2203-
je.killed_ptr= (uchar*)&thd->killed;
2203+
je.killed_ptr= (uint32_t *) &thd->killed;
22042204
if (json_nice(&je, str, Item_func_json_format::LOOSE))
22052205
goto js_error;
22062206

22072207
return str;
22082208

22092209
js_error:
22102210
report_json_error(js, &je, 0);
2211+
thd->check_killed(); // to get the error message right
22112212

22122213
return_null:
2213-
thd->check_killed(); // to get the error message right
22142214
null_value= 1;
22152215
return 0;
22162216
}
@@ -2263,7 +2263,7 @@ String *Item_func_json_array_insert::val_str(String *str)
22632263

22642264
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
22652265
(const uchar *) js->ptr() + js->length());
2266-
je.killed_ptr= (uchar*)&thd->killed;
2266+
je.killed_ptr= (uint32_t *) &thd->killed;
22672267

22682268
c_path->cur_step= c_path->p.steps;
22692269

@@ -2399,7 +2399,7 @@ String *Item_func_json_array_insert::val_str(String *str)
23992399

24002400
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
24012401
(const uchar *) js->ptr() + js->length());
2402-
je.killed_ptr= (uchar*)&thd->killed;
2402+
je.killed_ptr= (uint32_t *) &thd->killed;
24032403
if (json_nice(&je, str, Item_func_json_format::LOOSE))
24042404
goto js_error;
24052405

@@ -2690,11 +2690,11 @@ String *Item_func_json_merge::val_str(String *str)
26902690

26912691
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
26922692
(const uchar *) js1->ptr() + js1->length());
2693-
je1.killed_ptr= (uchar*)&thd->killed;
2693+
je1.killed_ptr= (uint32_t *) &thd->killed;
26942694

26952695
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
26962696
(const uchar *) js2->ptr() + js2->length());
2697-
je2.killed_ptr= (uchar*)&thd->killed;
2697+
je2.killed_ptr= (uint32_t *) &thd->killed;
26982698

26992699
if (do_merge(str, &je1, &je2))
27002700
goto error_return;
@@ -2716,7 +2716,8 @@ String *Item_func_json_merge::val_str(String *str)
27162716

27172717
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
27182718
(const uchar *) js1->ptr() + js1->length());
2719-
je1.killed_ptr= (uchar*)&thd->killed;
2719+
je1.killed_ptr= (uint32_t *) &thd->killed;
2720+
27202721
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
27212722
goto error_return;
27222723

@@ -2823,6 +2824,7 @@ static int do_merge_patch(String *str, json_engine_t *je1, json_engine_t *je2,
28232824

28242825
if (str->append('{'))
28252826
return 3;
2827+
28262828
while (json_scan_next(je1) == 0 &&
28272829
je1->state != JST_OBJ_END)
28282830
{
@@ -3002,7 +3004,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
30023004

30033005
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
30043006
(const uchar *) js2->ptr() + js2->length());
3005-
je2.killed_ptr= (uchar*)&thd->killed;
3007+
je2.killed_ptr= (uint32_t *) &thd->killed;
30063008

30073009
if (merge_to_null)
30083010
{
@@ -3022,7 +3024,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
30223024

30233025
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
30243026
(const uchar *) js1->ptr() + js1->length());
3025-
je1.killed_ptr= (uchar*)&thd->killed;
3027+
je1.killed_ptr= (uint32_t *) &thd->killed;
30263028

30273029
if (do_merge_patch(str, &je1, &je2, &empty_result))
30283030
goto error_return;
@@ -3051,7 +3053,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
30513053

30523054
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
30533055
(const uchar *) js1->ptr() + js1->length());
3054-
je1.killed_ptr= (uchar*)&thd->killed;
3056+
je1.killed_ptr= (uint32_t *) &thd->killed;
30553057
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
30563058
goto error_return;
30573059

@@ -3093,6 +3095,7 @@ longlong Item_func_json_length::val_int()
30933095

30943096
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
30953097
(const uchar *) js->ptr() + js->length());
3098+
je.killed_ptr= (uint32_t *) &current_thd->killed;
30963099

30973100
if (arg_count > 1)
30983101
{
@@ -3158,6 +3161,7 @@ longlong Item_func_json_length::val_int()
31583161

31593162
err_return:
31603163
report_json_error(js, &je, 0);
3164+
current_thd->check_killed(); // to get the error message right
31613165
null_return:
31623166
null_value= 1;
31633167
return 0;
@@ -3177,6 +3181,7 @@ longlong Item_func_json_depth::val_int()
31773181

31783182
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
31793183
(const uchar *) js->ptr() + js->length());
3184+
je.killed_ptr= (uint32_t *) &current_thd->killed;
31803185

31813186
do
31823187
{
@@ -3211,6 +3216,7 @@ longlong Item_func_json_depth::val_int()
32113216
return depth;
32123217

32133218
report_json_error(js, &je, 0);
3219+
current_thd->check_killed(); // to get the error message right
32143220
null_value= 1;
32153221
return 0;
32163222
}
@@ -3237,6 +3243,7 @@ String *Item_func_json_type::val_str(String *str)
32373243

32383244
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
32393245
(const uchar *) js->ptr() + js->length());
3246+
je.killed_ptr= (uint32_t *) &current_thd->killed;
32403247

32413248
if (json_read_value(&je))
32423249
goto error;
@@ -3275,6 +3282,7 @@ String *Item_func_json_type::val_str(String *str)
32753282

32763283
error:
32773284
report_json_error(js, &je, 0);
3285+
current_thd->check_killed();
32783286
null_value= 1;
32793287
return 0;
32803288
}
@@ -3355,7 +3363,7 @@ String *Item_func_json_insert::val_str(String *str)
33553363

33563364
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
33573365
(const uchar *) js->ptr() + js->length());
3358-
je.killed_ptr= (uchar*)&thd->killed;
3366+
je.killed_ptr= (uint32_t *) &thd->killed;
33593367

33603368
if (c_path->p.last_step < c_path->p.steps)
33613369
goto v_found;
@@ -3545,7 +3553,7 @@ String *Item_func_json_insert::val_str(String *str)
35453553

35463554
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
35473555
(const uchar *) js->ptr() + js->length());
3548-
je.killed_ptr= (uchar*)&thd->killed;
3556+
je.killed_ptr= (uint32_t *) &thd->killed;
35493557
if (json_nice(&je, str, Item_func_json_format::LOOSE))
35503558
goto js_error;
35513559

@@ -3626,7 +3634,7 @@ String *Item_func_json_remove::val_str(String *str)
36263634

36273635
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
36283636
(const uchar *) js->ptr() + js->length());
3629-
je.killed_ptr= (uchar*)&thd->killed;
3637+
je.killed_ptr= (uint32_t *) &thd->killed;
36303638

36313639
c_path->cur_step= c_path->p.steps;
36323640

@@ -3747,7 +3755,7 @@ String *Item_func_json_remove::val_str(String *str)
37473755

37483756
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
37493757
(const uchar *) js->ptr() + js->length());
3750-
je.killed_ptr= (uchar*)&thd->killed;
3758+
je.killed_ptr= (uint32_t *) &thd->killed;
37513759
if (json_nice(&je, str, Item_func_json_format::LOOSE))
37523760
goto js_error;
37533761

@@ -4187,6 +4195,7 @@ String *Item_func_json_format::val_str(String *str)
41874195
int tab_size= 4;
41884196
THD *thd= current_thd;
41894197

4198+
JSON_DO_PAUSE_EXECUTION(thd, 0.0002);
41904199
if ((null_value= args[0]->null_value))
41914200
return 0;
41924201

@@ -4209,7 +4218,7 @@ String *Item_func_json_format::val_str(String *str)
42094218

42104219
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
42114220
(const uchar *) js->ptr()+js->length());
4212-
je.killed_ptr= (uchar*)&thd->killed;
4221+
je.killed_ptr= (uint32_t *) &thd->killed;
42134222

42144223
if (json_nice(&je, str, fmt, tab_size))
42154224
{
@@ -4983,6 +4992,7 @@ bool Item_func_json_overlaps::val_bool()
49834992
report_json_error(js, &je, 0);
49844993
if (ve.s.error)
49854994
report_json_error(val, &ve, 1);
4995+
current_thd->check_killed(); // to get the error message right
49864996
return 0;
49874997
}
49884998

sql/sql_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ extern const LEX_CSTRING Diag_condition_item_names[];
613613
These states are bit coded with HARD. For each state there must be a pair
614614
<state_even_num>, and <state_odd_num>_HARD.
615615
*/
616-
enum killed_state
616+
enum killed_state : uint32_t
617617
{
618618
NOT_KILLED= 0,
619619
KILL_HARD_BIT= 1, /* Bit for HARD KILL */

sql/sql_reload.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
469469
/*
470470
If the query was killed then this function must fail.
471471
*/
472-
return result || (thd ? thd->killed : 0);
472+
return result || (thd ? thd->killed > NOT_KILLED : 0);
473473
}
474474

475475

strings/json_lib.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,13 +807,13 @@ static json_state_handler json_actions[NR_JSON_STATES][NR_C_CLASSES]=
807807
int json_scan_start(json_engine_t *je,
808808
CHARSET_INFO *i_cs, const uchar *str, const uchar *end)
809809
{
810-
static const uchar no_time_to_die= 0;
810+
static const uint32_t no_time_to_die= 0;
811811

812812
json_string_setup(&je->s, i_cs, str, end);
813813
je->stack[0]= JST_DONE;
814814
je->stack_p= 0;
815815
je->state= JST_VALUE;
816-
je->killed_ptr = (uchar*)&no_time_to_die;
816+
je->killed_ptr= (uint32_t *) &no_time_to_die;
817817
return 0;
818818
}
819819

0 commit comments

Comments
 (0)