List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:January 5 2006 11:09pm
Subject:bk commit into 5.1 tree (sergefp:1.2021)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of psergey. When psergey 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.2021 06/01/06 02:09:48 sergefp@stripped +5 -0
  WL#2682: 
  - make prune_partitions() assume that part_info->used_partitions holds a bitmap of 
    partitions to be used when it is invoked.
  - Added a few test cases
  - Some small fixes in other parts so those cases pass.

  sql/opt_range.cc
    1.193 06/01/06 02:09:33 sergefp@stripped +45 -19
    WL#2682: make prune_partitions() assume that part_info->used_partitions holds a bitmap of 
      partitions to be used when it is invoked.

  sql/handler.h
    1.176 06/01/06 02:09:33 sergefp@stripped +2 -1
    WL#2682: fix out of date comments

  sql/ha_partition.cc
    1.27 06/01/06 02:09:33 sergefp@stripped +2 -1
    WL#2682:
    * Make set_specific_partition() clear everything else (it seems to be needed when called from its 
      current location)
    * Make ha_partition::rnd_next() return ERR_END_OF_FILE when there are no partitions used (and
      not fail an assert), just as promised in ha_partition::rnd_init()

  mysql-test/t/partition_select.test
    1.2 06/01/06 02:09:33 sergefp@stripped +13 -0
    WL#2682: 
     - Added first testcases of partition selection and partition pruning working together,
     - Updated existing test results (here is prunining at work)

  mysql-test/r/partition_select.result
    1.2 06/01/06 02:09:33 sergefp@stripped +16 -2
    WL#2682: 
     - Added first testcases of partition selection and partition pruning working together,
     - Updated existing test results (here is prunining at work)

# 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:	sergefp
# Host:	newbox.mylan
# Root:	/home/psergey/mysql-5.1-wl2682

--- 1.175/sql/handler.h	2005-12-29 02:32:24 +03:00
+++ 1.176/sql/handler.h	2006-01-06 02:09:33 +03:00
@@ -591,7 +591,8 @@
   /* 
     A bitmap of partitions used by the current query. 
     Usage pattern:
-    * It is guaranteed that all partitions are set to be unused on query start.
+    TODO: To be clarified when WL#2682 completes. The below is likely to be
+    wrong:
     * Before index/rnd_init(), partition pruning code sets the bits for used
       partitions.
     * The handler->extra(HA_EXTRA_RESET) call at query end sets all partitions

--- 1.192/sql/opt_range.cc	2006-01-01 02:28:06 +03:00
+++ 1.193/sql/opt_range.cc	2006-01-06 02:09:33 +03:00
@@ -2257,11 +2257,15 @@
       pprune_cond   Condition to use for partition pruning
   
   DESCRIPTION
-    This function assumes that all partitions are marked as unused when it
-    is invoked. The function analyzes the condition, finds partitions that
-    need to be used to retrieve the records that match the condition, and 
-    marks them as used by setting appropriate bit in part_info->used_partitions
-    In the worst case all partitions are marked as used.
+    This function assumes that at the time of its invocation, the 
+    part_info->used_partitions bitmap contains a bitmap of partitions to be
+    used in the query (normally all bits are set, if use of some partitions
+    is explicitly specified, then only some of the bits are set).
+    
+    The function analyzes the condition, and finds partitions that need to be
+    used to retrieve the records that match the condition, and leaves the
+    part_info->used_partitions bitmap to contain only partitions that were
+    specified to be used, and actually need to be used.
 
   NOTE
     This function returns promptly if called for non-partitioned table.
@@ -2282,10 +2286,7 @@
     DBUG_RETURN(FALSE); /* not a partitioned table */
 
   if (!pprune_cond)
-  {
-    mark_all_partitions_as_used(part_info);
-    DBUG_RETURN(FALSE);
-  }
+    DBUG_RETURN(FALSE); /* Leave the used_partitions bitmap as is */
 
   PART_PRUNE_PARAM prune_param;
   MEM_ROOT alloc;
@@ -2299,7 +2300,6 @@
 
   if (create_partition_index_descrition(&prune_param))
   {
-    mark_all_partitions_as_used(part_info);
     free_root(&alloc,MYF(0));		// Return memory & allocator
     DBUG_RETURN(FALSE);
   }
@@ -2321,21 +2321,40 @@
   prune_param.key= prune_param.range_param.key_parts;
   SEL_TREE *tree;
   SEL_ARG *arg;
+  MY_BITMAP used_partitions_bck;
+  uint bitmap_bytes;
   int res;
 
   tree= get_mm_tree(range_par, pprune_cond);
   if (!tree)
-    goto all_used;
+    goto all_used_no_clear;
 
   if (tree->type == SEL_TREE::IMPOSSIBLE)
   {
+    bitmap_clear_all(&part_info->used_partitions);
     retval= TRUE;
     goto end;
   }
 
   if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
-    goto all_used;
+    goto all_used_no_clear;
    
