List:Commits« Previous MessageNext Message »
From:dlenev Date:January 16 2006 1:57pm
Subject:bk commit into 5.1 tree (dlenev:1.2056)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of dlenev. When dlenev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2056 06/01/16 16:56:36 dlenev@stripped +12 -0
  Merge mysql.com:/home/dlenev/src/mysql-5.0-bg12198-2
  into  mysql.com:/home/dlenev/src/mysql-5.1-merges

  sql/sql_base.cc
    1.296 06/01/16 16:56:23 dlenev@stripped +0 -14
    Manual merge.

  storage/myisam/myisam_ftdump.c
    1.38 06/01/16 13:20:31 dlenev@stripped +0 -0
    Auto merged

  storage/innobase/os/os0thread.c
    1.30 06/01/16 13:20:31 dlenev@stripped +0 -0
    Auto merged

  sql/sql_show.cc
    1.290 06/01/16 13:20:31 dlenev@stripped +0 -0
    Auto merged

  sql/sql_select.cc
    1.385 06/01/16 13:20:30 dlenev@stripped +0 -0
    Auto merged

  sql/sql_handler.cc
    1.79 06/01/16 13:20:29 dlenev@stripped +0 -0
    Auto merged

  sql/sp_head.cc
    1.212 06/01/16 13:20:28 dlenev@stripped +0 -0
    Auto merged

  sql/mysqld.cc
    1.518 06/01/16 13:20:27 dlenev@stripped +0 -0
    Auto merged

  sql/item_cmpfunc.cc
    1.189 06/01/16 13:20:26 dlenev@stripped +0 -0
    Auto merged

  sql/field.cc
    1.297 06/01/16 13:20:26 dlenev@stripped +0 -0
    Auto merged

  storage/myisam/myisam_ftdump.c
    1.36.1.2 06/01/16 13:20:25 dlenev@stripped +0 -0
    Merge rename: myisam/myisam_ftdump.c -> storage/myisam/myisam_ftdump.c

  storage/innobase/os/os0thread.c
    1.28.1.2 06/01/16 13:20:25 dlenev@stripped +0 -0
    Merge rename: innobase/os/os0thread.c -> storage/innobase/os/os0thread.c

  mysql-test/t/sp.test
    1.169 06/01/16 13:20:25 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/sp.result
    1.179 06/01/16 13:20:25 dlenev@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	dlenev
# Host:	brandersnatch.site
# Root:	/home/dlenev/src/mysql-5.1-merges/RESYNC

--- 1.296/sql/field.cc	2006-01-06 21:42:54 +03:00
+++ 1.297/sql/field.cc	2006-01-16 13:20:26 +03:00
@@ -9068,11 +9068,11 @@
   switch (packlength)
   {
   case 1:
-    return 255;
+    return 255 * field_charset->mbmaxlen;
   case 2:
-    return 65535;
+    return 65535 * field_charset->mbmaxlen;
   case 3:
-    return 16777215;
+    return 16777215 * field_charset->mbmaxlen;
   case 4:
     return (uint32) 4294967295U;
   default:

--- 1.517/sql/mysqld.cc	2006-01-13 11:42:31 +03:00
+++ 1.518/sql/mysqld.cc	2006-01-16 13:20:27 +03:00
@@ -3493,6 +3493,11 @@
     }
   }
 #endif
+#ifdef __NETWARE__
+  /* Increasing stacksize of threads on NetWare */
+  
+  pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
+#endif
 
   (void) thr_setconcurrency(concurrency);	// 10 by default
 

--- 1.295/sql/sql_base.cc	2006-01-12 21:50:32 +03:00
+++ 1.296/sql/sql_base.cc	2006-01-16 16:56:23 +03:00
@@ -2083,8 +2083,10 @@
     (*field)->table_name= &table->alias;
   }
   for (key=0 ; key < table->s->keys ; key++)
+  {
     for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
       table->key_info[key].key_part[part].field->table= table;
+  }
   if (table->triggers)
     table->triggers->set_table(table);
 

