Commit 0e69c252 authored by unknown's avatar unknown
Browse files

Merge rurik.mysql.com:/home/igor/mysql-5.0-opt

into  rurik.mysql.com:/home/igor/dev-opt/mysql-5.0-opt-bug21727


mysql-test/r/subselect.result:
  Auto merged
mysql-test/t/subselect.test:
  Auto merged
sql/filesort.cc:
  Auto merged
sql/item_subselect.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/records.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/table.cc:
  Auto merged
parents 361f0468 2a7cf59f
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -3560,3 +3560,19 @@ FROM t1 GROUP BY t1.a LIMIT 1)
2
2
DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
SET SESSION sort_buffer_size = 32 * 1024;
SELECT SQL_NO_CACHE COUNT(*) 
FROM (SELECT  a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
COUNT(*)
3000
SET SESSION sort_buffer_size = 8 * 1024 * 1024;
SELECT SQL_NO_CACHE COUNT(*) 
FROM (SELECT  a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
COUNT(*)
3000
DROP TABLE t1,t2;
+37 −0
Original line number Diff line number Diff line
@@ -2443,3 +2443,40 @@ SELECT (
FROM t1 t2
GROUP BY t2.a;
DROP TABLE t1,t2;  

#
# Bug #21727: Correlated subquery that requires filesort:
#             slow with big sort_buffer_size 
#

CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
                 PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));

disable_query_log;
let $1=3000;
while ($1)
{
  eval INSERT INTO t1(a) VALUES(RAND()*1000);
  eval SELECT MAX(b) FROM t1 INTO @id;
  let $2=10;
  while ($2)
  {
    eval INSERT INTO t2(y,z) VALUES(@id,RAND()*1000);
    dec $2;
  } 
  dec $1;
}
enable_query_log;

SET SESSION sort_buffer_size = 32 * 1024;
SELECT SQL_NO_CACHE COUNT(*) 
  FROM (SELECT  a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
          FROM t1) t;

SET SESSION sort_buffer_size = 8 * 1024 * 1024;
SELECT SQL_NO_CACHE COUNT(*) 
  FROM (SELECT  a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
          FROM t1) t;

DROP TABLE t1,t2;
+34 −7
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
  DBUG_PUSH("");		/* No DBUG here */
#endif
  FILESORT_INFO table_sort;
  TABLE_LIST *tab= table->pos_in_table_list;
  Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
  /* 
    Don't use table->sort in filesort as it is also used by 
    QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end 
@@ -121,7 +123,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
  my_b_clear(&tempfile);
  my_b_clear(&buffpek_pointers);
  buffpek=0;
  sort_keys= (uchar **) NULL;
  error= 1;
  bzero((char*) &param,sizeof(param));
  param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
@@ -202,13 +203,15 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
    ulong old_memavl;
    ulong keys= memavl/(param.rec_length+sizeof(char*));
    param.keys=(uint) min(records+1, keys);
    if ((sort_keys= (uchar **) make_char_array(param.keys, param.rec_length,
    if (table_sort.sort_keys ||
        (table_sort.sort_keys= (uchar **) make_char_array(param.keys, param.rec_length,
                                               MYF(0))))
      break;
    old_memavl=memavl;
    if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
      memavl= min_sort_memory;
  }
  sort_keys= table_sort.sort_keys;
  if (memavl < min_sort_memory)
  {
    my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),
@@ -235,8 +238,12 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
  }
  else
  {
    if (!(buffpek=read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
    if (!table_sort.buffpek && table_sort.buffpek_len < maxbuffer &&
        !(table_sort.buffpek=
          (byte *) read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
      goto err;
    buffpek= (BUFFPEK *) table_sort.buffpek;
    table_sort.buffpek_len= maxbuffer;
    close_cached_file(&buffpek_pointers);
	/* Open cached file if it isn't open */
    if (! my_b_inited(outfile) &&
@@ -269,8 +276,14 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
 err:
  if (param.tmp_buffer)
    x_free(param.tmp_buffer);
  if (!subselect || !subselect->is_uncacheable())
  {
    x_free((gptr) sort_keys);
    table_sort.sort_keys= 0;
    x_free((gptr) buffpek);
    table_sort.buffpek= 0;
    table_sort.buffpek_len= 0;
  }
  close_cached_file(&tempfile);
  close_cached_file(&buffpek_pointers);
  if (my_b_inited(outfile))
@@ -301,13 +314,27 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
} /* filesort */


void filesort_free_buffers(TABLE *table)
void filesort_free_buffers(TABLE *table, bool full)
{
  if (table->sort.record_pointers)
  {
    my_free((gptr) table->sort.record_pointers,MYF(0));
    table->sort.record_pointers=0;
  }
  if (full)
  {
    if (table->sort.sort_keys )
    {
      x_free((gptr) table->sort.sort_keys);
      table->sort.sort_keys= 0;
    }
    if (table->sort.buffpek)
    {
      x_free((gptr) table->sort.buffpek);
      table->sort.buffpek= 0;
      table->sort.buffpek_len= 0;
    }
  }
  if (table->sort.addon_buf)
  {
    my_free((char *) table->sort.addon_buf, MYF(0));
+7 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ class Item_subselect :public Item_result_field
    single select and union subqueries only.
  */
  bool is_evaluated() const;
  bool is_uncacheable() const;

  /*
    Used by max/min subquery to initialize value presence registration
@@ -482,3 +483,9 @@ inline bool Item_subselect::is_evaluated() const
  return engine->is_executed();
}

inline bool Item_subselect::is_uncacheable() const
{
  return engine->uncacheable();
}

+1 −1
Original line number Diff line number Diff line
@@ -1475,7 +1475,7 @@ void end_read_record(READ_RECORD *info);
ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
		 uint s_length, SQL_SELECT *select,
		 ha_rows max_rows, ha_rows *examined_rows);
void filesort_free_buffers(TABLE *table);
void filesort_free_buffers(TABLE *table, bool full);
void change_double_for_sort(double nr,byte *to);
double my_double_round(double value, int dec, bool truncate);
int get_quick_record(SQL_SELECT *select);
Loading