Commit f5a80e5a authored by unknown's avatar unknown
Browse files

Merge 51.0.168.192.in-addr.arpa:/Users/bell/mysql/bk/work-qc_item_view-5.0

into 51.0.168.192.in-addr.arpa:/Users/bell/mysql/bk/work-repl-5.0


BitKeeper/etc/logging_ok:
  auto-union
parents c41a485d fee0f25f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2480,5 +2480,17 @@ ERROR 42000: Can't find any matching row in the user table
select bug5278()|
ERROR 42000: Can't find any matching row in the user table
drop function bug5278|
drop procedure if exists p1|
create table t3(id int)|
insert into t3 values(1)|
create procedure bug7992()
begin
declare i int;
select max(id)+1 into i from t3;
end|
call bug7992()|
call bug7992()|
drop procedure bug7992|
drop table t3|
drop table t1;
drop table t2;
+25 −0
Original line number Diff line number Diff line
drop table if exists t1,t2,v1,v2,v3;
drop view if exists t1,t2,v1,v2,v3;
set GLOBAL query_cache_size=1355776;
flush status;
create table t1 (a int, b int);
@@ -98,4 +100,27 @@ Qcache_hits 1
drop view v1;
set query_cache_type=default;
drop table t1;
create table t1 (a int);
insert into t1 values (1), (2), (3);
create view v1 as select a from t1 where a > 1;
select * from v1;
a
2
3
alter view v1 as select a from t1 where a > 2;
select * from v1;
a
3
drop view v1;
select * from v1;
ERROR 42S02: Table 'test.v1' doesn't exist
drop table t1;
create table t1 (a int, primary key (a), b int);
create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
select * from v3;
a	b
drop view v3;
drop table t1, t2;
set GLOBAL query_cache_size=default;
+19 −0
Original line number Diff line number Diff line
@@ -2982,7 +2982,26 @@ select bug5278()|
select bug5278()|
drop function bug5278|

#
# BUG#7992: rolling back temporary Item tree changes in SP
#
--disable_warnings
drop procedure if exists p1|
--enable_warnings
create table t3(id int)|
insert into t3 values(1)|
create procedure bug7992()
begin
  declare i int;
  select max(id)+1 into i from t3;
end|

call bug7992()|
call bug7992()|
drop procedure bug7992|
drop table t3|

delimiter ;|
drop table t1;
drop table t2;
+30 −1
Original line number Diff line number Diff line
@@ -2,6 +2,11 @@
#
# QUERY CACHE options for VIEWs
#
--disable_warnings
drop table if exists t1,t2,v1,v2,v3;
drop view if exists t1,t2,v1,v2,v3;
--enable_warnings

set GLOBAL query_cache_size=1355776;
flush status;
create table t1 (a int, b int);
@@ -53,6 +58,30 @@ drop view v1;
set query_cache_type=default;

drop table t1;
set GLOBAL query_cache_size=default;

#
# invalidation of view
#
create table t1 (a int);
insert into t1 values (1), (2), (3);
create view v1 as select a from t1 where a > 1;
select * from v1;
alter view v1 as select a from t1 where a > 2;
select * from v1;
drop view v1;
-- error 1146
select * from v1;
drop table t1;

#
# join view with QC
#
create table t1 (a int, primary key (a), b int);
create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
select * from v3;
drop view v3;
drop table t1, t2;

set GLOBAL query_cache_size=default;
+181 −78
Original line number Diff line number Diff line
@@ -311,7 +311,7 @@ TODO list:
#include "emb_qcache.h"
#endif

#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
#if !defined(EXTRA_DBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
  pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
@@ -2103,45 +2103,76 @@ void Query_cache::invalidate_table(Query_cache_block *table_block)
  }
}


/*
  Store all used tables
  Register given table list begining with given position in tables table of
  block

  SYNOPSIS
    register_all_tables()
    block		Store tables in this block
    tables_used		List if used tables
    tables_arg		Not used ?
    Query_cache::register_tables_from_list
    tables_used     given table list
    counter         number current position in table of tables of block
    block_table     pointer to current position in tables table of block

  RETURN
    0   error
    number of next position of table entry in table of tables of block
*/

