Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 87 additions & 31 deletions sql/item_jsonfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -622,48 +622,92 @@ bool Item_func_json_equals::val_bool()
longlong result= 0;
int arg_num= 0;
String a_tmp, b_tmp;
String *a= nullptr, *b= nullptr;
THD *thd;
json_engine_t je;

if ((null_value= args[0]->null_value || args[1]->null_value))
return 1;

String *a= args[0]->val_json(&a_tmp);
if ((null_value= a == nullptr))
return 1;
String *b= args[1]->val_json(&b_tmp);
if ((null_value= b == nullptr))
return 1;

DYNAMIC_STRING a_res;
if (init_dynamic_string(&a_res, NULL, 0, 0))
thd= current_thd;
JSON_DO_PAUSE_EXECUTION(thd, 0.0002);
je.killed_ptr= (uint32_t *) &thd->killed;

/* Process First Argument */
if (args[0]->const_item() && a_parsed)
{
null_value= 1;
return 1;
if(a_null) goto return_null;
}

DYNAMIC_STRING b_res;
if (init_dynamic_string(&b_res, NULL, 0, 0))
else
{
a= args[0]->val_json(&a_tmp);
if (!a) goto set_a_null;
DYNAMIC_STRING a_res;
if (init_dynamic_string(&a_res, NULL, 0, 0)) goto set_a_null;

if (json_normalize_engine(&je, &a_res, a->ptr(), a->length(), a->charset()))
{
dynstr_free(&a_res);
goto set_a_null;
}

cached_a.copy(a_res.str, a_res.length, a->charset());
dynstr_free(&a_res);
null_value= 1;
return 1;
if (args[0]->const_item())
{
a_null= false;
a_parsed= true;
}
}

thd= current_thd;
JSON_DO_PAUSE_EXECUTION(thd, 0.0002);
je.killed_ptr= (uint32_t *) &thd->killed;
arg_num++;

if (json_normalize_engine(&je, &a_res, a->ptr(), a->length(), a->charset()))
goto return_null;
/* Process Second Argument */
if (args[1]->const_item() && b_parsed)
{
if(b_null) goto return_null;
}
else
{
b= args[1]->val_json(&b_tmp);
if (!b) goto set_b_null;
DYNAMIC_STRING b_res;
if (init_dynamic_string(&b_res, NULL, 0, 0)) goto set_b_null;

arg_num++;
if (json_normalize_engine(&je, &b_res, b->ptr(), b->length(), b->charset()))
goto return_null;
if (json_normalize_engine(&je, &b_res, b->ptr(), b->length(), b->charset()))
{
dynstr_free(&b_res);
goto set_b_null;
}

result= strcmp(a_res.str, b_res.str) ? 0 : 1;
cached_b.copy(b_res.str, b_res.length, b->charset());
dynstr_free(&b_res);
if (args[1]->const_item())
{
b_null= false;
b_parsed= true;
}
}

result= strcmp(cached_a.c_ptr_safe(), cached_b.c_ptr_safe()) ? 0 : 1;
goto end;

set_a_null:
if (args[0]->const_item())
{
a_null= true;
a_parsed= true;
}
goto return_null;

set_b_null:
if (args[1]->const_item())
{
b_null= true;
b_parsed= true;
}

return_null:
null_value= 1;

Expand All @@ -675,8 +719,6 @@ bool Item_func_json_equals::val_bool()
a= b;
report_json_error(a, &je, arg_num);
}
dynstr_free(&b_res);
dynstr_free(&a_res);
return result;
}

Expand Down Expand Up @@ -5053,10 +5095,26 @@ bool Item_func_json_overlaps::val_bool()
thd= current_thd;
JSON_DO_PAUSE_EXECUTION(thd, 0.0002);

if (!a2_parsed)
if (args[1]->const_item() && a2_parsed)
{
val= args[1]->val_json(&tmp_val);
a2_parsed= a2_constant;
val= (cached_val.is_alloced() || cached_val.length()) ? &cached_val : 0;
}
else
{
String *v= args[1]->val_json(&tmp_val);
if (v)
{
cached_val.copy(v->ptr(), v->length(), v->charset());
val= &cached_val;
}
else
{
cached_val.length(0);
val= 0;
}

if (args[1]->const_item())
a2_parsed= true;
}

if (val == 0)
Expand Down Expand Up @@ -5092,8 +5150,6 @@ bool Item_func_json_overlaps::val_bool()

bool Item_func_json_overlaps::fix_length_and_dec(THD *thd)
{
a2_constant= args[1]->const_item();
a2_parsed= FALSE;
set_maybe_null();

return Item_bool_func::fix_length_and_dec(thd);
Expand Down
21 changes: 17 additions & 4 deletions sql/item_jsonfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,12 @@ class Item_func_json_valid: public Item_bool_func

class Item_func_json_equals: public Item_bool_func
{
String cached_a, cached_b;
bool a_parsed, b_parsed;
bool a_null, b_null;
public:
Item_func_json_equals(THD *thd, Item *a, Item *b):
Item_bool_func(thd, a, b) {}
Item_bool_func(thd, a, b), a_parsed(false), b_parsed(false), a_null(false), b_null(false) {}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_equals") };
Expand All @@ -138,6 +141,11 @@ class Item_func_json_equals: public Item_bool_func
Item *shallow_copy(THD *thd) const override
{ return get_item_copy<Item_func_json_equals>(thd, this); }
bool val_bool() override;
void cleanup() override
{
a_parsed= b_parsed= false;
Item_bool_func::cleanup();
}
};


Expand Down Expand Up @@ -848,18 +856,23 @@ extern bool is_json_type(const Item *item);
class Item_func_json_overlaps: public Item_bool_func
{
String tmp_js;
bool a2_constant, a2_parsed;
String tmp_val, *val;
bool a2_parsed;
String tmp_val, cached_val, *val;
public:
Item_func_json_overlaps(THD *thd, Item *a, Item *b):
Item_bool_func(thd, a, b) {}
Item_bool_func(thd, a, b), a2_parsed(false) {}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_overlaps") };
return name;
}
bool fix_length_and_dec(THD *thd) override;
bool val_bool() override;
void cleanup() override
{
a2_parsed= false;
Item_bool_func::cleanup();
}
Item *shallow_copy(THD *thd) const override
{ return get_item_copy<Item_func_json_overlaps>(thd, this); }
};
Expand Down