Loading sql/mysql_priv.h +6 −6 Original line number Diff line number Diff line Loading @@ -700,14 +700,14 @@ const char *set_thd_proc_info(THD *thd, const char *info, @sa Prepared_statement::reprepare() */ enum enum_metadata_type enum enum_table_ref_type { /** Initial value set by the parser */ METADATA_NULL= 0, METADATA_VIEW, METADATA_BASE_TABLE, METADATA_I_S_TABLE, METADATA_TMP_TABLE TABLE_REF_NULL= 0, TABLE_REF_VIEW, TABLE_REF_BASE_TABLE, TABLE_REF_I_S_TABLE, TABLE_REF_TMP_TABLE }; /* Loading sql/sp_head.cc +3 −3 Original line number Diff line number Diff line Loading @@ -1068,7 +1068,7 @@ sp_head::execute(THD *thd) LEX *old_lex; Item_change_list old_change_list; String old_packet; Metadata_version_observer *save_metadata_observer= thd->m_metadata_observer; Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; Object_creation_ctx *saved_creation_ctx; Loading Loading @@ -1154,7 +1154,7 @@ sp_head::execute(THD *thd) of substatements (Bug#12257, Bug#27011, Bug#32868, Bug#33000), but it's not implemented yet. */ thd->m_metadata_observer= 0; thd->m_reprepare_observer= 0; /* It is also more efficient to save/restore current thd->lex once when Loading Loading @@ -1317,7 +1317,7 @@ sp_head::execute(THD *thd) thd->derived_tables= old_derived_tables; thd->variables.sql_mode= save_sql_mode; thd->abort_on_warning= save_abort_on_warning; thd->m_metadata_observer= save_metadata_observer; thd->m_reprepare_observer= save_reprepare_observer; thd->stmt_arena= old_arena; state= EXECUTED; Loading sql/sql_base.cc +9 −9 Original line number Diff line number Diff line Loading @@ -3737,8 +3737,8 @@ void assign_new_table_id(TABLE_SHARE *share) @sa Execute_observer @sa check_prepared_statement() to see cases when an observer is installed @sa TABLE_LIST::is_metadata_id_equal() @sa TABLE_SHARE::get_metadata_id() @sa TABLE_LIST::is_table_ref_id_equal() @sa TABLE_SHARE::get_table_ref_id() @param[in] thd used to report errors @param[in,out] tables TABLE_LIST instance created by the parser Loading @@ -3754,10 +3754,10 @@ bool check_and_update_table_version(THD *thd, TABLE_LIST *tables, TABLE_SHARE *table_share) { if (! tables->is_metadata_id_equal(table_share)) if (! tables->is_table_ref_id_equal(table_share)) { if (thd->m_metadata_observer && thd->m_metadata_observer->report_error(thd)) if (thd->m_reprepare_observer && thd->m_reprepare_observer->report_error(thd)) { /* Version of the table share is different from the Loading @@ -3768,14 +3768,14 @@ check_and_update_table_version(THD *thd, return TRUE; } /* Always maintain the latest version and type */ tables->set_metadata_id(table_share); tables->set_table_ref_id(table_share); } #if 0 #ifndef DBUG_OFF /* Spuriously reprepare each statement. */ if (thd->m_metadata_observer && thd->stmt_arena->is_reprepared == FALSE) if (thd->m_reprepare_observer && thd->stmt_arena->is_reprepared == FALSE) { thd->m_metadata_observer->report_error(thd); thd->m_reprepare_observer->report_error(thd); return TRUE; } #endif Loading Loading @@ -3865,7 +3865,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, Note, the assert below is known to fail inside stored procedures (Bug#27011). */ DBUG_ASSERT(thd->m_metadata_observer); DBUG_ASSERT(thd->m_reprepare_observer); check_and_update_table_version(thd, table_list, share); /* Always an error. */ DBUG_ASSERT(thd->is_error()); Loading sql/sql_class.cc +14 −5 Original line number Diff line number Diff line Loading @@ -198,6 +198,19 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ /** Push an error to the error stack and return TRUE for now. */ bool Reprepare_observer::report_error(THD *thd) { my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER)); m_invalidated= TRUE; return TRUE; } Open_tables_state::Open_tables_state(ulong version_arg) :version(version_arg), state_flags(0U) { Loading Loading @@ -360,10 +373,6 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, return thd->strmake(str.ptr(), str.length()); } Metadata_version_observer::~Metadata_version_observer() { } /** Clear this diagnostics area. Loading Loading @@ -2774,7 +2783,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) handler_tables == 0 && derived_tables == 0 && lock == 0 && locked_tables == 0 && prelocked_mode == NON_PRELOCKED && m_metadata_observer == NULL); m_reprepare_observer == NULL); set_open_tables_state(backup); DBUG_VOID_RETURN; } Loading sql/sql_class.h +14 −15 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ #include "rpl_tblmap.h" /** An abstract interface that can be used to take an action when An interface that is used to take an action when the locking module notices that a table version has changed since the last execution. "Table" here may refer to any kind of table -- a base table, a temporary table, a view or an Loading @@ -36,36 +36,35 @@ parse tree *may* be no longer valid, e.g. in case it contains optimizations that depend on table metadata. This class provides an abstract interface (a method) that is This class provides an interface (a method) that is invoked when such a situation takes place. The implementation of the interface in most cases simply reports an error, but the exact details depend on the nature of the SQL statement. The implementation of the method simply reports an error, but the exact details depend on the nature of the SQL statement. At most 1 instance of this class is active at a time, in which case THD::m_metadata_observer is not NULL. case THD::m_reprepare_observer is not NULL. @sa check_and_update_table_version() for details of the version tracking algorithm @sa Execute_observer for details of how we detect that a metadata change is fatal and a re-prepare is necessary @sa Open_tables_state::m_metadata_observer for the life cycle @sa Open_tables_state::m_reprepare_observer for the life cycle of metadata observers. */ class Metadata_version_observer class Reprepare_observer { public: virtual ~Metadata_version_observer(); /** Check if a change of metadata is OK. In future the signature of this method may be extended to accept the old and the new versions, but since currently the check is very simple, we only need the THD to report an error. */ virtual bool report_error(THD *thd)= 0; bool report_error(THD *thd); bool is_invalidated() const { return m_invalidated; } void reset_reprepare_observer() { m_invalidated= FALSE; } private: bool m_invalidated; }; Loading Loading @@ -848,7 +847,7 @@ class Open_tables_state tracking. @sa check_and_update_table_version() */ Metadata_version_observer *m_metadata_observer; Reprepare_observer *m_reprepare_observer; /** List of regular tables in use by this thread. Contains temporary and Loading Loading @@ -953,7 +952,7 @@ class Open_tables_state extra_lock= lock= locked_tables= 0; prelocked_mode= NON_PRELOCKED; state_flags= 0U; m_metadata_observer= NULL; m_reprepare_observer= NULL; } }; Loading Loading
sql/mysql_priv.h +6 −6 Original line number Diff line number Diff line Loading @@ -700,14 +700,14 @@ const char *set_thd_proc_info(THD *thd, const char *info, @sa Prepared_statement::reprepare() */ enum enum_metadata_type enum enum_table_ref_type { /** Initial value set by the parser */ METADATA_NULL= 0, METADATA_VIEW, METADATA_BASE_TABLE, METADATA_I_S_TABLE, METADATA_TMP_TABLE TABLE_REF_NULL= 0, TABLE_REF_VIEW, TABLE_REF_BASE_TABLE, TABLE_REF_I_S_TABLE, TABLE_REF_TMP_TABLE }; /* Loading
sql/sp_head.cc +3 −3 Original line number Diff line number Diff line Loading @@ -1068,7 +1068,7 @@ sp_head::execute(THD *thd) LEX *old_lex; Item_change_list old_change_list; String old_packet; Metadata_version_observer *save_metadata_observer= thd->m_metadata_observer; Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; Object_creation_ctx *saved_creation_ctx; Loading Loading @@ -1154,7 +1154,7 @@ sp_head::execute(THD *thd) of substatements (Bug#12257, Bug#27011, Bug#32868, Bug#33000), but it's not implemented yet. */ thd->m_metadata_observer= 0; thd->m_reprepare_observer= 0; /* It is also more efficient to save/restore current thd->lex once when Loading Loading @@ -1317,7 +1317,7 @@ sp_head::execute(THD *thd) thd->derived_tables= old_derived_tables; thd->variables.sql_mode= save_sql_mode; thd->abort_on_warning= save_abort_on_warning; thd->m_metadata_observer= save_metadata_observer; thd->m_reprepare_observer= save_reprepare_observer; thd->stmt_arena= old_arena; state= EXECUTED; Loading
sql/sql_base.cc +9 −9 Original line number Diff line number Diff line Loading @@ -3737,8 +3737,8 @@ void assign_new_table_id(TABLE_SHARE *share) @sa Execute_observer @sa check_prepared_statement() to see cases when an observer is installed @sa TABLE_LIST::is_metadata_id_equal() @sa TABLE_SHARE::get_metadata_id() @sa TABLE_LIST::is_table_ref_id_equal() @sa TABLE_SHARE::get_table_ref_id() @param[in] thd used to report errors @param[in,out] tables TABLE_LIST instance created by the parser Loading @@ -3754,10 +3754,10 @@ bool check_and_update_table_version(THD *thd, TABLE_LIST *tables, TABLE_SHARE *table_share) { if (! tables->is_metadata_id_equal(table_share)) if (! tables->is_table_ref_id_equal(table_share)) { if (thd->m_metadata_observer && thd->m_metadata_observer->report_error(thd)) if (thd->m_reprepare_observer && thd->m_reprepare_observer->report_error(thd)) { /* Version of the table share is different from the Loading @@ -3768,14 +3768,14 @@ check_and_update_table_version(THD *thd, return TRUE; } /* Always maintain the latest version and type */ tables->set_metadata_id(table_share); tables->set_table_ref_id(table_share); } #if 0 #ifndef DBUG_OFF /* Spuriously reprepare each statement. */ if (thd->m_metadata_observer && thd->stmt_arena->is_reprepared == FALSE) if (thd->m_reprepare_observer && thd->stmt_arena->is_reprepared == FALSE) { thd->m_metadata_observer->report_error(thd); thd->m_reprepare_observer->report_error(thd); return TRUE; } #endif Loading Loading @@ -3865,7 +3865,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, Note, the assert below is known to fail inside stored procedures (Bug#27011). */ DBUG_ASSERT(thd->m_metadata_observer); DBUG_ASSERT(thd->m_reprepare_observer); check_and_update_table_version(thd, table_list, share); /* Always an error. */ DBUG_ASSERT(thd->is_error()); Loading
sql/sql_class.cc +14 −5 Original line number Diff line number Diff line Loading @@ -198,6 +198,19 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ /** Push an error to the error stack and return TRUE for now. */ bool Reprepare_observer::report_error(THD *thd) { my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER)); m_invalidated= TRUE; return TRUE; } Open_tables_state::Open_tables_state(ulong version_arg) :version(version_arg), state_flags(0U) { Loading Loading @@ -360,10 +373,6 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, return thd->strmake(str.ptr(), str.length()); } Metadata_version_observer::~Metadata_version_observer() { } /** Clear this diagnostics area. Loading Loading @@ -2774,7 +2783,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) handler_tables == 0 && derived_tables == 0 && lock == 0 && locked_tables == 0 && prelocked_mode == NON_PRELOCKED && m_metadata_observer == NULL); m_reprepare_observer == NULL); set_open_tables_state(backup); DBUG_VOID_RETURN; } Loading
sql/sql_class.h +14 −15 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ #include "rpl_tblmap.h" /** An abstract interface that can be used to take an action when An interface that is used to take an action when the locking module notices that a table version has changed since the last execution. "Table" here may refer to any kind of table -- a base table, a temporary table, a view or an Loading @@ -36,36 +36,35 @@ parse tree *may* be no longer valid, e.g. in case it contains optimizations that depend on table metadata. This class provides an abstract interface (a method) that is This class provides an interface (a method) that is invoked when such a situation takes place. The implementation of the interface in most cases simply reports an error, but the exact details depend on the nature of the SQL statement. The implementation of the method simply reports an error, but the exact details depend on the nature of the SQL statement. At most 1 instance of this class is active at a time, in which case THD::m_metadata_observer is not NULL. case THD::m_reprepare_observer is not NULL. @sa check_and_update_table_version() for details of the version tracking algorithm @sa Execute_observer for details of how we detect that a metadata change is fatal and a re-prepare is necessary @sa Open_tables_state::m_metadata_observer for the life cycle @sa Open_tables_state::m_reprepare_observer for the life cycle of metadata observers. */ class Metadata_version_observer class Reprepare_observer { public: virtual ~Metadata_version_observer(); /** Check if a change of metadata is OK. In future the signature of this method may be extended to accept the old and the new versions, but since currently the check is very simple, we only need the THD to report an error. */ virtual bool report_error(THD *thd)= 0; bool report_error(THD *thd); bool is_invalidated() const { return m_invalidated; } void reset_reprepare_observer() { m_invalidated= FALSE; } private: bool m_invalidated; }; Loading Loading @@ -848,7 +847,7 @@ class Open_tables_state tracking. @sa check_and_update_table_version() */ Metadata_version_observer *m_metadata_observer; Reprepare_observer *m_reprepare_observer; /** List of regular tables in use by this thread. Contains temporary and Loading Loading @@ -953,7 +952,7 @@ class Open_tables_state extra_lock= lock= locked_tables= 0; prelocked_mode= NON_PRELOCKED; state_flags= 0U; m_metadata_observer= NULL; m_reprepare_observer= NULL; } }; Loading