Drizzled Public API Documentation

sel_tree.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/sql_base.h>
00023 #include <drizzled/sql_select.h>
00024 #include <drizzled/memory/sql_alloc.h>
00025 #include <drizzled/optimizer/range.h>
00026 #include <drizzled/optimizer/range_param.h>
00027 #include <drizzled/optimizer/sel_arg.h>
00028 #include <drizzled/optimizer/sel_tree.h>
00029 #include <drizzled/optimizer/sel_imerge.h>
00030 
00031 using namespace std;
00032 using namespace drizzled;
00033 
00034 static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
00035 static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
00036 
00037 bool optimizer::sel_trees_can_be_ored(const SEL_TREE& tree1, const SEL_TREE& tree2, const RangeParameter& param)
00038 {
00039   key_map common_keys= tree1.keys_map;
00040   common_keys&= tree2.keys_map;
00041 
00042   if (common_keys.none())
00043     return false;
00044 
00045   /* trees have a common key, check if they refer to same key part */
00046   for (uint32_t key_no= 0; key_no < param.keys; key_no++)
00047   {
00048     if (common_keys.test(key_no) && tree1.keys[key_no]->part == tree2.keys[key_no]->part)
00049       return true;
00050   }
00051   return false;
00052 }
00053 
00054 
00055 /*
00056   Perform OR operation on 2 index_merge lists, storing result in first list.
00057 
00058   NOTES
00059     The following conversion is implemented:
00060      (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
00061       => (a_1||b_1).
00062 
00063     i.e. all conjuncts except the first one are currently dropped.
00064     This is done to avoid producing N*K ways to do index_merge.
00065 
00066     If (a_1||b_1) produce a condition that is always true, NULL is returned
00067     and index_merge is discarded (while it is actually possible to try
00068     harder).
00069 
00070     As a consequence of this, choice of keys to do index_merge read may depend
00071     on the order of conditions in WHERE part of the query.
00072 
00073   RETURN
00074     0     OK, result is stored in *im1
00075     other Error, both passed lists are unusable
00076 */
00077 
00078 static int imerge_list_or_list(optimizer::RangeParameter *param, List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
00079 {
00080   optimizer::SEL_IMERGE *imerge= &im1->front();
00081   im1->clear();
00082   im1->push_back(imerge);
00083 
00084   return imerge->or_sel_imerge_with_checks(*param, im2->front());
00085 }
00086 
00087 
00088 /*
00089   Perform OR operation on index_merge list and key tree.
00090 
00091   RETURN
00092      0     OK, result is stored in *im1.
00093      other Error
00094  */
00095 
00096 static int imerge_list_or_tree(optimizer::RangeParameter& param, List<optimizer::SEL_IMERGE>& im1, optimizer::SEL_TREE& tree)
00097 {
00098   List_iterator<optimizer::SEL_IMERGE> it(im1.begin());
00099   while (optimizer::SEL_IMERGE* imerge= it++)
00100   {
00101     if (imerge->or_sel_tree_with_checks(param, tree))
00102       it.remove();
00103   }
00104   return im1.is_empty();
00105 }
00106 
00107 
00108 optimizer::SEL_TREE* optimizer::tree_or(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
00109 {
00110   if (! tree1 || ! tree2)
00111     return 0;
00112 
00113   if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
00114     return tree2;
00115 
00116   if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
00117     return tree1;
00118 
00119   if (tree1->type == SEL_TREE::MAYBE)
00120     return tree1; // Can't use this
00121 
00122   if (tree2->type == SEL_TREE::MAYBE)
00123     return tree2;
00124 
00125   SEL_TREE *result= NULL;
00126   key_map  result_keys;
00127   result_keys.reset();
00128   if (sel_trees_can_be_ored(*tree1, *tree2, *param))
00129   {
00130     /* Join the trees key per key */
00131     SEL_ARG** key1= tree1->keys;
00132     SEL_ARG** key2= tree2->keys;
00133     SEL_ARG** end= key1+param->keys;
00134     for (; key1 != end;  key1++, key2++)
00135     {
00136       *key1= key_or(param, *key1, *key2);
00137       if (*key1)
00138       {
00139         result= tree1; // Added to tree1
00140         result_keys.set(key1 - tree1->keys);
00141       }
00142     }
00143     if (result)
00144       result->keys_map= result_keys;
00145   }
00146   else
00147   {
00148     /* ok, two trees have KEY type but cannot be used without index merge */
00149     if (tree1->merges.is_empty() && tree2->merges.is_empty())
00150     {
00151       if (param->remove_jump_scans && (remove_nonrange_trees(param, tree1) || remove_nonrange_trees(param, tree2)))
00152         return new SEL_TREE(SEL_TREE::ALWAYS);
00153       /* both trees are "range" trees, produce new index merge structure */
00154       result= new SEL_TREE();
00155       SEL_IMERGE* merge= new SEL_IMERGE();
00156       result->merges.push_back(merge);
00157       merge->or_sel_tree(param, tree1);
00158       merge->or_sel_tree(param, tree2);
00159       result->type= tree1->type;
00160     }
00161     else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
00162     {
00163       result= imerge_list_or_list(param, &tree1->merges, &tree2->merges)
00164         ? new SEL_TREE(SEL_TREE::ALWAYS)
00165         : tree1;
00166     }
00167     else
00168     {
00169       /* one tree is index merge tree and another is range tree */
00170       if (tree1->merges.is_empty())
00171         std::swap(tree1, tree2);
00172 
00173       if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
00174          return new SEL_TREE(SEL_TREE::ALWAYS);
00175       /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
00176       result= imerge_list_or_tree(*param, tree1->merges, *tree2)
00177         ? new SEL_TREE(SEL_TREE::ALWAYS)
00178         : tree1;
00179     }
00180   }
00181   return result;
00182 }
00183 
00184 
00185 static optimizer::SEL_ARG *
00186 key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
00187 {
00188   if (! key1)
00189   {
00190     if (key2)
00191     {
00192       key2->use_count--;
00193       key2->free_tree();
00194     }
00195     return 0;
00196   }
00197   if (! key2)
00198   {
00199     key1->use_count--;
00200     key1->free_tree();
00201     return 0;
00202   }
00203   key1->use_count--;
00204   key2->use_count--;
00205 
00206   if (key1->part != key2->part)
00207   {
00208     key1->free_tree();
00209     key2->free_tree();
00210     return 0;         // Can't optimize this
00211   }
00212 
00213   // If one of the key is MAYBE_KEY then the found region may be bigger
00214   if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
00215   {
00216     key2->free_tree();
00217     key1->use_count++;
00218     return key1;
00219   }
00220   if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
00221   {
00222     key1->free_tree();
00223     key2->use_count++;
00224     return key2;
00225   }
00226 
00227   if (key1->use_count > 0)
00228   {
00229     if (key2->use_count == 0 || key1->elements > key2->elements)
00230     {
00231       std::swap(key1,key2);
00232     }
00233     if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
00234       return 0;         // OOM
00235   }
00236 
00237   // Add tree at key2 to tree at key1
00238   bool key2_shared= key2->use_count != 0;
00239   key1->maybe_flag|= key2->maybe_flag;
00240 
00241   for (key2=key2->first(); key2; )
00242   {
00243     optimizer::SEL_ARG *tmp= key1->find_range(key2); // Find key1.min <= key2.min
00244     int cmp;
00245 
00246     if (! tmp)
00247     {
00248       tmp=key1->first(); // tmp.min > key2.min
00249       cmp= -1;
00250     }
00251     else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
00252     {           // Found tmp.max < key2.min
00253       optimizer::SEL_ARG *next= tmp->next;
00254       if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
00255       {
00256         // Join near ranges like tmp.max < 0 and key2.min >= 0
00257         optimizer::SEL_ARG *key2_next=key2->next;
00258         if (key2_shared)
00259         {
00260           key2=new optimizer::SEL_ARG(*key2);
00261           key2->increment_use_count(key1->use_count+1);
00262           key2->next= key2_next; // New copy of key2
00263         }
00264         key2->copy_min(tmp);
00265         if (! (key1=key1->tree_delete(tmp)))
00266         {         // Only one key in tree
00267           key1= key2;
00268           key1->make_root();
00269           key2= key2_next;
00270           break;
00271         }
00272       }
00273       if (! (tmp= next)) // tmp.min > key2.min
00274         break; // Copy rest of key2
00275     }
00276     if (cmp < 0)
00277     {           // tmp.min > key2.min
00278       int tmp_cmp;
00279       if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
00280       {
00281         if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
00282         {         // ranges are connected
00283           tmp->copy_min_to_min(key2);
00284           key1->merge_flags(key2);
00285           if (tmp->min_flag & NO_MIN_RANGE &&
00286               tmp->max_flag & NO_MAX_RANGE)
00287           {
00288             if (key1->maybe_flag)
00289               return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
00290             return 0;
00291           }
00292           key2->increment_use_count(-1);  // Free not used tree
00293           key2= key2->next;
00294           continue;
00295         }
00296         else
00297         {
00298           optimizer::SEL_ARG *next= key2->next; // Keys are not overlapping
00299           if (key2_shared)
00300           {
00301             optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2); // Must make copy
00302             if (! cpy)
00303               return 0; // OOM
00304             key1= key1->insert(cpy);
00305             key2->increment_use_count(key1->use_count+1);
00306           }
00307           else
00308             key1= key1->insert(key2);   // Will destroy key2_root
00309           key2= next;
00310           continue;
00311         }
00312       }
00313     }
00314 
00315     // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
00316     if (eq_tree(tmp->next_key_part,key2->next_key_part))
00317     {
00318       if (tmp->is_same(key2))
00319       {
00320         tmp->merge_flags(key2);     // Copy maybe flags
00321         key2->increment_use_count(-1);    // Free not used tree
00322       }
00323       else
00324       {
00325         optimizer::SEL_ARG *last= tmp;
00326         while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
00327                eq_tree(last->next->next_key_part,key2->next_key_part))
00328         {
00329           optimizer::SEL_ARG *save= last;
00330           last= last->next;
00331           key1= key1->tree_delete(save);
00332         }
00333         last->copy_min(tmp);
00334         if (last->copy_min(key2) || last->copy_max(key2))
00335         {         // Full range
00336           key1->free_tree();
00337           for (; key2; key2= key2->next)
00338             key2->increment_use_count(-1);  // Free not used tree
00339           if (key1->maybe_flag)
00340             return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
00341           return 0;
00342         }
00343       }
00344       key2= key2->next;
00345       continue;
00346     }
00347 
00348     if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
00349     {           // tmp.min <= x < key2.min
00350       optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
00351       if ((new_arg->next_key_part= key1->next_key_part))
00352         new_arg->increment_use_count(key1->use_count+1);
00353       tmp->copy_min_to_min(key2);
00354       key1= key1->insert(new_arg);
00355     }
00356 
00357     // tmp.min >= key2.min && tmp.min <= key2.max
00358     optimizer::SEL_ARG key(*key2); // Get copy we can modify
00359     for (;;)
00360     {
00361       if (tmp->cmp_min_to_min(&key) > 0)
00362       {           // key.min <= x < tmp.min
00363         optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
00364         if ((new_arg->next_key_part=key.next_key_part))
00365           new_arg->increment_use_count(key1->use_count+1);
00366         key1= key1->insert(new_arg);
00367       }
00368       if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
00369       {           // tmp.min. <= x <= tmp.max
00370         tmp->maybe_flag|= key.maybe_flag;
00371         key.increment_use_count(key1->use_count+1);
00372         tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
00373         if (! cmp)        // Key2 is ready
00374           break;
00375         key.copy_max_to_min(tmp);
00376         if (! (tmp= tmp->next))
00377         {
00378           optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
00379           if (! tmp2)
00380             return 0;       // OOM
00381           key1= key1->insert(tmp2);
00382           key2= key2->next;
00383           goto end;
00384         }
00385         if (tmp->cmp_min_to_max(&key) > 0)
00386         {
00387           optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
00388           if (! tmp2)
00389             return 0;       // OOM
00390           key1= key1->insert(tmp2);
00391           break;
00392         }
00393       }
00394       else
00395       {
00396         optimizer::SEL_ARG *new_arg= tmp->clone_last(&key); // tmp.min <= x <= key.max
00397         tmp->copy_max_to_min(&key);
00398         tmp->increment_use_count(key1->use_count+1);
00399         /* Increment key count as it may be used for next loop */
00400         key.increment_use_count(1);
00401         new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
00402         key1= key1->insert(new_arg);
00403         break;
00404       }
00405     }
00406     key2= key2->next;
00407   }
00408 
00409 end:
00410   while (key2)
00411   {
00412     optimizer::SEL_ARG *next= key2->next;
00413     if (key2_shared)
00414     {
00415       optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2);   // Must make copy
00416       if (! tmp)
00417         return 0;
00418       key2->increment_use_count(key1->use_count+1);
00419       key1= key1->insert(tmp);
00420     }
00421     else
00422       key1= key1->insert(key2);     // Will destroy key2_root
00423     key2= next;
00424   }
00425   key1->use_count++;
00426   return key1;
00427 }
00428 
00429 
00430 /*
00431   Remove the trees that are not suitable for record retrieval.
00432   SYNOPSIS
00433     param  Range analysis parameter
00434     tree   Tree to be processed, tree->type is KEY or KEY_SMALLER
00435 
00436   DESCRIPTION
00437     This function walks through tree->keys[] and removes the SEL_ARG* trees
00438     that are not "maybe" trees (*) and cannot be used to construct quick range
00439     selects.
00440     (*) - have type MAYBE or MAYBE_KEY. Perhaps we should remove trees of
00441           these types here as well.
00442 
00443     A SEL_ARG* tree cannot be used to construct quick select if it has
00444     tree->part != 0. (e.g. it could represent "keypart2 < const").
00445 
00446     WHY THIS FUNCTION IS NEEDED
00447 
00448     Normally we allow construction of optimizer::SEL_TREE objects that have SEL_ARG
00449     trees that do not allow quick range select construction. For example for
00450     " keypart1=1 AND keypart2=2 " the execution will proceed as follows:
00451     tree1= optimizer::SEL_TREE { SEL_ARG{keypart1=1} }
00452     tree2= optimizer::SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
00453                                                from this
00454     call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
00455                                    tree.
00456 
00457     There is an exception though: when we construct index_merge optimizer::SEL_TREE,
00458     any SEL_ARG* tree that cannot be used to construct quick range select can
00459     be removed, because current range analysis code doesn't provide any way
00460     that tree could be later combined with another tree.
00461     Consider an example: we should not construct
00462     st1 = optimizer::SEL_TREE {
00463       merges = SEL_IMERGE {
00464                             optimizer::SEL_TREE(t.key1part1 = 1),
00465                             optimizer::SEL_TREE(t.key2part2 = 2)   -- (*)
00466                           }
00467                    };
00468     because
00469      - (*) cannot be used to construct quick range select,
00470      - There is no execution path that would cause (*) to be converted to
00471        a tree that could be used.
00472 
00473     The latter is easy to verify: first, notice that the only way to convert
00474     (*) into a usable tree is to call tree_and(something, (*)).
00475 
00476     Second look at what tree_and/tree_or function would do when passed a
00477     optimizer::SEL_TREE that has the structure like st1 tree has, and conlcude that
00478     tree_and(something, (*)) will not be called.
00479 
00480   RETURN
00481     0  Ok, some suitable trees left
00482     1  No tree->keys[] left.
00483 */
00484 bool optimizer::remove_nonrange_trees(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree)
00485 {
00486   bool res= true;
00487   for (uint32_t i= 0; i < param->keys; i++)
00488   {
00489     if (tree->keys[i])
00490     {
00491       if (tree->keys[i]->part)
00492       {
00493         tree->keys[i]= NULL;
00494         tree->keys_map.reset(i);
00495       }
00496       else
00497         res= false;
00498     }
00499   }
00500   return res;
00501 }
00502 
00503 
00504 /* Compare if two trees are equal */
00505 static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
00506 {
00507   if (a == b)
00508     return true;
00509 
00510   if (! a || ! b || ! a->is_same(b))
00511   {
00512     return false;
00513   }
00514 
00515   if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
00516   {
00517     if (! eq_tree(a->left,b->left))
00518       return false;
00519   }
00520   else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
00521   {
00522     return false;
00523   }
00524 
00525   if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
00526   {
00527     if (! eq_tree(a->right,b->right))
00528       return false;
00529   }
00530   else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
00531   {
00532     return false;
00533   }
00534 
00535   if (a->next_key_part != b->next_key_part)
00536   {           // Sub range
00537     if (! a->next_key_part != ! b->next_key_part ||
00538         ! eq_tree(a->next_key_part, b->next_key_part))
00539       return false;
00540   }
00541 
00542   return true;
00543 }