diff options
author | unknown <kostja@bodhi.(none)> | 2008-04-19 14:37:20 +0400 |
---|---|---|
committer | unknown <kostja@bodhi.(none)> | 2008-04-19 14:37:20 +0400 |
commit | f74a78b8eb43b67e6376e8ffafec557687c2e77f (patch) | |
tree | d45e65eb7b3c91ac492f651592c763f36836e04f /sql/table.h | |
parent | c481f6b3cf80f471321d2ef4e7c68fe9e6e5d0ca (diff) | |
parent | 642b4c27c5920da3285d2f68fd77090057e84b57 (diff) | |
download | mariadb-git-f74a78b8eb43b67e6376e8ffafec557687c2e77f.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into bodhi.(none):/opt/local/work/mysql-5.1-27430
include/my_global.h:
Auto merged
mysql-test/r/grant.result:
Auto merged
mysql-test/t/disabled.def:
Auto merged
mysql-test/t/grant.test:
Auto merged
sql/item.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/table.h:
Auto merged
storage/myisam/mi_create.c:
Auto merged
tests/mysql_client_test.c:
Auto merged
sql/share/errmsg.txt:
Manual merge.
Diffstat (limited to 'sql/table.h')
-rw-r--r-- | sql/table.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/sql/table.h b/sql/table.h index 0e0a35b022d..eccb5d85be2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -438,6 +438,105 @@ typedef struct st_table_share return table_map_id; } + /** + Convert unrelated members of TABLE_SHARE to one enum + representing its metadata type. + + @todo perhaps we need to have a member instead of a function. + */ + enum enum_metadata_type get_metadata_type() const + { + if (is_view) + return METADATA_VIEW; + switch (tmp_table) { + case NO_TMP_TABLE: + return METADATA_BASE_TABLE; + case SYSTEM_TMP_TABLE: + return METADATA_I_S_TABLE; + default: + return METADATA_TMP_TABLE; + } + } + /** + Return a table metadata version. + * for base tables, we return table_map_id. + It is assigned from a global counter incremented for each + new table loaded into the table definition cache (TDC). + * for temporary tables it's table_map_id again. But for + temporary tables table_map_id is assigned from + thd->query_id. The latter is assigned from a thread local + counter incremented for every new SQL statement. Since + temporary tables are thread-local, each temporary table + gets a unique id. + * for everything else (views, information schema tables), + the version id is zero. + + This choice of version id is a large compromise + to have a working prepared statement validation in 5.1. In + future version ids will be persistent, as described in WL#4180. + + Let's try to explain why and how this limited solution allows + to validate prepared statements. + + Firstly, spaces (in mathematical sense) of version numbers + never intersect for different metadata types. Therefore, + version id of a temporary table is never compared with + a version id of a view or a temporary table, and vice versa. + + Secondly, for base tables, we know that each DDL flushes the + respective share from the TDC. This ensures that whenever + a table is altered or dropped and recreated, it gets a new + version id. + Unfortunately, since elements of the TDC are also flushed on + LRU basis, this choice of version ids leads to false positives. + E.g. when the TDC size is too small, we may have a SELECT + * FROM INFORMATION_SCHEMA.TABLES flush all its elements, which + in turn will lead to a validation error and a subsequent + reprepare of all prepared statements. This is + considered acceptable, since as long as prepared statements are + automatically reprepared, spurious invalidation is only + a performance hit. Besides, no better simple solution exists. + + For temporary tables, using thd->query_id ensures that if + a temporary table was altered or recreated, a new version id is + assigned. This suits validation needs very well and will perhaps + never change. + + Metadata of information schema tables never changes. + Thus we can safely assume 0 for a good enough version id. + + Views are a special and tricky case. A view is always inlined + into the parse tree of a prepared statement at prepare. + Thus, when we execute a prepared statement, the parse tree + will not get modified even if the view is replaced with another + view. Therefore, we can safely choose 0 for version id of + views and effectively never invalidate a prepared statement + when a view definition is altered. Note, that this leads to + wrong binary log in statement-based replication, since we log + prepared statement execution in form Query_log_events + containing conventional statements. But since there is no + metadata locking for views, the very same problem exists for + conventional statements alone, as reported in Bug#25144. The only + difference between prepared and conventional execution is, + effectively, that for prepared statements the race condition + window is much wider. + In 6.0 we plan to support view metadata locking (WL#3726) and + extend table definition cache to cache views (WL#4298). + When this is done, views will be handled in the same fashion + as the base tables. + + Finally, by taking into account metadata type, we always + track that a change has taken place when a view is replaced + with a base table, a base table is replaced with a temporary + table and so on. + + @sa TABLE_LIST::is_metadata_version_equal() + */ + ulong get_metadata_version() const + { + return tmp_table == SYSTEM_TMP_TABLE || is_view ? 0 : table_map_id; + } + } TABLE_SHARE; @@ -1233,6 +1332,33 @@ struct TABLE_LIST child_def_version= ~0UL; } + /** + Compare the version of metadata from the previous execution + (if any) with values obtained from the current table + definition cache element. + + @sa check_and_update_table_version() + */ + inline + bool is_metadata_version_equal(TABLE_SHARE *s) const + { + return (m_metadata_type == s->get_metadata_type() && + m_metadata_version == s->get_metadata_version()); + } + + /** + Record the value of metadata version of the corresponding + table definition cache element in this parse tree node. + + @sa check_and_update_table_version() + */ + inline + void set_metadata_version(TABLE_SHARE *s) + { + m_metadata_type= s->get_metadata_type(); + m_metadata_version= s->get_metadata_version(); + } + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); @@ -1243,6 +1369,10 @@ private: /* Remembered MERGE child def version. See top comment in ha_myisammrg.cc */ ulong child_def_version; + /** See comments for set_metadata_version() */ + enum enum_metadata_type m_metadata_type; + /** See comments for set_metadata_version() */ + ulong m_metadata_version; }; class Item; |