From f65ba9aeb7eea75656c74da7c20cb4157cb8d943 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 17 Apr 2019 15:50:59 +0200 Subject: MDEV-17124: mariadb 10.1.34, views and prepared statements: ERROR 1615 (HY000): Prepared statement needs to be re-prepared 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 (microseconds) of the view to be sure that version really have changed; - time (microseconds) of creation of a trigger related to time (microseconds) of statement preparation. --- sql/sql_trigger.cc | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'sql/sql_trigger.cc') diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 247055d397c..375b2e12d65 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -37,6 +37,8 @@ #ifdef WITH_WSREP #include "debug_sync.h" #endif /* WITH_WSREP */ +#include +#include LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str, const char* str, size_t length, @@ -212,7 +214,7 @@ static File_option triggers_file_parameters[]= }, { { STRING_WITH_LEN("created") }, - my_offsetof(class Table_triggers_list, create_times), + my_offsetof(class Table_triggers_list, hr_create_times), FILE_OPTIONS_ULLLIST }, { { 0, 0 }, 0, FILE_OPTIONS_STRING } @@ -896,6 +898,10 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, if (!(trigger= new (&table->mem_root) Trigger(this, 0))) goto err_without_cleanup; + /* Time with in microseconds */ + trigger->hr_create_time= make_hr_time(thd->query_start(), + thd->query_start_sec_part()); + /* Create trigger_name.TRN file to ensure trigger name is unique */ if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, (uchar*)&trigname, trigname_file_parameters)) @@ -904,8 +910,6 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Populate the trigger object */ trigger->sql_mode= thd->variables.sql_mode; - /* Time with 2 decimals, like in MySQL 5.7 */ - trigger->create_time= ((ulonglong) thd->query_start())*100 + thd->query_start_sec_part()/10000; build_trig_stmt_query(thd, tables, stmt_query, &trigger_definition, &trigger->definer, trg_definer_holder); @@ -973,7 +977,7 @@ void Table_triggers_list::empty_lists() client_cs_names.empty(); connection_cl_names.empty(); db_cl_names.empty(); - create_times.empty(); + hr_create_times.empty(); } @@ -1009,7 +1013,7 @@ bool Trigger::add_to_file_list(void* param_arg) base->client_cs_names.push_back(&client_cs_name, mem_root) || base->connection_cl_names.push_back(&connection_cl_name, mem_root) || base->db_cl_names.push_back(&db_cl_name, mem_root) || - base->create_times.push_back(&create_time, mem_root)) + base->hr_create_times.push_back(&hr_create_time.val, mem_root)) return 1; return 0; } @@ -1391,7 +1395,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, List_iterator_fast it_client_cs_name(trigger_list->client_cs_names); List_iterator_fast it_connection_cl_name(trigger_list->connection_cl_names); List_iterator_fast it_db_cl_name(trigger_list->db_cl_names); - List_iterator_fast it_create_times(trigger_list->create_times); + List_iterator_fast + it_create_times(trigger_list->hr_create_times); LEX *old_lex= thd->lex; LEX lex; sp_rcontext *save_spcont= thd->spcont; @@ -1477,7 +1482,14 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, trigger->sql_mode= sql_mode; trigger->definition= *trg_create_str; - trigger->create_time= trg_create_time ? *trg_create_time : 0; + trigger->hr_create_time= + my_hrtime_t({trg_create_time ? *trg_create_time : 0}); + /* + Fix time if in 100th of second (comparison with max uint * 100 + (max possible timestamp in the old format)) + */ + if (trigger->hr_create_time.val < 429496729400ULL) + trigger->hr_create_time.val*= 10000; trigger->name= sp ? sp->m_name : empty_clex_str; trigger->on_table_name.str= (char*) lex.raw_trg_on_table_name_begin; trigger->on_table_name.length= (lex.raw_trg_on_table_name_end - -- cgit v1.2.1 From fa6d7e4e9897cd80dfddb855f4336fca4d002dcc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Oct 2022 16:11:13 +0200 Subject: compilation error extended initializers are only allowed since c++11 --- sql/sql_trigger.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sql/sql_trigger.cc') diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 375b2e12d65..f01efd84528 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1482,8 +1482,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, trigger->sql_mode= sql_mode; trigger->definition= *trg_create_str; - trigger->hr_create_time= - my_hrtime_t({trg_create_time ? *trg_create_time : 0}); + trigger->hr_create_time.val= trg_create_time ? *trg_create_time : 0; /* Fix time if in 100th of second (comparison with max uint * 100 (max possible timestamp in the old format)) -- cgit v1.2.1