List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:December 16 2011 11:45pm
Subject:bzr push into mysql-trunk branch (mattias.jonsson:3673 to 3674) WL#4443
View as plain text  
 3674 Mattias Jonsson	2011-12-17
      WL#4443
      
      cleanups

    modified:
      sql/handler.cc
      sql/item_cmpfunc.cc
      sql/item_row.cc
      sql/item_strfunc.cc
      sql/opt_range.cc
      sql/sql_base.cc
      sql/sql_insert.cc
      sql/sql_lex.h
      sql/sql_select.cc
      sql/sql_union.cc
 3673 Mattias Jonsson	2011-12-16
      WL#4443 fixing query cache tests
      
      Reverted back to storing queries in the query cache after
      the tables was locked.
      
      This makes transactional storage engines work with the query cache
      since they can use the lock as signal to start a new transaktion.
      
      This also means that queries that fails (like on access control) before
      the tables are locked is not registered and is not included in
      Qcache_not_cached status variable.

    modified:
      mysql-test/r/grant_cache_no_prot.result
      sql/sql_select.cc
      sql/sql_union.cc
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-12-16 20:28:07 +0000
+++ b/sql/handler.cc	2011-12-16 23:44:33 +0000
@@ -2216,7 +2216,6 @@ int handler::ha_open(TABLE *table_arg, c
              ("name: %s  db_type: %d  db_stat: %d  mode: %d  lock_test: %d",
               name, ht->db_type, table_arg->db_stat, mode,
               test_if_locked));
-  DBUG_PRINT("info", ("this: 0x%p", this));
 
   table= table_arg;
   DBUG_ASSERT(table->s == table_share);