--- 1.384/sql/sql_select.cc	2006-01-10 16:56:40 +03:00
+++ 1.385/sql/sql_select.cc	2006-01-16 13:20:30 +03:00
@@ -3508,13 +3508,32 @@
     parts of the row from any of the used index.
     This is because table scans uses index and we would not win
     anything by using a table scan.
+
+    A word for word translation of the below if-statement in psergey's
+    understanding: we check if we should use table scan if:
+    (1) The found 'ref' access produces more records than a table scan
+        (or index scan, or quick select), or 'ref' is more expensive than
+        any of them.
+    (2) This doesn't hold: the best way to perform table scan is to to perform
+        'range' access using index IDX, and the best way to perform 'ref' 
+        access is to use the same index IDX, with the same or more key parts.
+        (note: it is not clear how this rule is/should be extended to 
+        index_merge quick selects)
+    (3) See above note about InnoDB.
+    (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access
+             path, but there is no quick select)
+        If the condition in the above brackets holds, then the only possible
+        "table scan" access method is ALL/index (there is no quick select).
+        Since we have a 'ref' access path, and FORCE INDEX instructs us to
+        choose it over ALL/index, there is no need to consider a full table
+        scan.
   */
-  if ((records >= s->found_records || best > s->read_time) &&
-      !(s->quick && best_key && s->quick->index == best_key->key &&
-        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
-      !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
-        ! s->table->used_keys.is_clear_all() && best_key) &&
-      !(s->table->force_index && best_key))
+  if ((records >= s->found_records || best > s->read_time) &&            // (1)
+      !(s->quick && best_key && s->quick->index == best_key->key &&      // (2)
+        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
+      !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&      // (3)
+        ! s->table->used_keys.is_clear_all() && best_key) &&             // (3)
+      !(s->table->force_index && best_key && !s->quick))                 // (4)
   {                                             // Check full join
     ha_rows rnd_records= s->found_records;
     /*
@@ -4497,13 +4516,15 @@
 	parts of the row from any of the used index.
 	This is because table scans uses index and we would not win
 	anything by using a table scan.
+        (see comment in best_access_path() for more details on the below
+         condition)
       */
       if ((records >= s->found_records || best > s->read_time) &&
 	  !(s->quick && best_key && s->quick->index == best_key->key &&
 	    best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
 	  !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
 	    ! s->table->used_keys.is_clear_all() && best_key) &&
-	  !(s->table->force_index && best_key))
+	  !(s->table->force_index && best_key && !s->quick))
       {						// Check full join
         ha_rows rnd_records= s->found_records;
         /*
@@ -8651,6 +8672,11 @@
         have null
       */
       hidden_null_count=null_count;
+      /*
+	We need to update hidden_field_count as we may have stored group
+	functions with constant arguments
+      */
+      param->hidden_field_count= (uint) (reg_field - table->field);
       null_count= 0;
     }
   }
@@ -8872,7 +8898,7 @@
     }
   }
 