+  /* Allocate a bitmap of the same size as table->used_partitions.*/
+  {
+    uint n_bits= part_info->used_partitions.n_bits;
+    bitmap_bytes= bitmap_buffer_size(n_bits);
+    uint32 *bitmap_buf;
+    if (!(bitmap_buf= (uint32*)alloc_root(&alloc, bitmap_bytes)))
+    {
+      goto all_used_no_clear;
+    }
+    bitmap_init(&used_partitions_bck, bitmap_buf, n_bits, FALSE);
+    memcpy(used_partitions_bck.bitmap, part_info->used_partitions.bitmap,
+           bitmap_bytes);
+    bitmap_clear_all(&part_info->used_partitions);
+  }
+   
+  //todo: alloc a 'backup' mem_root here..
   if (tree->merges.is_empty())
   {
     prune_param.arg_stack_end= prune_param.arg_stack;
@@ -2369,12 +2388,23 @@
     res == 1 => some used partitions => retval=FALSE
     res == -1 - we jump over this line to all_used:
   */
-  retval= test(!res);
+  if (res)
+  {
+    //intersect
+    bitmap_intersect(&part_info->used_partitions, &used_partitions_bck);
+    if (bitmap_is_clear_all(&part_info->used_partitions))
+      retval= TRUE;
+  }
+  else
+    retval= TRUE;
   goto end;
 
 all_used:
+  /* put the original bitmap back */
+  memcpy(part_info->used_partitions.bitmap, used_partitions_bck.bitmap,
+         bitmap_bytes);
+all_used_no_clear:
   retval= FALSE; // some partitions are used
-  mark_all_partitions_as_used(prune_param.part_info);
 end:
   thd->no_errors=0;
   thd->mem_root= range_par->old_root;
@@ -2806,11 +2836,7 @@
 
 static void mark_all_partitions_as_used(partition_info *part_info)
 {
-  DBUG_ENTER("mark_all_partitions_as_used");
-  DBUG_PRINT("info", ("used_partitions %lx", part_info->used_partitions));
-  // REMOVE AFTER PSERGEY FIX!!!!
-  //bitmap_set_all(&part_info->used_partitions);
-  DBUG_VOID_RETURN;
+  bitmap_set_all(&part_info->used_partitions);
 }
 
 

--- 1.26/sql/ha_partition.cc	2006-01-04 05:11:50 +03:00
+++ 1.27/sql/ha_partition.cc	2006-01-06 02:09:33 +03:00
@@ -1194,6 +1194,7 @@
   }
 
   DBUG_PRINT("info", ("selected partition %s is in table", partition_name));
+  bitmap_clear_all(&m_part_info->used_partitions);
   while (el != NULL)
   {
     bitmap_set_bit(&(m_part_info->used_partitions), el->index);
@@ -1636,7 +1637,6 @@
   DBUG_ENTER("ha_partition::rnd_next");
   DBUG_PRINT("info", ("m_scan_value %d", m_scan_value));
 
-  DBUG_ASSERT(m_scan_value == 1);
 
   if (MY_BIT_NONE == current_partition_index)
   {
@@ -1647,6 +1647,7 @@
     goto end;
   }
   
+  DBUG_ASSERT(m_scan_value == 1);
   file= m_file[current_partition_index];
   
   while (TRUE)

--- 1.1/mysql-test/r/partition_select.result	2006-01-01 02:28:06 +03:00
+++ 1.2/mysql-test/r/partition_select.result	2006-01-06 02:09:33 +03:00
@@ -61,7 +61,6 @@
 20
 SELECT * FROM t1 PARTITION (p3) WHERE id = 2;
 id
-2
 SELECT * FROM t1 PARTITION (foo);
 ERROR HY000: partition 'foo' doesn't exist
 CREATE TABLE `t2` (
@@ -127,6 +126,21 @@
 20
 SELECT * FROM t2 PARTITION (p3) WHERE id = 2;
 id
-2
 SELECT * FROM t2 PARTITION (foo);
 ERROR HY000: partition 'foo' doesn't exist
+drop table t1,t2;
+create table t1 (a int) partition by hash(a) partitions 3;
+insert into t1 values(1),(2),(3);
+explain partitions select * from t1 where a=1;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	3	Using where
+explain partitions select * from t1 partition (p1) where a=1;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	3	Using where
+explain partitions select * from t1 partition (p1) where a=1 or a=2;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	3	Using where
+explain partitions select * from t1 partition (p2) where a=1;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+drop table t1;

--- 1.1/mysql-test/t/partition_select.test	2006-01-01 02:28:06 +03:00
+++ 1.2/mysql-test/t/partition_select.test	2006-01-06 02:09:33 +03:00
@@ -51,3 +51,16 @@
 SELECT * FROM t2 PARTITION (p3) WHERE id = 2;
 --error 1501
 SELECT * FROM t2 PARTITION (foo);
+
+drop table t1,t2;
+
+# Tests for working together with partition pruning.
+create table t1 (a int) partition by hash(a) partitions 3;
+insert into t1 values(1),(2),(3);
+explain partitions select * from t1 where a=1;
+explain partitions select * from t1 partition (p1) where a=1;
+explain partitions select * from t1 partition (p1) where a=1 or a=2;
+explain partitions select * from t1 partition (p2) where a=1;
+
+drop table t1;
+
Thread
bk commit into 5.1 tree (sergefp:1.2021)Sergey Petrunia6 Jan