diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2019-04-17 15:50:59 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2022-01-24 14:41:06 +0100 |
commit | 349283c5e7a3a338445140156e866d6ade939edf (patch) | |
tree | ee5f87b18649f9b4ac55239bce87826c0f06bc31 /sql/table.cc | |
parent | ecfa9361406f9007af8a808567909a519aa9984b (diff) | |
download | mariadb-git-bb-10.2-MDEV-17124.tar.gz |
MDEV-17124: mariadb 10.1.34, views and prepared statements: ERROR 1615 (HY000): Prepared statement needs to be re-preparedbb-10.2-MDEV-17124
The problem is that if table definition cache (TDC) is full of real tables
which are in tables cache, view definition can not stay there so will be
removed by its own underlying tables.
In situation above old mechanism of detection matching definition in PS
and current version always require reprepare and so prevent executing
the PS.
One work around is to increase TDC, other - improve version check for
views/triggers (which is done here). Now in suspicious cases we check:
- timestamp (ms) of the view to be sure that version really have changed;
- time (ms) of creation of a trigger related to time (ms) of statement
preparation.
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/sql/table.cc b/sql/table.cc index ca6ce02e4f2..24412966b36 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8480,6 +8480,53 @@ bool TABLE_LIST::is_with_table() } +bool TABLE_LIST::is_table_ref_id_equal(THD* thd, TABLE_SHARE *s) +{ + enum enum_table_ref_type tp= s->get_table_ref_type(); + if (m_table_ref_type == tp) + { + bool res= m_table_ref_version == s->get_table_ref_version(); + + /* + If definition is different check content version + */ + if (tabledef_version.length && + tabledef_version.length == s->tabledef_version.length && + memcmp(tabledef_version.str, s->tabledef_version.str, + tabledef_version.length) == 0) + { + if (table && table->triggers) + { + + ulonglong ms_stmt_prepare= thd->ms_prepare_time; + if (ms_stmt_prepare) + for(uint i= 0; i < TRG_EVENT_MAX; i++) + for (uint j= 0; j < TRG_ACTION_MAX; j++) + { + Trigger *tr= + table->triggers->get_trigger((trg_event_type)i, + (trg_action_time_type)j); + if (tr) + if (ms_stmt_prepare <= tr->ms_create_time) + { + set_tabledef_version(s); + return FALSE; + } + } + } + set_table_id(s); + return TRUE; + } + else + tabledef_version.length= 0; + return res; + } + else + set_tabledef_version(s); + return FALSE; +} + + uint TABLE_SHARE::actual_n_key_parts(THD *thd) { return use_ext_keys && |