1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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.
This commit is contained in:
unknown
2008-04-19 14:37:20 +04:00
39 changed files with 4385 additions and 4779 deletions

View File

@ -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;