summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-07-26 12:04:21 +0400
committerAlexander Barkov <bar@mariadb.com>2018-07-26 13:05:22 +0400
commit5c5a116b47020e7ed79a59d4d2ced69a686ff090 (patch)
tree80ee4f67d2ab610f0ac52531fe25e0636c53a3ea /sql
parent3c141e319ab29afdfe843553da385fe5d981906e (diff)
downloadmariadb-git-5c5a116b47020e7ed79a59d4d2ced69a686ff090.tar.gz
MDEV-16614 signal 7 after calling stored procedure, that uses regexp
The problem happened in the derived condition pushdown code: - When Item_func_regex::build_clone() was called, it created a copy of the original Item_func_regex, and this copy got registered in free_list. Class specific additional dynamic members (such as "re") made a shallow copy, rather than a deep copy, in the cloned Item_func_regex. As a result, the Regexp_processor_pcre::m_pcre of the cloned Item_func_regex and of the original Item_func_regex pointed to the same compiled regular expression. - On cleanup_items(), both original and cloned copies of Item_func_regex called re.cleanup(), which called pcre_free(m_pcre). So the same compiled regular expression was freed two times, which was noticed by ASAN. The same problem was repeatable for Item_func_regexp_instr. A similar problem happened for Item_func_sp, for the sp_result_field member. Both original and cloned copies of Item_func_sp pointed the same Field instance and both deleted it on cleanup(). A possible solution would be to fix build_clone() to create deep (instead of shallow) copies for the dynamic members of the affected classes (Item_func_regex, Item_func_regexp_instr, Item_func sp). However, this would be too complex. As agreed with Galina and Igor, this patch disallows using using these affected classes in derived condition pushdown by overriding get_clone() to return NULL.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_func.h10
2 files changed, 3 insertions, 21 deletions
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index a59432058eb..41a51ee8d12 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2117,16 +2117,7 @@ public:
bool fix_length_and_dec();
const char *func_name() const { return "regexp"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regex>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
- {
- Item_func_regex *clone= (Item_func_regex*) Item_bool_func::build_clone(thd, mem_root);
- if (clone)
- clone->re.reset();
- return clone;
- }
-
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
void print(String *str, enum_query_type query_type)
{
print_op(str, query_type);
@@ -2154,8 +2145,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
bool fix_length_and_dec();
const char *func_name() const { return "regexp_instr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
diff --git a/sql/item_func.h b/sql/item_func.h
index 0969cf2e3f0..4652f2c2d31 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -2439,15 +2439,7 @@ public:
{
return TRUE;
}
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_sp>(thd, mem_root, this); }
- Item *build_clone(THD *thd, MEM_ROOT *mem_root)
- {
- Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd, mem_root);
- if (clone)
- clone->sp_result_field= NULL;
- return clone;
- }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
bool eval_not_null_tables(void *opt_arg)
{
not_null_tables_cache= 0;