@@ -2268,7 +2267,6 @@ int handler::ha_open(TABLE *table_arg, c
 int handler::ha_close(void)
 {
   DBUG_ENTER("handler::ha_close");
-  DBUG_PRINT("info", ("this: 0x%p", this));
 #ifdef HAVE_PSI_TABLE_INTERFACE
   PSI_CALL(close_table)(m_psi);
   m_psi= NULL; /* instrumentation handle, invalid after close_table() */
@@ -2316,11 +2314,10 @@ int handler::ha_index_init(uint idx, boo
 int handler::ha_index_end()
 {
   DBUG_ENTER("ha_index_end");
-  /* Due to the HANDLER SQL command we cannot enforse this */
-  /*
-  DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
+  /* SQL HANDLER function can call this without having it locked. */
+  DBUG_ASSERT(ha_table_flags() & HA_CAN_SQL_HANDLER ||
+              table_share->tmp_table != NO_TMP_TABLE ||
               m_lock_type != F_UNLCK);
-  */
   DBUG_ASSERT(inited==INDEX);
   inited=NONE;
   end_range= NULL;
@@ -2363,11 +2360,10 @@ int handler::ha_rnd_init(bool scan)
 int handler::ha_rnd_end()
 {
   DBUG_ENTER("ha_rnd_end");
-  /* Due to the HANDLER SQL command we cannot enforse this */
-  /*
-  DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
+  /* SQL HANDLER function can call this without having it locked. */
+  DBUG_ASSERT(ha_table_flags() & HA_CAN_SQL_HANDLER ||
+              table_share->tmp_table != NO_TMP_TABLE ||
               m_lock_type != F_UNLCK);
-  */
   DBUG_ASSERT(inited==RND);
   inited=NONE;
   end_range= NULL;
@@ -6139,11 +6135,12 @@ int handler::ha_external_lock(THD *thd, 
   {
     DBUG_PRINT("error", ("inited (%d) != NONE in ha_external_lock (%d, was %d)",
                          inited, lock_type, m_lock_type));
-#ifdef NOT_YET_DUE_TO_HANDLER_SQL_INTERFACE
     /* HANDLER t READ... uses this even between locks */
-    inited= NONE;
-    DBUG_ASSERT(0);
-#endif
+    if (!(ha_table_flags() & HA_CAN_SQL_HANDLER))
+    {
+      inited= NONE;
+      DBUG_ASSERT(0);
+    }
   }
   /* If this handler is cloned, then table->file is not this handler! */
   // TODO: have an indicator in the handler to show that it is clone,
@@ -6229,7 +6226,6 @@ int handler::ha_external_lock(THD *thd, 
 int handler::ha_reset()
 {
   DBUG_ENTER("handler::ha_reset");
-  DBUG_PRINT("info", ("this: 0x%p", this));
   /* Check that we have called all proper deallocation functions */
   DBUG_ASSERT((uchar*) table->def_read_set.bitmap +
               table->s->column_bitmap_size ==
@@ -6261,7 +6257,6 @@ int handler::ha_write_row(uchar *buf)
   MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
 
   DBUG_ENTER("handler::ha_write_row");
-  DBUG_PRINT("info", ("this: 0x%p", this));
 
   MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
   mark_trx_read_write();

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2011-12-16 12:58:27 +0000
+++ b/sql/item_cmpfunc.cc	2011-12-16 23:44:33 +0000
@@ -5324,7 +5324,9 @@ bool Item_func_like::fix_fields(THD *thd
       We could also do boyer-more for non-const items, but as we would have to
       recompute the tables for each row it's not worth it.
     */
-    if (args[1]->const_item() && !args[1]->has_subquery() &&
+    if (args[1]->const_item() &&
+        /* Do not evaluate subqueries unless the tables are locked */
+        (thd->lex->is_query_tables_locked() || !args[1]->has_subquery()) &&
         !use_strnxfrm(collation.collation) &&
         !(specialflag & SPECIAL_NO_NEW_FUNC))
     {

=== modified file 'sql/item_row.cc'
--- a/sql/item_row.cc	2011-12-06 00:37:19 +0000
+++ b/sql/item_row.cc	2011-12-16 23:44:33 +0000
@@ -80,10 +80,12 @@ bool Item_row::fix_fields(THD *thd, Item
     used_tables_cache |= item->used_tables();
     /*
       Do not treat subqueries as const ones here as it will cause their
-      evaluation during prepare stage.
+      evaluation during prepare stage, unless the query tables are locked.
     */
-    const_item_cache&= item->const_item() && !item->has_subquery()
-                       && !with_null;
+    const_item_cache&= item->const_item() &&
+          /* Do not evaluate subqueries unless the tables are locked */
+          (thd->lex->is_query_tables_locked() || !item->has_subquery()) &&
+          !with_null;
     not_null_tables_cache|= item->not_null_tables();
 
     if (const_item_cache)

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2011-12-16 12:58:27 +0000
+++ b/sql/item_strfunc.cc	2011-12-16 23:44:33 +0000
@@ -1539,6 +1539,7 @@ void Item_func_substr::fix_length_and_de
 
   agg_arg_charsets_for_string_result(collation, args, 1);
   DBUG_ASSERT(collation.collation != NULL);
+  /* Don't evaluate subqueries during prepare. */
   if (args[1]->const_item() && !args[1]->has_subquery())
   {
     int32 start= (int32) args[1]->val_int();

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2011-12-16 12:58:27 +0000
+++ b/sql/opt_range.cc	2011-12-16 23:44:33 +0000
@@ -6464,11 +6464,10 @@ get_mm_leaf(RANGE_OPT_PARAM *param, Item
        field->type() == MYSQL_TYPE_DATETIME))
     field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
 
-  // TODO: don't use file, use something else, like query_tables_status.
-  if (field->table->file->get_lock_type() == F_UNLCK &&
+  if (!param->thd->lex->is_query_tables_locked() &&
       (!value->const_item() || value->has_subquery()))
   {
-    /* Don't eval non const or subqueries if not locked. I.e. prepare phase */
+    /* Don't eval non const or subqueries if not locked. I.e. in prepare. */
     tree= 0;
     field->table->in_use->variables.sql_mode= orig_sql_mode;
     goto end;

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-12-16 12:58:27 +0000
+++ b/sql/sql_base.cc	2011-12-16 23:44:33 +0000
@@ -5919,10 +5919,6 @@ bool lock_tables(THD *thd, TABLE_LIST *t
         master and slave inconsistent.
         We can solve these problems in mixed mode by switching to binlogging 
         if at least one updated table is used by sub-statement
-        TODO: Verify what to do if first_not_own_table is not correct here?
-        I.e. when the first table have been unlinked, but there rest are
-        not own tables, i.e. when query_tables_own_last is set,
-        but *query_tables_own_last is NULL.
       */
       if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables && 
           has_write_table_with_auto_increment(thd->lex->first_not_own_table()))
@@ -5941,23 +5937,6 @@ bool lock_tables(THD *thd, TABLE_LIST *t
         thd->lex->sql_command != SQLCOM_LOCK_TABLES)
     {
       TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
-#ifdef TEST_FIRST_NOT_OWN
-      if (!first_not_own)
-      {
-        /*
-          It is either only own tables.
-          Or the first table may have been removed by unlink_first_table,
-          which sets first/query_tables->next_global to NULL and to which
-          query_tables_own_last pointed to. This can only happen in
-          CREATE TABLE t [SELECT...].
-        */
-        if (thd->lex->query_tables_own_last != thd->lex->query_tables_last)
-        {
-          DBUG_ASSERT(thd->lex->sql_command == SQLCOM_CREATE_TABLE);
-          first_not_own= thd->lex->query_tables;
-        }
-      }
-#endif /* TEST_FIRST_NOT_OWN */
       /*
         We just have done implicit LOCK TABLES, and now we have
         to emulate first open_and_lock_tables() after it.

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2011-12-16 12:58:27 +0000
+++ b/sql/sql_insert.cc	2011-12-16 23:44:33 +0000
@@ -3402,23 +3402,6 @@ select_insert::prepare(List<Item> &value
     lex->current_select->options|= OPTION_BUFFER_RESULT;
     lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
   }
-#ifdef MOVED_TO_PREPARE2
-  else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
-           thd->locked_tables_mode <= LTM_LOCK_TABLES &&
-           !thd->lex->describe)
-  {
-    /*
-      We must not yet prepare the result table if it is the same as one of the 
-      source tables (INSERT SELECT). The preparation may disable 
-      indexes on the result table, which may be used during the select, if it
-      is the same table (Bug #6034). Do the preparation after the select phase
-      in select_insert::prepare2().
-      We won't start bulk inserts at all if this statement uses functions or
-      should invoke triggers since they may access to the same table too.
-    */
-    table->file->ha_start_bulk_insert((ha_rows) 0);
-  }
-#endif
   restore_record(table,s->default_values);		// Get empty record
   table->next_number_field=table->found_next_number_field;
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-12-16 12:58:27 +0000
+++ b/sql/sql_lex.h	2011-12-16 23:44:33 +0000
@@ -1206,9 +1206,8 @@ public:
       Then it might be not own tables left any way.
       This can be checked by comparing query_tables_own_last with
       query_tables_last and if they is not the same, then
-      first not own is query_tables.
+      first_not_own_table is query_tables.
     */
-    // TODO: check if this works
     if (query_tables_own_last)
     {
       if (*query_tables_own_last)
@@ -1220,7 +1219,6 @@ public:
       }
     }
     return NULL;
-    //return (query_tables_own_last ? *query_tables_own_last : 0);
   }
   void chop_off_not_own_tables()
   {

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-12-16 22:18:36 +0000
+++ b/sql/sql_select.cc	2011-12-16 23:44:33 +0000
@@ -1232,8 +1232,9 @@ mysql_select(THD *thd,
   }
 
   /*
-    We must wait after locking to store the query in the query cache.
-    Transactional engines must been signalled that the statement started.
+    Tables must be locked before storing the query in the query cache.
+    Transactional engines must been signalled that the statement started,
+    which external_lock signals.
   */
   if (store_in_query_cache)
     query_cache_store_query(thd, thd->lex->query_tables);

=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc	2011-12-16 22:18:36 +0000
+++ b/sql/sql_union.cc	2011-12-16 23:44:33 +0000
@@ -52,8 +52,9 @@ bool mysql_union(THD *thd, LEX *lex, sel
     goto err;
 
   /*
-    We must wait after locking to store the query in the query cache.
-    Transactional engines must been signalled that the statement started.
+    Tables must be locked before storing the query in the query cache.
+    Transactional engines must been signalled that the statement started,
+    which external_lock signals.
   */
   if (store_in_query_cache)
     query_cache_store_query(thd, thd->lex->query_tables);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (mattias.jonsson:3673 to 3674) WL#4443Mattias Jonsson19 Dec