diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2019-09-04 04:29:03 +1000 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2020-07-21 16:18:00 +1000 |
commit | 5acd391e8b2d4d760ae7f96a59413c9ea247e9b1 (patch) | |
tree | 7c76c0dace6ba4cc0c4f1dd4c855c9b8688878fa /sql/item.cc | |
parent | ca9276e37ea29468406d5ec7c17d2ad5c032637f (diff) | |
download | mariadb-git-5acd391e8b2d4d760ae7f96a59413c9ea247e9b1.tar.gz |
MDEV-16039 Crash when selecting virtual columns generated using functions with DAYNAME()
* Allocate items on thd->mem_root while refixing vcol exprs
* Make vcol tree changes register and roll them back after the statement is executed.
Explanation:
Due to collation implementation specifics an Item tree could change while fixing.
The tricky thing here is to make it on a proper arena.
It's usually not a problem when a field is deterministic, however, makes a pain vice-versa, during allocation allocating.
A non-deterministic field should be refixed on each statement, since it depends on the environment state.
Changing the tree will be temporary and therefore it should be reverted after the statement execution.
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 27 |
1 files changed, 3 insertions, 24 deletions
diff --git a/sql/item.cc b/sql/item.cc index 9451d4203ca..644bef7524a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2325,14 +2325,7 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll, bool res= FALSE; uint i; - /* - In case we're in statement prepare, create conversion item - in its memory: it will be reused on each execute. - */ - Query_arena backup; - Query_arena *arena= thd->stmt_arena->is_stmt_prepare() ? - thd->activate_stmt_arena_if_needed(&backup) : - NULL; + DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare()); for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { @@ -2354,20 +2347,8 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll, res= TRUE; break; // we cannot return here, we need to restore "arena". } - /* - If in statement prepare, then we create a converter for two - constant items, do it once and then reuse it. - If we're in execution of a prepared statement, arena is NULL, - and the conv was created in runtime memory. This can be - the case only if the argument is a parameter marker ('?'), - because for all true constants the charset converter has already - been created in prepare. In this case register the change for - rollback. - */ - if (thd->stmt_arena->is_stmt_prepare()) - *arg= conv; - else - thd->change_item_tree(arg, conv); + + thd->change_item_tree(arg, conv); if (conv->fix_fields(thd, arg)) { @@ -2375,8 +2356,6 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll, break; // we cannot return here, we need to restore "arena". } } - if (arena) - thd->restore_active_arena(arena, &backup); return res; } |