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/table.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/table.cc')
-rw-r--r-- | sql/table.cc | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sql/table.cc b/sql/table.cc index 5ba996b746d..6e8c9aab12e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -47,6 +47,17 @@ #define MYSQL57_GENERATED_FIELD 128 #define MYSQL57_GCOL_HEADER_SIZE 4 +class Table_arena: public Query_arena +{ +public: + Table_arena(MEM_ROOT *mem_root, enum enum_state state_arg) : + Query_arena(mem_root, state_arg){} + virtual Type type() const + { + return Type::TABLE; + } +}; + static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *, TABLE *, String *, Virtual_column_info **, bool *); static bool check_vcol_forward_refs(Field *, Virtual_column_info *); @@ -1020,8 +1031,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, We need to use CONVENTIONAL_EXECUTION here to ensure that any new items created by fix_fields() are not reverted. */ - table->expr_arena= new (alloc_root(mem_root, sizeof(Query_arena))) - Query_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION); + table->expr_arena= new (alloc_root(mem_root, sizeof(Table_arena))) + Table_arena(mem_root, + Query_arena::STMT_CONVENTIONAL_EXECUTION); if (!table->expr_arena) DBUG_RETURN(1); |