my_bool Query_cache::register_all_tables(Query_cache_block *block,
					 TABLE_LIST *tables_used,
					 TABLE_COUNTER_TYPE tables_arg)
TABLE_COUNTER_TYPE
Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
                                       TABLE_COUNTER_TYPE counter,
                                       Query_cache_block_table *block_table)
{
  TABLE_COUNTER_TYPE n;
  DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x",
		      (ulong) block, (int) tables_arg,
		      (int) ALIGN_SIZE(sizeof(Query_cache_block))));

  Query_cache_block_table *block_table = block->table(0);

  for (n= 0;
  DBUG_ENTER("Query_cache::register_tables_from_list");
  for (n= counter;
       tables_used;
       tables_used= tables_used->next_global, n++, block_table++)
  {
    block_table->n= n;
    if (tables_used->view)
    {
      char key[MAX_DBKEY_LENGTH];
      uint key_length;
      DBUG_PRINT("qcache", ("view %s, db %s",
                            tables_used->view_name.str,
                            tables_used->view_db.str));
      key_length= (uint) (strmov(strmov(key, tables_used->view_db.str) + 1,
                                 tables_used->view_name.str) - key) + 1;
      /*
        There are not callback function for for VIEWs
      */
      if (!insert_table(key_length, key, block_table,
                        tables_used->view_db.length + 1,
                        HA_CACHE_TBL_NONTRANSACT, 0, 0))
        DBUG_RETURN(0);
      {
        TABLE_COUNTER_TYPE inc= register_tables_from_list(tables_used->ancestor,
                                                          n + 1,
                                                          block_table + 1);
        if (!inc)
          DBUG_RETURN(0);
        n+= inc;
        block_table+= inc;
      }
    }
    else
    {
      DBUG_PRINT("qcache",
                 ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
		tables_used->table_name, tables_used->db,
                  tables_used->table->s->table_name,
                  tables_used->table->s->table_cache_key,
                  (ulong) tables_used->table,
                  tables_used->table->s->key_length,
                  (ulong) tables_used->table->s->table_cache_key));
    block_table->n= n;
      if (!insert_table(tables_used->table->s->key_length,
                        tables_used->table->s->table_cache_key, block_table,
                        tables_used->db_length,
                        tables_used->table->file->table_cache_type(),
                        tables_used->callback_func,
                        tables_used->engine_data))
      break;
        DBUG_RETURN(0);

      if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
      {
@@ -2163,13 +2194,39 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
                            db_length,
                            tables_used->table->file->table_cache_type(),
                            0, 0))
	  goto err;
            DBUG_RETURN(0);
        }
      }
    }
  }
  DBUG_RETURN(n - counter);
}

/*
  Store all used tables

  SYNOPSIS
    register_all_tables()
    block		Store tables in this block
    tables_used		List if used tables
    tables_arg		Not used ?
*/

my_bool Query_cache::register_all_tables(Query_cache_block *block,
					 TABLE_LIST *tables_used,
					 TABLE_COUNTER_TYPE tables_arg)
{
  TABLE_COUNTER_TYPE n;
  DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x",
		      (ulong) block, (int) tables_arg,
		      (int) ALIGN_SIZE(sizeof(Query_cache_block))));

  Query_cache_block_table *block_table = block->table(0);

  n= register_tables_from_list(tables_used, 0, block_table);

err:
  if (tables_used)
  if (n)
  {
    DBUG_PRINT("qcache", ("failed at table %d", (int) n));
    /* Unlink the tables we allocated above */
@@ -2178,7 +2235,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
	 tmp++)
      unlink_table(tmp);
  }
  return (tables_used == 0);
  return (n);
}

/*
@@ -2676,36 +2733,47 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
*****************************************************************************/

/*
  If query is cacheable return number tables in query
  (query without tables are not cached)
  Collect information about table types, check that tables are cachable and
  count them

  SYNOPSIS
    process_and_count_tables()
    tables_used     table list for processing
    tables_type     pointer to variable for table types collection

  RETURN
    0   error
    >0  number of tables
*/

TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
					     char *query,
					     LEX *lex,
					     TABLE_LIST *tables_used,
static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
                                                   uint8 *tables_type)
{
  DBUG_ENTER("process_and_count_tables");
  TABLE_COUNTER_TYPE table_count = 0;
  DBUG_ENTER("Query_cache::is_cacheable");

  if (lex->sql_command == SQLCOM_SELECT &&
      (thd->variables.query_cache_type == 1 ||
       (thd->variables.query_cache_type == 2 && (lex->select_lex.options &
						 OPTION_TO_QUERY_CACHE))) &&
      lex->safe_to_cache_query)
  {
    DBUG_PRINT("qcache", ("options %lx %lx, type %u",
			OPTION_TO_QUERY_CACHE,
			lex->select_lex.options,
			(int) thd->variables.query_cache_type));

  for (; tables_used; tables_used= tables_used->next_global)
  {
    table_count++;
    if (tables_used->view)
    {
      DBUG_PRINT("qcache", ("view %s, db %s",
                            tables_used->view_name.str,
                            tables_used->view_db.str));
      *tables_type|= HA_CACHE_TBL_NONTRANSACT;
      {
        TABLE_COUNTER_TYPE subcount;
        if (!(subcount= process_and_count_tables(tables_used->ancestor,
                                                 tables_type)))
          DBUG_RETURN(0);
        table_count+= subcount;
      }
    }
    else
    {
      DBUG_PRINT("qcache", ("table %s, db %s, type %u",
			  tables_used->table_name,
			  tables_used->db, tables_used->table->s->db_type));
                            tables_used->table->s->table_name,
                            tables_used->table->s->table_cache_key,
                            tables_used->table->s->db_type));
      *tables_type|= tables_used->table->file->table_cache_type();

      /*
@@ -2715,7 +2783,8 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
      if (tables_used->table->s->tmp_table != NO_TMP_TABLE ||
          (*tables_type & HA_CACHE_TBL_NOCACHE) ||
          (tables_used->db_length == 5 &&
	   my_strnncoll(table_alias_charset, (uchar*)tables_used->db, 6,
           my_strnncoll(table_alias_charset,
                        (uchar*)tables_used->table->s->table_cache_key, 6,
                        (uchar*)"mysql",6) == 0))
      {
        DBUG_PRINT("qcache",
@@ -2730,6 +2799,38 @@ other non-cacheable table(s)"));
        table_count+= (file->end_table - file->open_tables);
      }
    }
  }
  DBUG_RETURN(table_count);
}


/*
  If query is cacheable return number tables in query
  (query without tables are not cached)
*/

TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
					     char *query,
					     LEX *lex,
					     TABLE_LIST *tables_used,
					     uint8 *tables_type)
{
  TABLE_COUNTER_TYPE table_count;
  DBUG_ENTER("Query_cache::is_cacheable");

  if (lex->sql_command == SQLCOM_SELECT &&
      (thd->variables.query_cache_type == 1 ||
       (thd->variables.query_cache_type == 2 && (lex->select_lex.options &
						 OPTION_TO_QUERY_CACHE))) &&
      lex->safe_to_cache_query)
  {
    DBUG_PRINT("qcache", ("options %lx %lx, type %u",
			OPTION_TO_QUERY_CACHE,
			lex->select_lex.options,
			(int) thd->variables.query_cache_type));

    if (!(table_count= process_and_count_tables(tables_used, tables_type)))
      DBUG_RETURN(0);

    if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
	((*tables_type)&HA_CACHE_TBL_TRANSACT))
@@ -2769,7 +2870,9 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,

  for (; tables_used; tables_used= tables_used->next_global)
  {
    TABLE *table= tables_used->table;
    TABLE *table;
    if (!(table= tables_used->table))
      continue;
    handler *handler= table->file;
    if (!handler->register_query_cache_table(thd, table->s->table_cache_key,
					     table->s->key_length,
Loading