-  if (distinct)
+  if (distinct && field_count != param->hidden_field_count)
   {
     /*
       Create an unique key or an unique constraint over all columns

--- 1.289/sql/sql_show.cc	2006-01-13 19:04:32 +03:00
+++ 1.290/sql/sql_show.cc	2006-01-16 13:20:31 +03:00
@@ -2734,12 +2734,15 @@
         field->real_type() == MYSQL_TYPE_VARCHAR ||  // For varbinary type
         field->real_type() == MYSQL_TYPE_STRING)     // For binary type
     {
+      uint32 octet_max_length= field->max_length();
+      if (octet_max_length != (uint32) 4294967295U)
+        octet_max_length /= field->charset()->mbmaxlen;
       longlong char_max_len= is_blob ? 
-        (longlong) field->max_length() / field->charset()->mbminlen :
-        (longlong) field->max_length() / field->charset()->mbmaxlen;
+        (longlong) octet_max_length / field->charset()->mbminlen :
+        (longlong) octet_max_length / field->charset()->mbmaxlen;
       table->field[8]->store(char_max_len, TRUE);
       table->field[8]->set_notnull();
-      table->field[9]->store((longlong) field->max_length(), TRUE);
+      table->field[9]->store((longlong) octet_max_length, TRUE);
       table->field[9]->set_notnull();
     }
 

--- 1.178/mysql-test/r/sp.result	2006-01-11 14:49:43 +03:00
+++ 1.179/mysql-test/r/sp.result	2006-01-16 13:20:25 +03:00
@@ -918,6 +918,11 @@
 drop function if exists f6|
 drop function if exists f7|
 drop function if exists f8|
+drop function if exists f9|
+drop function if exists f10|
+drop function if exists f11|
+drop function if exists f12_1|
+drop function if exists f12_2|
 drop view if exists v0|
 drop view if exists v1|
 drop view if exists v2|
@@ -1097,6 +1102,62 @@
 select f4()|
 ERROR HY000: Table 't2' was not locked with LOCK TABLES
 unlock tables|
+create function f9() returns int
+begin
+declare a, b int;
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+set a:= (select count(*) from t3);
+set b:= (select count(*) from t3 t3_alias);
+return a + b;
+end|
+select f9()|
+f9()
+6
+Warnings:
+Note	1051	Unknown table 't3'
+select f9() from t1 limit 1|
+f9()
+6
+create function f10() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 select id from t4;
+return (select count(*) from t3);
+end|
+select f10()|
+ERROR 42S02: Table 'test.t4' doesn't exist
+create table t4 as select 1 as id|
+select f10()|
+f10()
+1
+create function f11() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+return (select count(*) from t3 as a, t3 as b);
+end|
+select f11()|
+ERROR HY000: Can't reopen table: 'a'
+select f11() from t1|
+ERROR HY000: Can't reopen table: 'a'
+create function f12_1() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+return f12_2();
+end|
+create function f12_2() returns int
+return (select count(*) from t3)|
+drop temporary table t3|
+select f12_1()|
+ERROR 42S02: Table 'test.t3' doesn't exist
+select f12_1() from t1 limit 1|
+ERROR 42S02: Table 'test.t3' doesn't exist
 drop function f0|
 drop function f1|
 drop function f2|
@@ -1106,11 +1167,17 @@
 drop function f6|
 drop function f7|
 drop function f8|
+drop function f9|
+drop function f10|
+drop function f11|
+drop function f12_1|
+drop function f12_2|
 drop view v0|
 drop view v1|
 drop view v2|
 delete from t1 |
 delete from t2 |
+drop table t4|
 drop table if exists fac|
 create table fac (n int unsigned not null primary key, f bigint unsigned)|
 drop procedure if exists ifac|

--- 1.168/mysql-test/t/sp.test	2005-12-22 07:10:55 +03:00
+++ 1.169/mysql-test/t/sp.test	2006-01-16 13:20:25 +03:00
@@ -1157,6 +1157,11 @@
 drop function if exists f6|
 drop function if exists f7|
 drop function if exists f8|
+drop function if exists f9|
+drop function if exists f10|
+drop function if exists f11|
+drop function if exists f12_1|
+drop function if exists f12_2|
 drop view if exists v0|
 drop view if exists v1|
 drop view if exists v2|
@@ -1234,8 +1239,6 @@
 select f6()|
 select id, f6() from t1|
 
-# TODO Test temporary table handling
-
 #
 # Let us test how new locking work with views
 #
@@ -1316,6 +1319,73 @@
 select f4()|
 unlock tables|
 
+# Tests for handling of temporary tables in functions.
+#
+# Unlike for permanent tables we should be able to create, use
+# and drop such tables in functions.
+# 
+# Simplest function using temporary table. It is also test case for bug 
+# #12198 "Temporary table aliasing does not work inside stored functions"
+create function f9() returns int
+begin
+  declare a, b int;
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  set a:= (select count(*) from t3);
+  set b:= (select count(*) from t3 t3_alias);
+  return a + b;
+end|
+# This will emit warning as t3 was not existing before.
+select f9()|
+select f9() from t1 limit 1|
+
+# Function which uses both temporary and permanent tables.
+create function f10() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 select id from t4;
+  return (select count(*) from t3);
+end|
+# Check that we don't ignore completely tables used in function
+--error ER_NO_SUCH_TABLE
+select f10()|
+create table t4 as select 1 as id|
+select f10()|
+
+# Practical cases which we don't handle well (yet)
+#
+# Function which does not work because of well-known and documented
+# limitation of MySQL. We can't use the several instances of the
+# same temporary table in statement.
+create function f11() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  return (select count(*) from t3 as a, t3 as b);
+end|
+--error ER_CANT_REOPEN_TABLE
+select f11()|
+--error ER_CANT_REOPEN_TABLE
+select f11() from t1|
+# We don't handle temporary tables used by nested functions well
+create function f12_1() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  return f12_2();
+end|
+create function f12_2() returns int
+  return (select count(*) from t3)|
+# We need clean start to get error
+drop temporary table t3|
+--error ER_NO_SUCH_TABLE
+select f12_1()|
+--error ER_NO_SUCH_TABLE
+select f12_1() from t1 limit 1|
 
 # Cleanup
 drop function f0|
@@ -1327,11 +1397,17 @@
 drop function f6|
 drop function f7|
 drop function f8|
+drop function f9|
+drop function f10|
+drop function f11|
+drop function f12_1|
+drop function f12_2|
 drop view v0|
 drop view v1|
 drop view v2|
 delete from t1 |
 delete from t2 |
+drop table t4|
 
 # End of non-bug tests
 

--- 1.211/sql/sp_head.cc	2006-01-13 19:04:32 +03:00
+++ 1.212/sql/sp_head.cc	2006-01-16 13:20:28 +03:00
@@ -3146,7 +3146,14 @@
 
 typedef struct st_sp_table
 {
-  LEX_STRING qname;     /* Multi-set key: db_name\0table_name\0alias\0 */
+  /*
+    Multi-set key:
+      db_name\0table_name\0alias\0 - for normal tables
+      db_name\0table_name\0        - for temporary tables
+    Note that in both cases we don't take last '\0' into account when
+    we count length of key.
+  */
+  LEX_STRING qname;
   uint db_length, table_name_length;
   bool temp;               /* true if corresponds to a temporary table */
   thr_lock_type lock_type; /* lock type used for prelocking */
@@ -3216,10 +3223,14 @@
       tname[tlen]= '\0';
 
       /*
-        It is safe to store pointer to table list elements in hash,
-        since they are supposed to have the same lifetime.
+        We ignore alias when we check if table was already marked as temporary
+        (and therefore should not be prelocked). Otherwise we will erroneously
+        treat table with same name but with different alias as non-temporary.
       */
-      if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)))
+      if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)) ||
+          ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname,
+                                        tlen - alen - 1)) &&
+           tab->temp))
       {
         if (tab->lock_type < table->lock_type)
           tab->lock_type= table->lock_type; // Use the table with the highest lock type
@@ -3231,14 +3242,18 @@
       {
 	if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
 	  return FALSE;
-	tab->qname.length= tlen;
-	tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1);
-	if (!tab->qname.str)
-	  return FALSE;
 	if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
 	    lex_for_tmp_check->query_tables == table &&
 	    lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
+        {
 	  tab->temp= TRUE;
+          tab->qname.length= tlen - alen - 1;
+        }
+        else
+          tab->qname.length= tlen;
+        tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1);
+        if (!tab->qname.str)
+          return FALSE;
         tab->table_name_length= table->table_name_length;
         tab->db_length= table->db_length;
         tab->lock_type= table->lock_type;

--- 1.78/sql/sql_handler.cc	2006-01-06 21:34:57 +03:00
+++ 1.79/sql/sql_handler.cc	2006-01-16 13:20:29 +03:00
@@ -424,7 +424,11 @@
 
   if (cond && ((!cond->fixed &&
                 cond->fix_fields(thd, &cond)) || cond->check_cols(1)))
+  {
+    if (table->query_id != thd->query_id)
+      cond->cleanup();                          // File was reopened
     goto err0;
+  }
 
   if (keyname)
   {
Thread
bk commit into 5.1 tree (dlenev:1.2056)dlenev16 Jan