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

MDEV-24909 JSON functions don't respect KILL QUERY / max_statement_time limit

pass the pointer to thd->killed down to the json library,
check it while scanning,
use thd->check_killed() to generate the proper error message
This commit is contained in:
Sergei Golubchik
2021-07-02 19:13:26 +02:00
parent bae9fb5904
commit bc10f58a58
5 changed files with 115 additions and 3 deletions

View File

@@ -240,7 +240,7 @@ handle_value:
};
} while (json_scan_next(je) == 0);
return je->s.error;
return je->s.error || *je->killed_ptr;
error:
return 1;
@@ -1653,6 +1653,7 @@ String *Item_func_json_array_append::val_str(String *str)
uint n_arg, n_path;
size_t str_rest_len;
const uchar *ar_end;
THD *thd= current_thd;
DBUG_ASSERT(fixed());
@@ -1680,6 +1681,7 @@ String *Item_func_json_array_append::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
c_path->cur_step= c_path->p.steps;
@@ -1760,6 +1762,7 @@ String *Item_func_json_array_append::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je, str, Item_func_json_format::LOOSE))
goto js_error;
@@ -1769,6 +1772,7 @@ js_error:
report_json_error(js, &je, 0);
return_null:
thd->check_killed(); // to get the error message right
null_value= 1;
return 0;
}
@@ -1779,6 +1783,7 @@ String *Item_func_json_array_insert::val_str(String *str)
json_engine_t je;
String *js= args[0]->val_json(&tmp_js);
uint n_arg, n_path;
THD *thd= current_thd;
DBUG_ASSERT(fixed());
@@ -1816,6 +1821,7 @@ String *Item_func_json_array_insert::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
c_path->cur_step= c_path->p.steps;
@@ -1855,7 +1861,7 @@ String *Item_func_json_array_insert::val_str(String *str)
goto js_error;
}
if (unlikely(je.s.error))
if (unlikely(je.s.error || *je.killed_ptr))
goto js_error;
str->length(0);
@@ -1899,6 +1905,7 @@ String *Item_func_json_array_insert::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je, str, Item_func_json_format::LOOSE))
goto js_error;
@@ -1907,6 +1914,7 @@ String *Item_func_json_array_insert::val_str(String *str)
js_error:
report_json_error(js, &je, 0);
return_null:
thd->check_killed(); // to get the error message right
null_value= 1;
return 0;
}
@@ -2165,6 +2173,7 @@ String *Item_func_json_merge::val_str(String *str)
json_engine_t je1, je2;
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
uint n_arg;
THD *thd= current_thd;
LINT_INIT(js2);
if (args[0]->null_value)
@@ -2181,9 +2190,11 @@ String *Item_func_json_merge::val_str(String *str)
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
(const uchar *) js1->ptr() + js1->length());
je1.killed_ptr= (uchar*)&thd->killed;
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
(const uchar *) js2->ptr() + js2->length());
je2.killed_ptr= (uchar*)&thd->killed;
if (do_merge(str, &je1, &je2))
goto error_return;
@@ -2205,6 +2216,7 @@ String *Item_func_json_merge::val_str(String *str)
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
(const uchar *) js1->ptr() + js1->length());
je1.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
goto error_return;
@@ -2216,6 +2228,7 @@ error_return:
report_json_error(js1, &je1, 0);
if (je2.s.error)
report_json_error(js2, &je2, n_arg);
thd->check_killed(); // to get the error message right
null_return:
null_value= 1;
return NULL;
@@ -2465,6 +2478,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
uint n_arg;
bool empty_result, merge_to_null;
THD *thd= current_thd;
/* To report errors properly if some JSON is invalid. */
je1.s.error= je2.s.error= 0;
@@ -2481,6 +2495,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
(const uchar *) js2->ptr() + js2->length());
je2.killed_ptr= (uchar*)&thd->killed;
if (merge_to_null)
{
@@ -2502,6 +2517,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
(const uchar *) js1->ptr() + js1->length());
je1.killed_ptr= (uchar*)&thd->killed;
if (do_merge_patch(str, &je1, &je2, &empty_result))
goto error_return;
@@ -2530,6 +2546,7 @@ cont_point:
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
(const uchar *) js1->ptr() + js1->length());
je1.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
goto error_return;
@@ -2541,6 +2558,7 @@ error_return:
report_json_error(js1, &je1, 0);
if (je2.s.error)
report_json_error(js2, &je2, n_arg);
thd->check_killed(); // to get the error message right
null_return:
null_value= 1;
return NULL;
@@ -2777,6 +2795,7 @@ String *Item_func_json_insert::val_str(String *str)
String *js= args[0]->val_json(&tmp_js);
uint n_arg, n_path;
json_string_t key_name;
THD *thd= current_thd;
DBUG_ASSERT(fixed());
@@ -2817,6 +2836,7 @@ String *Item_func_json_insert::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (c_path->p.last_step < c_path->p.steps)
goto v_found;
@@ -2998,6 +3018,7 @@ continue_point:
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je, str, Item_func_json_format::LOOSE))
goto js_error;
@@ -3005,6 +3026,7 @@ continue_point:
js_error:
report_json_error(js, &je, 0);
thd->check_killed(); // to get the error message right
return_null:
null_value= 1;
return 0;
@@ -3028,6 +3050,7 @@ String *Item_func_json_remove::val_str(String *str)
String *js= args[0]->val_json(&tmp_js);
uint n_arg, n_path;
json_string_t key_name;
THD *thd= current_thd;
DBUG_ASSERT(fixed());
@@ -3074,6 +3097,7 @@ String *Item_func_json_remove::val_str(String *str)
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
c_path->cur_step= c_path->p.steps;
@@ -3182,6 +3206,7 @@ v_found:
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je, str, Item_func_json_format::LOOSE))
goto js_error;
@@ -3189,6 +3214,7 @@ v_found:
return str;
js_error:
thd->check_killed(); // to get the error message right
report_json_error(js, &je, 0);
null_return:
null_value= 1;
@@ -3579,6 +3605,7 @@ String *Item_func_json_format::val_str(String *str)
String *js= args[0]->val_json(&tmp_js);
json_engine_t je;
int tab_size= 4;
THD *thd= current_thd;
if ((null_value= args[0]->null_value))
return 0;
@@ -3602,11 +3629,13 @@ String *Item_func_json_format::val_str(String *str)
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
(const uchar *) js->ptr()+js->length());
je.killed_ptr= (uchar*)&thd->killed;
if (json_nice(&je, str, fmt, tab_size))
{
null_value= 1;
report_json_error(js, &je, 0);
thd->check_killed(); // to get the error message right
return 0;
}