opt_range.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:67k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /*
  14.   TODO:
  15.   Fix that MAYBE_KEY are stored in the tree so that we can detect use
  16.   of full hash keys for queries like:
  17.   select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205);
  18. */
  19. #ifdef __GNUC__
  20. #pragma implementation // gcc: Class implementation
  21. #endif
  22. #include "mysql_priv.h"
  23. #include <m_ctype.h>
  24. #include <nisam.h>
  25. #include "sql_select.h"
  26. #ifndef EXTRA_DEBUG
  27. #define test_rb_tree(A,B) {}
  28. #define test_use_count(A) {}
  29. #endif
  30. static int sel_cmp(Field *f,char *a,char *b,uint8 a_flag,uint8 b_flag);
  31. static char is_null_string[2]= {1,0};
  32. class SEL_ARG :public Sql_alloc
  33. {
  34. public:
  35.   uint8 min_flag,max_flag,maybe_flag;
  36.   uint8 part; // Which key part
  37.   uint8 maybe_null;
  38.   uint16 elements; // Elements in tree
  39.   ulong use_count; // use of this sub_tree
  40.   Field *field;
  41.   char *min_value,*max_value; // Pointer to range
  42.   SEL_ARG *left,*right,*next,*prev,*parent,*next_key_part;
  43.   enum leaf_color { BLACK,RED } color;
  44.   enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
  45.   SEL_ARG() {}
  46.   SEL_ARG(SEL_ARG &);
  47.   SEL_ARG(Field *,const char *,const char *);
  48.   SEL_ARG(Field *field, uint8 part, char *min_value, char *max_value,
  49.   uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
  50.   SEL_ARG(enum Type type_arg)
  51.     :elements(1),use_count(1),left(0),next_key_part(0),type(type_arg) {}
  52.   inline bool is_same(SEL_ARG *arg)
  53.   {
  54.     if (type != arg->type)
  55.       return 0;
  56.     if (type != KEY_RANGE)
  57.       return 1;
  58.     return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
  59.   }
  60.   inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
  61.   inline void maybe_smaller() { maybe_flag=1; }
  62.   inline int cmp_min_to_min(SEL_ARG* arg)
  63.   {
  64.     return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
  65.   }
  66.   inline int cmp_min_to_max(SEL_ARG* arg)
  67.   {
  68.     return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
  69.   }
  70.   inline int cmp_max_to_max(SEL_ARG* arg)
  71.   {
  72.     return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
  73.   }
  74.   inline int cmp_max_to_min(SEL_ARG* arg)
  75.   {
  76.     return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
  77.   }
  78.   SEL_ARG *clone_and(SEL_ARG* arg)
  79.   { // Get overlapping range
  80.     char *new_min,*new_max;
  81.     uint8 flag_min,flag_max;
  82.     if (cmp_min_to_min(arg) >= 0)
  83.     {
  84.       new_min=min_value; flag_min=min_flag;
  85.     }
  86.     else
  87.     {
  88.       new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
  89.     }
  90.     if (cmp_max_to_max(arg) <= 0)
  91.     {
  92.       new_max=max_value; flag_max=max_flag;
  93.     }
  94.     else
  95.     {
  96.       new_max=arg->max_value; flag_max=arg->max_flag;
  97.     }
  98.     return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
  99.        test(maybe_flag && arg->maybe_flag));
  100.   }
  101.   SEL_ARG *clone_first(SEL_ARG *arg)
  102.   { // min <= X < arg->min
  103.     return new SEL_ARG(field,part, min_value, arg->min_value,
  104.        min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
  105.        maybe_flag | arg->maybe_flag);
  106.   }
  107.   SEL_ARG *clone_last(SEL_ARG *arg)
  108.   { // min <= X <= key_max
  109.     return new SEL_ARG(field, part, min_value, arg->max_value,
  110.        min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
  111.   }
  112.   SEL_ARG *clone(SEL_ARG *new_parent,SEL_ARG **next);
  113.   bool copy_min(SEL_ARG* arg)
  114.   { // Get overlapping range
  115.     if (cmp_min_to_min(arg) > 0)
  116.     {
  117.       min_value=arg->min_value; min_flag=arg->min_flag;
  118.       if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
  119.   (NO_MAX_RANGE | NO_MIN_RANGE))
  120. return 1; // Full range
  121.     }
  122.     maybe_flag|=arg->maybe_flag;
  123.     return 0;
  124.   }
  125.   bool copy_max(SEL_ARG* arg)
  126.   { // Get overlapping range
  127.     if (cmp_max_to_max(arg) <= 0)
  128.     {
  129.       max_value=arg->max_value; max_flag=arg->max_flag;
  130.       if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
  131.   (NO_MAX_RANGE | NO_MIN_RANGE))
  132. return 1; // Full range
  133.     }
  134.     maybe_flag|=arg->maybe_flag;
  135.     return 0;
  136.   }
  137.   void copy_min_to_min(SEL_ARG *arg)
  138.   {
  139.     min_value=arg->min_value; min_flag=arg->min_flag;
  140.   }
  141.   void copy_min_to_max(SEL_ARG *arg)
  142.   {
  143.     max_value=arg->min_value;
  144.     max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
  145.   }
  146.   void copy_max_to_min(SEL_ARG *arg)
  147.   {
  148.     min_value=arg->max_value;
  149.     min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
  150.   }
  151.   void store(uint length,char **min_key,uint min_key_flag,
  152.      char **max_key, uint max_key_flag)
  153.   {
  154.     if (!(min_flag & NO_MIN_RANGE) &&
  155. !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
  156.     {
  157.       if (maybe_null && *min_value)
  158.       {
  159. **min_key=1;
  160. bzero(*min_key+1,length);
  161.       }
  162.       else
  163. memcpy(*min_key,min_value,length+(int) maybe_null);
  164.       (*min_key)+= length+(int) maybe_null;
  165.     }
  166.     if (!(max_flag & NO_MAX_RANGE) &&
  167. !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
  168.     {
  169.       if (maybe_null && *max_value)
  170.       {
  171. **max_key=1;
  172. bzero(*max_key+1,length);
  173.       }
  174.       else
  175. memcpy(*max_key,max_value,length+(int) maybe_null);
  176.       (*max_key)+= length+(int) maybe_null;
  177.     }
  178.   }
  179.   void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
  180.   {
  181.     SEL_ARG *key_tree= first();
  182.     key_tree->store(key[key_tree->part].part_length,
  183.     range_key,*range_key_flag,range_key,NO_MAX_RANGE);
  184.     *range_key_flag|= key_tree->min_flag;
  185.     if (key_tree->next_key_part &&
  186. key_tree->next_key_part->part == key_tree->part+1 &&
  187. !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
  188. key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
  189.       key_tree->next_key_part->store_min_key(key,range_key, range_key_flag);
  190.   }
  191.   void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
  192.   {
  193.     SEL_ARG *key_tree= last();
  194.     key_tree->store(key[key_tree->part].part_length,
  195.     range_key, NO_MIN_RANGE, range_key,*range_key_flag);
  196.     (*range_key_flag)|= key_tree->max_flag;
  197.     if (key_tree->next_key_part &&
  198. key_tree->next_key_part->part == key_tree->part+1 &&
  199. !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
  200. key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
  201.       key_tree->next_key_part->store_max_key(key,range_key, range_key_flag);
  202.   }
  203.   SEL_ARG *insert(SEL_ARG *key);
  204.   SEL_ARG *tree_delete(SEL_ARG *key);
  205.   SEL_ARG *find_range(SEL_ARG *key);
  206.   SEL_ARG *rb_insert(SEL_ARG *leaf);
  207.   friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
  208. #ifdef EXTRA_DEBUG
  209.   friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
  210.   void test_use_count(SEL_ARG *root);
  211. #endif
  212.   SEL_ARG *first();
  213.   SEL_ARG *last();
  214.   void make_root();
  215.   inline bool simple_key()
  216.   {
  217.     return !next_key_part && elements == 1;
  218.   }
  219.   void increment_use_count(long count)
  220.   {
  221.     if (next_key_part)
  222.     {
  223.       next_key_part->use_count+=count;
  224.       count*= (next_key_part->use_count-count);
  225.       for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
  226. if (pos->next_key_part)
  227.   pos->increment_use_count(count);
  228.     }
  229.   }
  230.   void free_tree()
  231.   {
  232.     for (SEL_ARG *pos=first(); pos ; pos=pos->next)
  233.       if (pos->next_key_part)
  234.       {
  235. pos->next_key_part->use_count--;
  236. pos->next_key_part->free_tree();
  237.       }
  238.   }
  239.   inline SEL_ARG **parent_ptr()
  240.   {
  241.     return parent->left == this ? &parent->left : &parent->right;
  242.   }
  243.   SEL_ARG *clone_tree();
  244. };
  245. class SEL_TREE :public Sql_alloc
  246. {
  247. public:
  248.   enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
  249.   SEL_TREE(enum Type type_arg) :type(type_arg) {}
  250.   SEL_TREE() :type(KEY) { bzero((char*) keys,sizeof(keys));}
  251.   SEL_ARG *keys[MAX_KEY];
  252. };
  253. typedef struct st_qsel_param {
  254.   uint baseflag,keys,max_key_part;
  255.   table_map prev_tables,read_tables,current_table;
  256.   TABLE *table;
  257.   bool quick; // Don't calulate possible keys
  258.   KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
  259.   uint real_keynr[MAX_KEY];
  260.   char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
  261.     max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
  262. } PARAM;
  263. static SEL_TREE * get_mm_parts(PARAM *param,Field *field,
  264.        Item_func::Functype type,Item *value,
  265.        Item_result cmp_type);
  266. static SEL_ARG *get_mm_leaf(Field *field,KEY_PART *key_part,
  267.     Item_func::Functype type,Item *value);
  268. static bool like_range(const char *ptr,uint length,char wild_prefix,
  269.        uint field_length, char *min_str,char *max_str,
  270.        char max_sort_char,uint *min_length,uint *max_length);
  271. static SEL_TREE *get_mm_tree(PARAM *param,COND *cond);
  272. static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree);
  273. static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
  274. char *min_key,uint min_key_flag,
  275. char *max_key, uint max_key_flag);
  276. static QUICK_SELECT *get_quick_select(PARAM *param,uint index,
  277.       SEL_ARG *key_tree);
  278. #ifndef DBUG_OFF
  279. static void print_quick(QUICK_SELECT *quick,key_map needed_reg);
  280. #endif
  281. static SEL_TREE *tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
  282. static SEL_TREE *tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
  283. static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
  284. static SEL_ARG *key_or(SEL_ARG *key1,SEL_ARG *key2);
  285. static SEL_ARG *key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag);
  286. static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
  287. static bool get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
  288.    SEL_ARG *key_tree,char *min_key,uint min_key_flag,
  289.    char *max_key,uint max_key_flag);
  290. static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
  291. static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
  292. /***************************************************************************
  293. ** Basic functions for SQL_SELECT and QUICK_SELECT
  294. ***************************************************************************/
  295. /* make a select from mysql info
  296.    Error is set as following:
  297.    0 = ok
  298.    1 = Got some error (out of memory?)
  299.    */
  300. SQL_SELECT *make_select(TABLE *head, table_map const_tables,
  301. table_map read_tables, COND *conds, int *error)
  302. {
  303.   SQL_SELECT *select;
  304.   DBUG_ENTER("make_select");
  305.   *error=0;
  306.   if (!conds)
  307.     DBUG_RETURN(0);
  308.   if (!(select= new SQL_SELECT))
  309.   {
  310.     *error= 1;
  311.     DBUG_RETURN(0); /* purecov: inspected */
  312.   }
  313.   select->read_tables=read_tables;
  314.   select->const_tables=const_tables;
  315.   select->head=head;
  316.   select->cond=conds;
  317.   if (head->io_cache)
  318.   {
  319.     select->file= *head->io_cache;
  320.     select->records=(ha_rows) (select->file.end_of_file/
  321.        head->file->ref_length);
  322.     my_free((gptr) (head->io_cache),MYF(0));
  323.     head->io_cache=0;
  324.   }
  325.   DBUG_RETURN(select);
  326. }
  327. SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
  328. {
  329.   quick_keys=0; needed_reg=0;
  330.   my_b_clear(&file);
  331. }
  332. SQL_SELECT::~SQL_SELECT()
  333. {
  334.   delete quick;
  335.   if (free_cond)
  336.     delete cond;
  337.   close_cached_file(&file);
  338. }
  339. #undef index // Fix for Unixware 7
  340. QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
  341.   :error(0),index(key_nr),max_used_key_length(0),head(table),
  342.    it(ranges),range(0)
  343. {
  344.   if (!no_alloc)
  345.   {
  346.     init_sql_alloc(&alloc,1024,0); // Allocates everything here
  347.     my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
  348.   }
  349.   else
  350.     bzero((char*) &alloc,sizeof(alloc));
  351.   file=head->file;
  352.   record=head->record[0];
  353.   init();
  354. }
  355. QUICK_SELECT::~QUICK_SELECT()
  356. {
  357.   file->index_end();
  358.   free_root(&alloc,MYF(0));
  359. }
  360. int QUICK_SELECT::init()
  361. {
  362.   return error=file->index_init(index);
  363. }
  364. QUICK_RANGE::QUICK_RANGE()
  365.   :min_key(0),max_key(0),min_length(0),max_length(0),
  366.    flag(NO_MIN_RANGE | NO_MAX_RANGE)
  367. {}
  368. SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
  369. {
  370.   type=arg.type;
  371.   min_flag=arg.min_flag;
  372.   max_flag=arg.max_flag;
  373.   maybe_flag=arg.maybe_flag;
  374.   maybe_null=arg.maybe_null;
  375.   part=arg.part;
  376.   field=arg.field;
  377.   min_value=arg.min_value;
  378.   max_value=arg.max_value;
  379.   next_key_part=arg.next_key_part;
  380.   use_count=1; elements=1;
  381. }
  382. inline void SEL_ARG::make_root()
  383. {
  384.   left=right= &null_element;
  385.   color=BLACK;
  386.   next=prev=0;
  387.   use_count=0; elements=1;
  388. }
  389. SEL_ARG::SEL_ARG(Field *f,const char *min_value_arg,const char *max_value_arg)
  390.   :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
  391.    elements(1), use_count(1), field(f), min_value((char*) min_value_arg),
  392.    max_value((char*) max_value_arg), next(0),prev(0),
  393.    next_key_part(0),color(BLACK),type(KEY_RANGE)
  394. {
  395.   left=right= &null_element;
  396. }
  397. SEL_ARG::SEL_ARG(Field *field_,uint8 part_,char *min_value_,char *max_value_,
  398.  uint8 min_flag_,uint8 max_flag_,uint8 maybe_flag_)
  399.   :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
  400.    part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
  401.    field(field_), min_value(min_value_), max_value(max_value_),
  402.    next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
  403. {
  404.   left=right= &null_element;
  405. }
  406. SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
  407. {
  408.   SEL_ARG *tmp;
  409.   if (type != KEY_RANGE)
  410.   {
  411.     tmp=new SEL_ARG(type);
  412.     tmp->prev= *next_arg; // Link into next/prev chain
  413.     (*next_arg)->next=tmp;
  414.     (*next_arg)= tmp;
  415.   }
  416.   else
  417.   {
  418.     tmp=new SEL_ARG(field,part, min_value,max_value,
  419.     min_flag, max_flag, maybe_flag);
  420.     tmp->parent=new_parent;
  421.     tmp->next_key_part=next_key_part;
  422.     if (left != &null_element)
  423.       tmp->left=left->clone(tmp,next_arg);
  424.     tmp->prev= *next_arg; // Link into next/prev chain
  425.     (*next_arg)->next=tmp;
  426.     (*next_arg)= tmp;
  427.     if (right != &null_element)
  428.       tmp->right=right->clone(tmp,next_arg);
  429.   }
  430.   increment_use_count(1);
  431.   return tmp;
  432. }
  433. SEL_ARG *SEL_ARG::first()
  434. {
  435.   SEL_ARG *next_arg=this;
  436.   if (!next_arg->left)
  437.     return 0; // MAYBE_KEY
  438.   while (next_arg->left != &null_element)
  439.     next_arg=next_arg->left;
  440.   return next_arg;
  441. }
  442. SEL_ARG *SEL_ARG::last()
  443. {
  444.   SEL_ARG *next_arg=this;
  445.   if (!next_arg->right)
  446.     return 0; // MAYBE_KEY
  447.   while (next_arg->right != &null_element)
  448.     next_arg=next_arg->right;
  449.   return next_arg;
  450. }
  451. /*
  452.   Check if a compare is ok, when one takes ranges in account
  453.   Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
  454.  */
  455. static int sel_cmp(Field *field, char *a,char *b,uint8 a_flag,uint8 b_flag)
  456. {
  457.   int cmp;
  458.   /* First check if there was a compare to a min or max element */
  459.   if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
  460.   {
  461.     if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
  462. (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
  463.       return 0;
  464.     return (a_flag & NO_MIN_RANGE) ? -1 : 1;
  465.   }
  466.   if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
  467.     return (b_flag & NO_MIN_RANGE) ? 1 : -1;
  468.   if (field->real_maybe_null()) // If null is part of key
  469.   {
  470.     if (*a != *b)
  471.     {
  472.       return *a ? -1 : 1;
  473.     }
  474.     if (*a)
  475.       goto end; // NULL where equal
  476.     a++; b++; // Skipp NULL marker
  477.   }
  478.   cmp=field->key_cmp((byte*) a,(byte*) b);
  479.   if (cmp) return cmp < 0 ? -1 : 1; // The values differed
  480.   // Check if the compared equal arguments was defined with open/closed range
  481.  end:
  482.   if (a_flag & (NEAR_MIN | NEAR_MAX))
  483.   {
  484.     if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
  485.       return 0;
  486.     if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
  487.       return (a_flag & NEAR_MIN) ? 2 : -2;
  488.     return (a_flag & NEAR_MIN) ? 1 : -1;
  489.   }
  490.   if (b_flag & (NEAR_MIN | NEAR_MAX))
  491.     return (b_flag & NEAR_MIN) ? -2 : 2;
  492.   return 0; // The elements where equal
  493. }
  494. SEL_ARG *SEL_ARG::clone_tree()
  495. {
  496.   SEL_ARG tmp_link,*next_arg,*root;
  497.   next_arg= &tmp_link;
  498.   root=clone((SEL_ARG *) 0, &next_arg);
  499.   next_arg->next=0; // Fix last link
  500.   tmp_link.next->prev=0; // Fix first link
  501.   root->use_count=0;
  502.   return root;
  503. }
  504. /*****************************************************************************
  505. ** Test if a key can be used in different ranges
  506. ** Returns:
  507. ** -1 if impossible select
  508. ** 0 if can't use quick_select
  509. ** 1 if found usable range
  510. ** Updates the following in the select parameter:
  511. ** needed_reg ; Bits for keys with may be used if all prev regs are read
  512. ** quick    ; Parameter to use when reading records.
  513. ** In the table struct the following information is updated:
  514. ** quick_keys ; Which keys can be used
  515. ** quick_rows ; How many rows the key matches
  516. *****************************************************************************/
  517. int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
  518.   ha_rows limit, bool force_quick_range)
  519. {
  520.   uint basflag;
  521.   uint idx;
  522.   double scan_time;
  523.   DBUG_ENTER("test_quick_select");
  524.   delete quick;
  525.   quick=0;
  526.   needed_reg=0; quick_keys=0;
  527.   if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
  528.       !limit)
  529.     DBUG_RETURN(0); /* purecov: inspected */
  530.   if (!((basflag= head->file->option_flag()) & HA_KEYPOS_TO_RNDPOS) &&
  531.       keys_to_use == (uint) ~0 || !keys_to_use)
  532.     DBUG_RETURN(0); /* Not smart database */
  533.   records=head->file->records;
  534.   if (!records)
  535.     records++; /* purecov: inspected */
  536.   scan_time=(double) records / TIME_FOR_COMPARE+1;
  537.   read_time=(double) head->file->scan_time()+ scan_time + 1.0;
  538.   if (limit < records)
  539.     read_time=(double) records+scan_time+1; // Force to use index
  540.   else if (read_time <= 2.0 && !force_quick_range)
  541.     DBUG_RETURN(0); /* No nead for quick select */
  542.   DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
  543.   keys_to_use&=head->keys_in_use_for_query;
  544.   if (keys_to_use)
  545.   {
  546.     MEM_ROOT *old_root,alloc;
  547.     SEL_TREE *tree;
  548.     KEY_PART *key_parts;
  549.     PARAM param;
  550.     /* set up parameter that is passed to all functions */
  551.     param.baseflag=basflag;
  552.     param.prev_tables=prev_tables | const_tables;
  553.     param.read_tables=read_tables;
  554.     param.current_table= head->map;
  555.     param.table=head;
  556.     param.keys=0;
  557.     current_thd->no_errors=1; // Don't warn about NULL
  558.     init_sql_alloc(&alloc,2048,0);
  559.     if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc,
  560.    sizeof(KEY_PART)*
  561.    head->key_parts)))
  562.     {
  563.       current_thd->no_errors=0;
  564.       free_root(&alloc,MYF(0)); // Return memory & allocator
  565.       DBUG_RETURN(0); // Can't use range
  566.     }
  567.     key_parts= param.key_parts;
  568.     old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
  569.     my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
  570.     for (idx=0 ; idx < head->keys ; idx++)
  571.     {
  572.       if (!(keys_to_use & ((key_map) 1L << idx)))
  573. continue;
  574.       KEY *key_info= &head->key_info[idx];
  575.       if (key_info->flags & HA_FULLTEXT)
  576. continue;    // ToDo: ft-keys in non-ft ranges, if possible   SerG
  577.       param.key[param.keys]=key_parts;
  578.       for (uint part=0 ; part < key_info->key_parts ; part++,key_parts++)
  579.       {
  580. key_parts->key=param.keys;
  581. key_parts->part=part;
  582. key_parts->part_length= key_info->key_part[part].length;
  583. key_parts->field=    key_info->key_part[part].field;
  584. key_parts->null_bit= key_info->key_part[part].null_bit;
  585. if (key_parts->field->type() == FIELD_TYPE_BLOB)
  586.   key_parts->part_length+=HA_KEY_BLOB_LENGTH;
  587.       }
  588.       param.real_keynr[param.keys++]=idx;
  589.     }
  590.     param.key_parts_end=key_parts;
  591.     if ((tree=get_mm_tree(&param,cond)))
  592.     {
  593.       if (tree->type == SEL_TREE::IMPOSSIBLE)
  594.       {
  595. records=0L; // Return -1 from this function
  596. read_time= (double) HA_POS_ERROR;
  597.       }
  598.       else if (tree->type == SEL_TREE::KEY ||
  599.        tree->type == SEL_TREE::KEY_SMALLER)
  600.       {
  601. SEL_ARG **key,**end,**best_key=0;
  602. for (idx=0,key=tree->keys, end=key+param.keys ;
  603.      key != end ;
  604.      key++,idx++)
  605. {
  606.   ha_rows found_records;
  607.   double found_read_time;
  608.   if (*key)
  609.   {
  610.     if ((*key)->type == SEL_ARG::MAYBE_KEY ||
  611. (*key)->maybe_flag)
  612.       needed_reg|= (key_map) 1 << param.real_keynr[idx];
  613.     found_records=check_quick_select(&param,idx, *key);
  614.     if (found_records != HA_POS_ERROR && found_records > 2 &&
  615. head->used_keys & ((table_map) 1 << param.real_keynr[idx]) &&
  616. (head->file->option_flag() & HA_HAVE_KEY_READ_ONLY))
  617.     {
  618.       /*
  619.       ** We can resolve this by only reading through this key
  620.       ** Assume that we will read trough the whole key range
  621.       ** and that all key blocks are half full (normally things are
  622.       ** much better)
  623.       */
  624.       uint keys_per_block= head->file->block_size/2/head->key_info[param.real_keynr[idx]].key_length+1;
  625.       found_read_time=((double) (found_records+keys_per_block-1)/
  626.        (double) keys_per_block);
  627.     }
  628.     else
  629.       found_read_time= head->file->read_time(found_records)+
  630. (double) found_records / TIME_FOR_COMPARE;
  631.     if (read_time > found_read_time)
  632.     {
  633.       read_time=found_read_time;
  634.       records=found_records;
  635.       best_key=key;
  636.     }
  637.   }
  638. }
  639. if (best_key && records)
  640. {
  641.   if ((quick=get_quick_select(&param,(uint) (best_key-tree->keys),
  642.       *best_key)))
  643.   {
  644.     quick->records=records;
  645.     quick->read_time=read_time;
  646.   }
  647. }
  648.       }
  649.     }
  650.     free_root(&alloc,MYF(0)); // Return memory & allocator
  651.     my_pthread_setspecific_ptr(THR_MALLOC,old_root);
  652.     current_thd->no_errors=0;
  653.   }
  654.   DBUG_EXECUTE("info",print_quick(quick,needed_reg););
  655.   /*
  656.     Assume that if the user is using 'limit' we will only need to scan
  657.     limit rows if we are using a key
  658.   */
  659.   DBUG_RETURN(records ? test(quick) : -1);
  660. }
  661. /* make a select tree of all keys in condition */
  662. static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
  663. {
  664.   SEL_TREE *tree=0;
  665.   DBUG_ENTER("get_mm_tree");
  666.   if (cond->type() == Item::COND_ITEM)
  667.   {
  668.     List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
  669.     if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
  670.     {
  671.       tree=0;
  672.       Item *item;
  673.       while ((item=li++))
  674.       {
  675. SEL_TREE *new_tree=get_mm_tree(param,item);
  676. tree=tree_and(param,tree,new_tree);
  677. if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
  678.   break;
  679.       }
  680.     }
  681.     else
  682.     { // COND OR
  683.       tree=get_mm_tree(param,li++);
  684.       if (tree)
  685.       {
  686. Item *item;
  687. while ((item=li++))
  688. {
  689.   SEL_TREE *new_tree=get_mm_tree(param,item);
  690.   if (!new_tree)
  691.     DBUG_RETURN(0);
  692.   tree=tree_or(param,tree,new_tree);
  693.   if (!tree || tree->type == SEL_TREE::ALWAYS)
  694.     break;
  695. }
  696.       }
  697.     }
  698.     DBUG_RETURN(tree);
  699.   }
  700.   /* Here when simple cond */
  701.   if (cond->const_item())
  702.   {
  703.     if (cond->val_int())
  704.       DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
  705.     DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE));
  706.   }
  707.   table_map ref_tables=cond->used_tables();
  708.   if (ref_tables & ~(param->prev_tables | param->read_tables |
  709.      param->current_table))
  710.     DBUG_RETURN(0); // Can't be calculated yet
  711.   if (cond->type() != Item::FUNC_ITEM)
  712.   { // Should be a field
  713.     if (ref_tables & param->current_table)
  714.       DBUG_RETURN(0);
  715.     DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
  716.   }
  717.   if (!(ref_tables & param->current_table))
  718.     DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
  719.   Item_func *cond_func= (Item_func*) cond;
  720.   if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
  721.     DBUG_RETURN(0); // Can't be calculated
  722.   if (cond_func->functype() == Item_func::BETWEEN)
  723.   {
  724.     if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
  725.     {
  726.       Field *field=((Item_field*) (cond_func->arguments()[0]))->field;
  727.       Item_result cmp_type=field->cmp_type();
  728.       tree= get_mm_parts(param,field,Item_func::GE_FUNC,
  729.  cond_func->arguments()[1],cmp_type);
  730.       DBUG_RETURN(tree_and(param,tree,
  731.    get_mm_parts(param, field,
  732. Item_func::LE_FUNC,
  733. cond_func->arguments()[2],cmp_type)));
  734.     }
  735.     DBUG_RETURN(0);
  736.   }
  737.   if (cond_func->functype() == Item_func::IN_FUNC)
  738.   { // COND OR
  739.     Item_func_in *func=(Item_func_in*) cond_func;
  740.     if (func->key_item()->type() == Item::FIELD_ITEM)
  741.     {
  742.       Field *field=((Item_field*) (func->key_item()))->field;
  743.       Item_result cmp_type=field->cmp_type();
  744.       tree= get_mm_parts(param,field,Item_func::EQ_FUNC,
  745.  func->arguments()[0],cmp_type);
  746.       if (!tree)
  747. DBUG_RETURN(tree); // Not key field
  748.       for (uint i=1 ; i < func->argument_count(); i++)
  749.       {
  750. SEL_TREE *new_tree=get_mm_parts(param,field,Item_func::EQ_FUNC,
  751. func->arguments()[i],cmp_type);
  752. tree=tree_or(param,tree,new_tree);
  753.       }
  754.       DBUG_RETURN(tree);
  755.     }
  756.     DBUG_RETURN(0); // Can't optimize this IN
  757.   }
  758.   /* check field op const */
  759.   /* btw, ft_func's arguments()[0] isn't FIELD_ITEM.  SerG*/
  760.   if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
  761.   {
  762.     tree= get_mm_parts(param,
  763.        ((Item_field*) (cond_func->arguments()[0]))->field,
  764.        cond_func->functype(),
  765.        cond_func->arg_count > 1 ? cond_func->arguments()[1] :
  766.        0,
  767.        ((Item_field*) (cond_func->arguments()[0]))->field->
  768.        cmp_type());
  769.   }
  770.   /* check const op field */
  771.   if (!tree &&
  772.       cond_func->have_rev_func() &&
  773.       cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
  774.   {
  775.     DBUG_RETURN(get_mm_parts(param,
  776.      ((Item_field*)
  777.       (cond_func->arguments()[1]))->field,
  778.      ((Item_bool_func2*) cond_func)->rev_functype(),
  779.      cond_func->arguments()[0],
  780.      ((Item_field*)
  781.       (cond_func->arguments()[1]))->field->cmp_type()
  782.      ));
  783.   }
  784.   DBUG_RETURN(tree);
  785. }
  786. static SEL_TREE *
  787. get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
  788.      Item_result cmp_type)
  789. {
  790.   DBUG_ENTER("get_mm_parts");
  791.   if (field->table != param->table)
  792.     DBUG_RETURN(0);
  793.   KEY_PART *key_part = param->key_parts,*end=param->key_parts_end;
  794.   SEL_TREE *tree=0;
  795.   if (value &&
  796.       value->used_tables() & ~(param->prev_tables | param->read_tables))
  797.     DBUG_RETURN(0);
  798.   for ( ; key_part != end ; key_part++)
  799.   {
  800.     if (field->eq(key_part->field))
  801.     {
  802.       SEL_ARG *sel_arg=0;
  803.       if (!tree)
  804. tree=new SEL_TREE();
  805.       if (!value || !(value->used_tables() & ~param->read_tables))
  806.       {
  807. sel_arg=get_mm_leaf(key_part->field,key_part,type,value);
  808. if (!sel_arg)
  809.   continue;
  810. if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
  811. {
  812.   tree->type=SEL_TREE::IMPOSSIBLE;
  813.   DBUG_RETURN(tree);
  814. }
  815.       }
  816.       else
  817. sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY);// This key may be used later
  818.       sel_arg->part=(uchar) key_part->part;
  819.       tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
  820.     }
  821.   }
  822.   DBUG_RETURN(tree);
  823. }
  824. static SEL_ARG *
  825. get_mm_leaf(Field *field,KEY_PART *key_part,
  826.     Item_func::Functype type,Item *value)
  827. {
  828.   uint maybe_null=(uint) field->real_maybe_null();
  829.   uint field_length=field->pack_length()+maybe_null;
  830.   SEL_ARG *tree;
  831.   DBUG_ENTER("get_mm_leaf");
  832.   if (type == Item_func::LIKE_FUNC)
  833.   {
  834.     bool like_error;
  835.     char buff1[MAX_FIELD_WIDTH],*min_str,*max_str;
  836.     String tmp(buff1,sizeof(buff1)),*res;
  837.     uint length,offset,min_length,max_length;
  838.     if (!(res= value->val_str(&tmp)))
  839.       DBUG_RETURN(&null_element);
  840.     // Check if this was a function. This should have be optimized away
  841.     // in the sql_select.cc
  842.     if (res != &tmp)
  843.     {
  844.       tmp.copy(*res); // Get own copy
  845.       res= &tmp;
  846.     }
  847.     if (field->cmp_type() != STRING_RESULT)
  848.       DBUG_RETURN(0); // Can only optimize strings
  849.     offset=maybe_null;
  850.     length=key_part->part_length;
  851.     if (field->type() == FIELD_TYPE_BLOB)
  852.     {
  853.       offset+=HA_KEY_BLOB_LENGTH;
  854.       field_length=key_part->part_length-HA_KEY_BLOB_LENGTH;
  855.     }
  856.     else
  857.     {
  858.       if (length < field_length)
  859. length=field_length; // Only if overlapping key
  860.       else
  861. field_length=length;
  862.     }
  863.     length+=offset;
  864.     if (!(min_str= (char*) sql_alloc(length*2)))
  865.       DBUG_RETURN(0);
  866.     max_str=min_str+length;
  867.     if (maybe_null)
  868.       max_str[0]= min_str[0]=0;
  869.     if (field->binary())
  870.       like_error=like_range(res->ptr(),res->length(),wild_prefix,field_length,
  871.     min_str+offset,max_str+offset,(char) 255,
  872.     &min_length,&max_length);
  873.     else
  874.     {
  875. #ifdef USE_STRCOLL
  876.       if (use_strcoll(default_charset_info))
  877.         like_error= my_like_range(default_charset_info,
  878.                                   res->ptr(),res->length(),wild_prefix,
  879.                                   field_length, min_str+maybe_null,
  880.                                   max_str+maybe_null,&min_length,&max_length);
  881.       else
  882. #endif
  883.         like_error=like_range(res->ptr(),res->length(),wild_prefix,field_length,
  884.                               min_str+offset,max_str+offset,
  885.                               max_sort_char,&min_length,&max_length);
  886.     }
  887.     if (like_error) // Can't optimize with LIKE
  888.       DBUG_RETURN(0);
  889.     if (offset != maybe_null) // Blob
  890.     {
  891.       int2store(min_str+maybe_null,min_length);
  892.       int2store(max_str+maybe_null,max_length);
  893.     }
  894.     DBUG_RETURN(new SEL_ARG(field,min_str,max_str));
  895.   }
  896.   if (!value) // IS NULL or IS NOT NULL
  897.   {
  898.     if (field->table->outer_join) // Can't use a key on this
  899.       DBUG_RETURN(0);
  900.     if (!maybe_null) // Not null field
  901.       DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);
  902.     tree=new SEL_ARG(field,is_null_string,is_null_string);
  903.     if (!tree)
  904.       DBUG_RETURN(0);
  905.     if (type == Item_func::ISNOTNULL_FUNC)
  906.     {
  907.       tree->min_flag=NEAR_MIN;     /* IS NOT NULL ->  X > NULL */
  908.       tree->max_flag=NO_MAX_RANGE;
  909.     }
  910.     DBUG_RETURN(tree);
  911.   }
  912.   if (!field->optimize_range() && type != Item_func::EQ_FUNC &&
  913.       type != Item_func::EQUAL_FUNC)
  914.     DBUG_RETURN(0); // Can't optimize this
  915.   /* We can't always use indexes when comparing a string index to a number */
  916.   /* cmp_type() is checked to allow compare of dates to numbers */
  917.   if (field->result_type() == STRING_RESULT &&
  918.       value->result_type() != STRING_RESULT &&
  919.       field->cmp_type() != value->result_type())
  920.     DBUG_RETURN(0);
  921.   if (value->save_in_field(field))
  922.   {
  923.     if (type == Item_func::EQUAL_FUNC)
  924.     {
  925.       /* convert column_name <=> NULL -> column_name IS NULL */
  926.       char *str= (char*) sql_alloc(1); // Get local copy of key
  927.       if (!*str)
  928. DBUG_RETURN(0);
  929.       *str = 1;
  930.       DBUG_RETURN(new SEL_ARG(field,str,str));
  931.     }
  932.     DBUG_RETURN(&null_element); // NULL is never true
  933.   }
  934.   // Get local copy of key
  935.   char *str= (char*) sql_alloc(key_part->part_length+maybe_null);
  936.   if (!str)
  937.     DBUG_RETURN(0);
  938.   if (maybe_null)
  939.     *str=0; // Not NULL
  940.   field->get_key_image(str+maybe_null,key_part->part_length);
  941.   if (!(tree=new SEL_ARG(field,str,str)))
  942.     DBUG_RETURN(0);
  943.   switch (type) {
  944.   case Item_func::LT_FUNC:
  945.     if (field_is_equal_to_item(field,value))
  946.       tree->max_flag=NEAR_MAX;
  947.     /* fall through */
  948.   case Item_func::LE_FUNC:
  949.     if (!maybe_null)
  950.       tree->min_flag=NO_MIN_RANGE; /* From start */
  951.     else
  952.     { // > NULL
  953.       tree->min_value=is_null_string;
  954.       tree->min_flag=NEAR_MIN;
  955.     }
  956.     break;
  957.   case Item_func::GT_FUNC:
  958.     if (field_is_equal_to_item(field,value))
  959.       tree->min_flag=NEAR_MIN;
  960.     /* fall through */
  961.   case Item_func::GE_FUNC:
  962.     tree->max_flag=NO_MAX_RANGE;
  963.     break;
  964.   default:
  965.     break;
  966.   }
  967.   DBUG_RETURN(tree);
  968. }
  969. /*
  970. ** Calculate min_str and max_str that ranges a LIKE string.
  971. ** Arguments:
  972. ** ptr Pointer to LIKE string.
  973. ** ptr_length Length of LIKE string.
  974. ** escape Escape character in LIKE.  (Normally '').
  975. ** All escape characters should be removed from min_str and max_str
  976. ** res_length Length of min_str and max_str.
  977. ** min_str Smallest case sensitive string that ranges LIKE.
  978. ** Should be space padded to res_length.
  979. ** max_str Largest case sensitive string that ranges LIKE.
  980. ** Normally padded with the biggest character sort value.
  981. **
  982. ** The function should return 0 if ok and 1 if the LIKE string can't be
  983. ** optimized !
  984. */
  985. static bool like_range(const char *ptr,uint ptr_length,char escape,
  986.        uint res_length, char *min_str,char *max_str,
  987.        char max_sort_chr, uint *min_length, uint *max_length)
  988. {
  989.   const char *end=ptr+ptr_length;
  990.   char *min_org=min_str;
  991.   char *min_end=min_str+res_length;
  992.   for (; ptr != end && min_str != min_end ; ptr++)
  993.   {
  994.     if (*ptr == escape && ptr+1 != end)
  995.     {
  996.       ptr++; // Skipp escape
  997.       *min_str++= *max_str++ = *ptr;
  998.       continue;
  999.     }
  1000.     if (*ptr == wild_one) // '_' in SQL
  1001.     {
  1002.       *min_str++=''; // This should be min char
  1003.       *max_str++=max_sort_chr;
  1004.       continue;
  1005.     }
  1006.     if (*ptr == wild_many) // '%' in SQL
  1007.     {
  1008.       *min_length= (uint) (min_str - min_org);
  1009.       *max_length=res_length;
  1010.       do {
  1011. *min_str++ = ' '; // Because if key compression
  1012. *max_str++ = max_sort_chr;
  1013.       } while (min_str != min_end);
  1014.       return 0;
  1015.     }
  1016.     *min_str++= *max_str++ = *ptr;
  1017.   }
  1018.   *min_length= *max_length = (uint) (min_str - min_org);
  1019.   /* Temporary fix for handling wild_one at end of string (key compression) */
  1020.   for (char *tmp= min_str ; tmp > min_org && tmp[-1] == '';)
  1021.     *--tmp=' ';
  1022.   while (min_str != min_end)
  1023.     *min_str++ = *max_str++ = ' '; // Because if key compression
  1024.   return 0;
  1025. }
  1026. /******************************************************************************
  1027. ** Tree manipulation functions
  1028. ** If tree is 0 it means that the condition can't be tested. It refers
  1029. ** to a non existent table or to a field in current table with isn't a key.
  1030. ** The different tree flags:
  1031. ** IMPOSSIBLE:  Condition is never true
  1032. ** ALWAYS:  Condition is always true
  1033. ** MAYBE:  Condition may exists when tables are read
  1034. ** MAYBE_KEY:  Condition refers to a key that may be used in join loop
  1035. ** KEY_RANGE:  Condition uses a key
  1036. ******************************************************************************/
  1037. /*
  1038. ** Add a new key test to a key when scanning through all keys
  1039. ** This will never be called for same key parts.
  1040. */
  1041. static SEL_ARG *
  1042. sel_add(SEL_ARG *key1,SEL_ARG *key2)
  1043. {
  1044.   SEL_ARG *root,**key_link;
  1045.   if (!key1)
  1046.     return key2;
  1047.   if (!key2)
  1048.     return key1;
  1049.   key_link= &root;
  1050.   while (key1 && key2)
  1051.   {
  1052.     if (key1->part < key2->part)
  1053.     {
  1054.       *key_link= key1;
  1055.       key_link= &key1->next_key_part;
  1056.       key1=key1->next_key_part;
  1057.     }
  1058.     else
  1059.     {
  1060.       *key_link= key2;
  1061.       key_link= &key2->next_key_part;
  1062.       key2=key2->next_key_part;
  1063.     }
  1064.   }
  1065.   *key_link=key1 ? key1 : key2;
  1066.   return root;
  1067. }
  1068. #define CLONE_KEY1_MAYBE 1
  1069. #define CLONE_KEY2_MAYBE 2
  1070. #define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
  1071. static SEL_TREE *
  1072. tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
  1073. {
  1074.   DBUG_ENTER("tree_and");
  1075.   if (!tree1)
  1076.     DBUG_RETURN(tree2);
  1077.   if (!tree2)
  1078.     DBUG_RETURN(tree1);
  1079.   if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
  1080.     DBUG_RETURN(tree1);
  1081.   if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
  1082.     DBUG_RETURN(tree2);
  1083.   if (tree1->type == SEL_TREE::MAYBE)
  1084.   {
  1085.     if (tree2->type == SEL_TREE::KEY)
  1086.       tree2->type=SEL_TREE::KEY_SMALLER;
  1087.     DBUG_RETURN(tree2);
  1088.   }
  1089.   if (tree2->type == SEL_TREE::MAYBE)
  1090.   {
  1091.     tree1->type=SEL_TREE::KEY_SMALLER;
  1092.     DBUG_RETURN(tree1);
  1093.   }
  1094.   /* Join the trees key per key */
  1095.   SEL_ARG **key1,**key2,**end;
  1096.   for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
  1097.        key1 != end ; key1++,key2++)
  1098.   {
  1099.     uint flag=0;
  1100.     if (*key1 || *key2)
  1101.     {
  1102.       if (*key1 && !(*key1)->simple_key())
  1103. flag|=CLONE_KEY1_MAYBE;
  1104.       if (*key2 && !(*key2)->simple_key())
  1105. flag|=CLONE_KEY2_MAYBE;
  1106.       *key1=key_and(*key1,*key2,flag);
  1107.       if ((*key1)->type == SEL_ARG::IMPOSSIBLE)
  1108.       {
  1109. tree1->type= SEL_TREE::IMPOSSIBLE;
  1110. break;
  1111.       }
  1112. #ifdef EXTRA_DEBUG
  1113.       (*key1)->test_use_count(*key1);
  1114. #endif
  1115.     }
  1116.   }
  1117.   DBUG_RETURN(tree1);
  1118. }
  1119. static SEL_TREE *
  1120. tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
  1121. {
  1122.   DBUG_ENTER("tree_or");
  1123.   if (!tree1 || !tree2)
  1124.     DBUG_RETURN(0);
  1125.   if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
  1126.     DBUG_RETURN(tree2);
  1127.   if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
  1128.     DBUG_RETURN(tree1);
  1129.   if (tree1->type == SEL_TREE::MAYBE)
  1130.     DBUG_RETURN(tree1); // Can't use this
  1131.   if (tree2->type == SEL_TREE::MAYBE)
  1132.     DBUG_RETURN(tree2);
  1133.   /* Join the trees key per key */
  1134.   SEL_ARG **key1,**key2,**end;
  1135.   SEL_TREE *result=0;
  1136.   for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
  1137.        key1 != end ; key1++,key2++)
  1138.   {
  1139.     *key1=key_or(*key1,*key2);
  1140.     if (*key1)
  1141.     {
  1142.       result=tree1; // Added to tree1
  1143. #ifdef EXTRA_DEBUG
  1144.       (*key1)->test_use_count(*key1);
  1145. #endif
  1146.     }
  1147.   }
  1148.   DBUG_RETURN(result);
  1149. }
  1150. /* And key trees where key1->part < key2 -> part */
  1151. static SEL_ARG *
  1152. and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
  1153. {
  1154.   SEL_ARG *next;
  1155.   ulong use_count=key1->use_count;
  1156.   if (key1->elements != 1)
  1157.   {
  1158.     key2->use_count+=key1->elements-1;
  1159.     key2->increment_use_count((int) key1->elements-1);
  1160.   }
  1161.   if (key1->type == SEL_ARG::MAYBE_KEY)
  1162.   {
  1163.     key1->left= &null_element; key1->next=0;
  1164.   }
  1165.   for (next=key1->first(); next ; next=next->next)
  1166.   {
  1167.     if (next->next_key_part)
  1168.     {
  1169.       SEL_ARG *tmp=key_and(next->next_key_part,key2,clone_flag);
  1170.       if (tmp && tmp->type == SEL_ARG::IMPOSSIBLE)
  1171.       {
  1172. key1=key1->tree_delete(next);
  1173. continue;
  1174.       }
  1175.       next->next_key_part=tmp;
  1176.       if (use_count)
  1177. next->increment_use_count(use_count);
  1178.     }
  1179.     else
  1180.       next->next_key_part=key2;
  1181.   }
  1182.   if (!key1)
  1183.     return &null_element; // Impossible ranges
  1184.   key1->use_count++;
  1185.   return key1;
  1186. }
  1187. static SEL_ARG *
  1188. key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
  1189. {
  1190.   if (!key1)
  1191.     return key2;
  1192.   if (!key2)
  1193.     return key1;
  1194.   if (key1->part != key2->part)
  1195.   {
  1196.     if (key1->part > key2->part)
  1197.     {
  1198.       swap(SEL_ARG *,key1,key2);
  1199.       clone_flag=swap_clone_flag(clone_flag);
  1200.     }
  1201.     // key1->part < key2->part
  1202.     key1->use_count--;
  1203.     if (key1->use_count > 0)
  1204.       key1=key1->clone_tree();
  1205.     return and_all_keys(key1,key2,clone_flag);
  1206.   }
  1207.   if (((clone_flag & CLONE_KEY2_MAYBE) &&
  1208.        !(clone_flag & CLONE_KEY1_MAYBE)) ||
  1209.       key1->type == SEL_ARG::MAYBE_KEY)
  1210.   { // Put simple key in key2
  1211.     swap(SEL_ARG *,key1,key2);
  1212.     clone_flag=swap_clone_flag(clone_flag);
  1213.   }
  1214.   // If one of the key is MAYBE_KEY then the found region may be smaller
  1215.   if (key2->type == SEL_ARG::MAYBE_KEY)
  1216.   {
  1217.     if (key1->use_count > 1)
  1218.     {
  1219.       key1->use_count--;
  1220.       key1=key1->clone_tree();
  1221.       key1->use_count++;
  1222.     }
  1223.     if (key1->type == SEL_ARG::MAYBE_KEY)
  1224.     { // Both are maybe key
  1225.       key1->next_key_part=key_and(key1->next_key_part,key2->next_key_part,
  1226.  clone_flag);
  1227.       if (key1->next_key_part &&
  1228.   key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
  1229. return key1;
  1230.     }
  1231.     else
  1232.     {
  1233.       key1->maybe_smaller();
  1234.       if (key2->next_key_part)
  1235. return and_all_keys(key1,key2,clone_flag);
  1236.       key2->use_count--; // Key2 doesn't have a tree
  1237.     }
  1238.     return key1;
  1239.   }
  1240.   key1->use_count--;
  1241.   key2->use_count--;
  1242.   SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
  1243.   while (e1 && e2)
  1244.   {
  1245.     int cmp=e1->cmp_min_to_min(e2);
  1246.     if (cmp < 0)
  1247.     {
  1248.       if (get_range(&e1,&e2,key1))
  1249. continue;
  1250.     }
  1251.     else if (get_range(&e2,&e1,key2))
  1252.       continue;
  1253.     SEL_ARG *next=key_and(e1->next_key_part,e2->next_key_part,clone_flag);
  1254.     e1->increment_use_count(1);
  1255.     e2->increment_use_count(1);
  1256.     if (!next || next->type != SEL_ARG::IMPOSSIBLE)
  1257.     {
  1258.       SEL_ARG *new_arg= e1->clone_and(e2);
  1259.       new_arg->next_key_part=next;
  1260.       if (!new_tree)
  1261.       {
  1262. new_tree=new_arg;
  1263.       }
  1264.       else
  1265. new_tree=new_tree->insert(new_arg);
  1266.     }
  1267.     if (e1->cmp_max_to_max(e2) < 0)
  1268.       e1=e1->next; // e1 can't overlapp next e2
  1269.     else
  1270.       e2=e2->next;
  1271.   }
  1272.   key1->free_tree();
  1273.   key2->free_tree();
  1274.   if (!new_tree)
  1275.     return &null_element; // Impossible range
  1276.   return new_tree;
  1277. }
  1278. static bool
  1279. get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
  1280. {
  1281.   (*e1)=root1->find_range(*e2); // first e1->min < e2->min
  1282.   if ((*e1)->cmp_max_to_min(*e2) < 0)
  1283.   {
  1284.     if (!((*e1)=(*e1)->next))
  1285.       return 1;
  1286.     if ((*e1)->cmp_min_to_max(*e2) > 0)
  1287.     {
  1288.       (*e2)=(*e2)->next;
  1289.       return 1;
  1290.     }
  1291.   }
  1292.   return 0;
  1293. }
  1294. static SEL_ARG *
  1295. key_or(SEL_ARG *key1,SEL_ARG *key2)
  1296. {
  1297.   if (!key1)
  1298.   {
  1299.     if (key2)
  1300.     {
  1301.       key2->use_count--;
  1302.       key2->free_tree();
  1303.     }
  1304.     return 0;
  1305.   }
  1306.   else if (!key2)
  1307.   {
  1308.     key1->use_count--;
  1309.     key1->free_tree();
  1310.     return 0;
  1311.   }
  1312.   key1->use_count--;
  1313.   key2->use_count--;
  1314.   if (key1->part != key2->part)
  1315.   {
  1316.     key1->free_tree();
  1317.     key2->free_tree();
  1318.     return 0; // Can't optimize this
  1319.   }
  1320.   // If one of the key is MAYBE_KEY then the found region may be bigger
  1321.   if (key1->type == SEL_ARG::MAYBE_KEY)
  1322.   {
  1323.     key2->free_tree();
  1324.     key1->use_count++;
  1325.     return key1;
  1326.   }
  1327.   if (key2->type == SEL_ARG::MAYBE_KEY)
  1328.   {
  1329.     key1->free_tree();
  1330.     key2->use_count++;
  1331.     return key2;
  1332.   }
  1333.   if (key1->use_count > 0)
  1334.   {
  1335.     if (key2->use_count == 0 || key1->elements > key2->elements)
  1336.     {
  1337.       swap(SEL_ARG *,key1,key2);
  1338.     }
  1339.     else
  1340.       key1=key1->clone_tree();
  1341.   }
  1342.   // Add tree at key2 to tree at key1
  1343.   bool key2_shared=key2->use_count != 0;
  1344.   key1->maybe_flag|=key2->maybe_flag;
  1345.   for (key2=key2->first(); key2; )
  1346.   {
  1347.     SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
  1348.     int cmp;
  1349.     if (!tmp)
  1350.     {
  1351.       tmp=key1->first(); // tmp.min > key2.min
  1352.       cmp= -1;
  1353.     }
  1354.     else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
  1355.     { // Found tmp.max < key2.min
  1356.       SEL_ARG *next=tmp->next;
  1357.       if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
  1358.       {
  1359. // Join near ranges like tmp.max < 0 and key2.min >= 0
  1360. SEL_ARG *key2_next=key2->next;
  1361. if (key2_shared)
  1362. {
  1363.   key2=new SEL_ARG(*key2);
  1364.   key2->increment_use_count(key1->use_count+1);
  1365.   key2->next=key2_next; // New copy of key2
  1366. }
  1367. key2->copy_min(tmp);
  1368. if (!(key1=key1->tree_delete(tmp)))
  1369. { // Only one key in tree
  1370.   key1=key2;
  1371.   key1->make_root();
  1372.   key2=key2_next;
  1373.   break;
  1374. }
  1375.       }
  1376.       if (!(tmp=next)) // tmp.min > key2.min
  1377. break; // Copy rest of key2
  1378.     }
  1379.     if (cmp < 0)
  1380.     { // tmp.min > key2.min
  1381.       int tmp_cmp;
  1382.       if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
  1383.       {
  1384. if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
  1385. { // ranges are connected
  1386.   tmp->copy_min_to_min(key2);
  1387.   key1->merge_flags(key2);
  1388.   if (tmp->min_flag & NO_MIN_RANGE &&
  1389.       tmp->max_flag & NO_MAX_RANGE)
  1390.   {
  1391.     if (key1->maybe_flag)
  1392.       return new SEL_ARG(SEL_ARG::MAYBE_KEY);
  1393.     return 0;
  1394.   }
  1395.   key2->increment_use_count(-1); // Free not used tree
  1396.   key2=key2->next;
  1397.   continue;
  1398. }
  1399. else
  1400. {
  1401.   SEL_ARG *next=key2->next; // Keys are not overlapping
  1402.   if (key2_shared)
  1403.   {
  1404.     key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
  1405.     key2->increment_use_count(key1->use_count+1);
  1406.   }
  1407.   else
  1408.     key1=key1->insert(key2); // Will destroy key2_root
  1409.   key2=next;
  1410.   continue;
  1411. }
  1412.       }
  1413.     }
  1414.     // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
  1415.     if (eq_tree(tmp->next_key_part,key2->next_key_part))
  1416.     {
  1417.       if (tmp->is_same(key2))
  1418.       {
  1419. tmp->merge_flags(key2); // Copy maybe flags
  1420. key2->increment_use_count(-1); // Free not used tree
  1421.       }
  1422.       else
  1423.       {
  1424. SEL_ARG *last=tmp;
  1425. while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
  1426.        eq_tree(last->next->next_key_part,key2->next_key_part))
  1427. {
  1428.   SEL_ARG *save=last;
  1429.   last=last->next;
  1430.   key1=key1->tree_delete(save);
  1431. }
  1432. if (last->copy_min(key2) || last->copy_max(key2))
  1433. { // Full range
  1434.   key1->free_tree();
  1435.   for (; key2 ; key2=key2->next)
  1436.     key2->increment_use_count(-1); // Free not used tree
  1437.   if (key1->maybe_flag)
  1438.     return new SEL_ARG(SEL_ARG::MAYBE_KEY);
  1439.   return 0;
  1440. }
  1441.       }
  1442.       key2=key2->next;
  1443.       continue;
  1444.     }
  1445.     if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
  1446.     { // tmp.min <= x < key2.min
  1447.       SEL_ARG *new_arg=tmp->clone_first(key2);
  1448.       if ((new_arg->next_key_part= key1->next_key_part))
  1449. new_arg->increment_use_count(key1->use_count+1);
  1450.       tmp->copy_min_to_min(key2);
  1451.       key1=key1->insert(new_arg);
  1452.     }
  1453.     // tmp.min >= key2.min && tmp.min <= key2.max
  1454.     SEL_ARG key(*key2); // Get copy we can modify
  1455.     for (;;)
  1456.     {
  1457.       if (tmp->cmp_min_to_min(&key) > 0)
  1458.       { // key.min <= x < tmp.min
  1459. SEL_ARG *new_arg=key.clone_first(tmp);
  1460. if ((new_arg->next_key_part=key.next_key_part))
  1461.   new_arg->increment_use_count(key1->use_count+1);
  1462. key1=key1->insert(new_arg);
  1463.       }
  1464.       if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
  1465.       { // tmp.min. <= x <= tmp.max
  1466. tmp->maybe_flag|= key.maybe_flag;
  1467. key.increment_use_count(key1->use_count+1);
  1468. tmp->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
  1469. if (!cmp) // Key2 is ready
  1470.   break;
  1471. key.copy_max_to_min(tmp);
  1472. if (!(tmp=tmp->next))
  1473. {
  1474.   key1=key1->insert(new SEL_ARG(key));
  1475.   key2=key2->next;
  1476.   goto end;
  1477. }
  1478. if (tmp->cmp_min_to_max(&key) > 0)
  1479. {
  1480.   key1=key1->insert(new SEL_ARG(key));
  1481.   break;
  1482. }
  1483.       }
  1484.       else
  1485.       {
  1486. SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
  1487. tmp->copy_max_to_min(&key);
  1488. tmp->increment_use_count(key1->use_count+1);
  1489. new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
  1490. key1=key1->insert(new_arg);
  1491. break;
  1492.       }
  1493.     }
  1494.     key2=key2->next;
  1495.   }
  1496. end:
  1497.   while (key2)
  1498.   {
  1499.     SEL_ARG *next=key2->next;
  1500.     if (key2_shared)
  1501.     {
  1502.       key2->increment_use_count(key1->use_count+1);
  1503.       key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
  1504.     }
  1505.     else
  1506.       key1=key1->insert(key2); // Will destroy key2_root
  1507.     key2=next;
  1508.   }
  1509.   key1->use_count++;
  1510.   return key1;
  1511. }
  1512. /* Compare if two trees are equal */
  1513. static bool eq_tree(SEL_ARG* a,SEL_ARG *b)
  1514. {
  1515.   if (a == b)
  1516.     return 1;
  1517.   if (!a || !b || !a->is_same(b))
  1518.     return 0;
  1519.   if (a->left != &null_element && b->left != &null_element)
  1520.   {
  1521.     if (!eq_tree(a->left,b->left))
  1522.       return 0;
  1523.   }
  1524.   else if (a->left != &null_element || b->left != &null_element)
  1525.     return 0;
  1526.   if (a->right != &null_element && b->right != &null_element)
  1527.   {
  1528.     if (!eq_tree(a->right,b->right))
  1529.       return 0;
  1530.   }
  1531.   else if (a->right != &null_element || b->right != &null_element)
  1532.     return 0;
  1533.   if (a->next_key_part != b->next_key_part)
  1534.   { // Sub range
  1535.     if (!a->next_key_part != !b->next_key_part ||
  1536. !eq_tree(a->next_key_part, b->next_key_part))
  1537.       return 0;
  1538.   }
  1539.   return 1;
  1540. }
  1541. SEL_ARG *
  1542. SEL_ARG::insert(SEL_ARG *key)
  1543. {
  1544.   SEL_ARG *element,**par,*last_element;
  1545.   LINT_INIT(par); LINT_INIT(last_element);
  1546.   for (element= this; element != &null_element ; )
  1547.   {
  1548.     last_element=element;
  1549.     if (key->cmp_min_to_min(element) > 0)
  1550.     {
  1551.       par= &element->right; element= element->right;
  1552.     }
  1553.     else
  1554.     {
  1555.       par = &element->left; element= element->left;
  1556.     }
  1557.   }
  1558.   *par=key;
  1559.   key->parent=last_element;
  1560. /* Link in list */
  1561.   if (par == &last_element->left)
  1562.   {
  1563.     key->next=last_element;
  1564.     if ((key->prev=last_element->prev))
  1565.       key->prev->next=key;
  1566.     last_element->prev=key;
  1567.   }
  1568.   else
  1569.   {
  1570.     if ((key->next=last_element->next))
  1571.       key->next->prev=key;
  1572.     key->prev=last_element;
  1573.     last_element->next=key;
  1574.   }
  1575.   key->left=key->right= &null_element;
  1576.   SEL_ARG *root=rb_insert(key); // rebalance tree
  1577.   root->use_count=this->use_count; // copy root info
  1578.   root->elements= this->elements+1;
  1579.   root->maybe_flag=this->maybe_flag;
  1580.   return root;
  1581. }
  1582. /*
  1583. ** Find best key with min <= given key
  1584. ** Because the call context this should never return 0 to get_range
  1585. */
  1586. SEL_ARG *
  1587. SEL_ARG::find_range(SEL_ARG *key)
  1588. {
  1589.   SEL_ARG *element=this,*found=0;
  1590.   for (;;)
  1591.   {
  1592.     if (element == &null_element)
  1593.       return found;
  1594.     int cmp=element->cmp_min_to_min(key);
  1595.     if (cmp == 0)
  1596.       return element;
  1597.     if (cmp < 0)
  1598.     {
  1599.       found=element;
  1600.       element=element->right;
  1601.     }
  1602.     else
  1603.       element=element->left;
  1604.   }
  1605. }
  1606. /*
  1607. ** Remove a element from the tree
  1608. ** This also frees all sub trees that is used by the element
  1609. */
  1610. SEL_ARG *
  1611. SEL_ARG::tree_delete(SEL_ARG *key)
  1612. {
  1613.   enum leaf_color remove_color;
  1614.   SEL_ARG *root,*nod,**par,*fix_par;
  1615.   root=this; this->parent= 0;
  1616.   /* Unlink from list */
  1617.   if (key->prev)
  1618.     key->prev->next=key->next;
  1619.   if (key->next)
  1620.     key->next->prev=key->prev;
  1621.   key->increment_use_count(-1);
  1622.   if (!key->parent)
  1623.     par= &root;
  1624.   else
  1625.     par=key->parent_ptr();
  1626.   if (key->left == &null_element)
  1627.   {
  1628.     *par=nod=key->right;
  1629.     fix_par=key->parent;
  1630.     if (nod != &null_element)
  1631.       nod->parent=fix_par;
  1632.     remove_color= key->color;
  1633.   }
  1634.   else if (key->right == &null_element)
  1635.   {
  1636.     *par= nod=key->left;
  1637.     nod->parent=fix_par=key->parent;
  1638.     remove_color= key->color;
  1639.   }
  1640.   else
  1641.   {
  1642.     SEL_ARG *tmp=key->next; // next bigger key (exist!)
  1643.     nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
  1644.     fix_par=tmp->parent;
  1645.     if (nod != &null_element)
  1646.       nod->parent=fix_par;
  1647.     remove_color= tmp->color;
  1648.     tmp->parent=key->parent; // Move node in place of key
  1649.     (tmp->left=key->left)->parent=tmp;
  1650.     if ((tmp->right=key->right) != &null_element)
  1651.       tmp->right->parent=tmp;
  1652.     tmp->color=key->color;
  1653.     *par=tmp;
  1654.     if (fix_par == key) // key->right == key->next
  1655.       fix_par=tmp; // new parent of nod
  1656.   }
  1657.   if (root == &null_element)
  1658.     return 0; // Maybe root later
  1659.   if (remove_color == BLACK)
  1660.     root=rb_delete_fixup(root,nod,fix_par);
  1661.   test_rb_tree(root,root->parent);
  1662.   root->use_count=this->use_count; // Fix root counters
  1663.   root->elements=this->elements-1;
  1664.   root->maybe_flag=this->maybe_flag;
  1665.   return root;
  1666. }
  1667. /* Functions to fix up the tree after insert and delete */
  1668. static void left_rotate(SEL_ARG **root,SEL_ARG *leaf)
  1669. {
  1670.   SEL_ARG *y=leaf->right;
  1671.   leaf->right=y->left;
  1672.   if (y->left != &null_element)
  1673.     y->left->parent=leaf;
  1674.   if (!(y->parent=leaf->parent))
  1675.     *root=y;
  1676.   else
  1677.     *leaf->parent_ptr()=y;
  1678.   y->left=leaf;
  1679.   leaf->parent=y;
  1680. }
  1681. static void right_rotate(SEL_ARG **root,SEL_ARG *leaf)
  1682. {
  1683.   SEL_ARG *y=leaf->left;
  1684.   leaf->left=y->right;
  1685.   if (y->right != &null_element)
  1686.     y->right->parent=leaf;
  1687.   if (!(y->parent=leaf->parent))
  1688.     *root=y;
  1689.   else
  1690.     *leaf->parent_ptr()=y;
  1691.   y->right=leaf;
  1692.   leaf->parent=y;
  1693. }
  1694. SEL_ARG *
  1695. SEL_ARG::rb_insert(SEL_ARG *leaf)
  1696. {
  1697.   SEL_ARG *y,*par,*par2,*root;
  1698.   root= this; root->parent= 0;
  1699.   leaf->color=RED;
  1700.   while (leaf != root && (par= leaf->parent)->color == RED)
  1701.   { // This can't be root or 1 level under
  1702.     if (par == (par2= leaf->parent->parent)->left)
  1703.     {
  1704.       y= par2->right;
  1705.       if (y->color == RED)
  1706.       {
  1707. par->color=BLACK;
  1708. y->color=BLACK;
  1709. leaf=par2;
  1710. leaf->color=RED; /* And the loop continues */
  1711.       }
  1712.       else
  1713.       {
  1714. if (leaf == par->right)
  1715. {
  1716.   left_rotate(&root,leaf->parent);
  1717.   par=leaf; /* leaf is now parent to old leaf */
  1718. }
  1719. par->color=BLACK;
  1720. par2->color=RED;
  1721. right_rotate(&root,par2);
  1722. break;
  1723.       }
  1724.     }
  1725.     else
  1726.     {
  1727.       y= par2->left;
  1728.       if (y->color == RED)
  1729.       {
  1730. par->color=BLACK;
  1731. y->color=BLACK;
  1732. leaf=par2;
  1733. leaf->color=RED; /* And the loop continues */
  1734.       }
  1735.       else
  1736.       {
  1737. if (leaf == par->left)
  1738. {
  1739.   right_rotate(&root,par);
  1740.   par=leaf;
  1741. }
  1742. par->color=BLACK;
  1743. par2->color=RED;
  1744. left_rotate(&root,par2);
  1745. break;
  1746.       }
  1747.     }
  1748.   }
  1749.   root->color=BLACK;
  1750.   test_rb_tree(root,root->parent);
  1751.   return root;
  1752. }
  1753. SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key,SEL_ARG *par)
  1754. {
  1755.   SEL_ARG *x,*w;
  1756.   root->parent=0;
  1757.   x= key;
  1758.   while (x != root && x->color == SEL_ARG::BLACK)
  1759.   {
  1760.     if (x == par->left)
  1761.     {
  1762.       w=par->right;
  1763.       if (w->color == SEL_ARG::RED)
  1764.       {
  1765. w->color=SEL_ARG::BLACK;
  1766. par->color=SEL_ARG::RED;
  1767. left_rotate(&root,par);
  1768. w=par->right;
  1769.       }
  1770.       if (w->left->color == SEL_ARG::BLACK && w->right->color == SEL_ARG::BLACK)
  1771.       {
  1772. w->color=SEL_ARG::RED;
  1773. x=par;
  1774.       }
  1775.       else
  1776.       {
  1777. if (w->right->color == SEL_ARG::BLACK)
  1778. {
  1779.   w->left->color=SEL_ARG::BLACK;
  1780.   w->color=SEL_ARG::RED;
  1781.   right_rotate(&root,w);
  1782.   w=par->right;
  1783. }
  1784. w->color=par->color;
  1785. par->color=SEL_ARG::BLACK;
  1786. w->right->color=SEL_ARG::BLACK;
  1787. left_rotate(&root,par);
  1788. x=root;
  1789. break;
  1790.       }
  1791.     }
  1792.     else
  1793.     {
  1794.       w=par->left;
  1795.       if (w->color == SEL_ARG::RED)
  1796.       {
  1797. w->color=SEL_ARG::BLACK;
  1798. par->color=SEL_ARG::RED;
  1799. right_rotate(&root,par);
  1800. w=par->left;
  1801.       }
  1802.       if (w->right->color == SEL_ARG::BLACK && w->left->color == SEL_ARG::BLACK)
  1803.       {
  1804. w->color=SEL_ARG::RED;
  1805. x=par;
  1806.       }
  1807.       else
  1808.       {
  1809. if (w->left->color == SEL_ARG::BLACK)
  1810. {
  1811.   w->right->color=SEL_ARG::BLACK;
  1812.   w->color=SEL_ARG::RED;
  1813.   left_rotate(&root,w);
  1814.   w=par->left;
  1815. }
  1816. w->color=par->color;
  1817. par->color=SEL_ARG::BLACK;
  1818. w->left->color=SEL_ARG::BLACK;
  1819. right_rotate(&root,par);
  1820. x=root;
  1821. break;
  1822.       }
  1823.     }
  1824.     par=x->parent;
  1825.   }
  1826.   x->color=SEL_ARG::BLACK;
  1827.   return root;
  1828. }
  1829. /* Test that the proporties for a red-black tree holds */
  1830. #ifdef EXTRA_DEBUG
  1831. int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
  1832. {
  1833.   int count_l,count_r;
  1834.   if (element == &null_element)
  1835.     return 0; // Found end of tree
  1836.   if (element->parent != parent)
  1837.   {
  1838.     sql_print_error("Wrong tree: Parent doesn't point at parent");
  1839.     return -1;
  1840.   }
  1841.   if (element->color == SEL_ARG::RED &&
  1842.       (element->left->color == SEL_ARG::RED ||
  1843.        element->right->color == SEL_ARG::RED))
  1844.   {
  1845.     sql_print_error("Wrong tree: Found two red in a row");
  1846.     return -1;
  1847.   }
  1848.   if (element->left == element->right && element->left != &null_element)
  1849.   { // Dummy test
  1850.     sql_print_error("Wrong tree: Found right == left");
  1851.     return -1;
  1852.   }
  1853.   count_l=test_rb_tree(element->left,element);
  1854.   count_r=test_rb_tree(element->right,element);
  1855.   if (count_l >= 0 && count_r >= 0)
  1856.   {
  1857.     if (count_l == count_r)
  1858.       return count_l+(element->color == SEL_ARG::BLACK);
  1859.     sql_print_error("Wrong tree: Incorrect black-count: %d - %d",
  1860.     count_l,count_r);
  1861.   }
  1862.   return -1; // Error, no more warnings
  1863. }
  1864. static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
  1865. {
  1866.   ulong count= 0;
  1867.   for (root=root->first(); root ; root=root->next)
  1868.   {
  1869.     if (root->next_key_part)
  1870.     {
  1871.       if (root->next_key_part == key)
  1872. count++;
  1873.       if (root->next_key_part->part < key->part)
  1874. count+=count_key_part_usage(root->next_key_part,key);
  1875.     }
  1876.   }
  1877.   return count;
  1878. }
  1879. void SEL_ARG::test_use_count(SEL_ARG *root)
  1880. {
  1881.   if (this == root && use_count != 1)
  1882.   {
  1883.     sql_print_error("Use_count: Wrong count %lu for root",use_count);
  1884.     return;
  1885.   }
  1886.   if (this->type != SEL_ARG::KEY_RANGE)
  1887.     return;
  1888.   uint e_count=0;
  1889.   for (SEL_ARG *pos=first(); pos ; pos=pos->next)
  1890.   {
  1891.     e_count++;
  1892.     if (pos->next_key_part)
  1893.     {
  1894.       ulong count=count_key_part_usage(root,pos->next_key_part);
  1895.       if (count > pos->next_key_part->use_count)
  1896.       {
  1897. sql_print_error("Use_count: Wrong count for key at %lx, %lu should be %lu",
  1898. pos,pos->next_key_part->use_count,count);
  1899. return;
  1900.       }
  1901.       pos->next_key_part->test_use_count(root);
  1902.     }
  1903.   }
  1904.   if (e_count != elements)
  1905.     sql_print_error("Wrong use count: %u for tree at %lx", e_count,
  1906.     (gptr) this);
  1907. }
  1908. #endif
  1909. /*****************************************************************************
  1910. ** Check how many records we will find by using the found tree
  1911. *****************************************************************************/
  1912. static ha_rows
  1913. check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
  1914. {
  1915.   ha_rows records;
  1916.   DBUG_ENTER("check_quick_select");
  1917.   if (!tree)
  1918.     DBUG_RETURN(HA_POS_ERROR); // Can't use it
  1919.   if (tree->type == SEL_ARG::IMPOSSIBLE)
  1920.     DBUG_RETURN(0L); // Impossible select. return
  1921.   if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
  1922.     DBUG_RETURN(HA_POS_ERROR); // Don't use tree
  1923.   param->max_key_part=0;
  1924.   records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
  1925.   if (records != HA_POS_ERROR)
  1926.   {
  1927.     uint key=param->real_keynr[idx];
  1928.     param->table->quick_keys|= (key_map) 1 << key;
  1929.     param->table->quick_rows[key]=records;
  1930.     param->table->quick_key_parts[key]=param->max_key_part+1;
  1931.   }
  1932.   DBUG_RETURN(records);
  1933. }
  1934. static ha_rows
  1935. check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
  1936.  char *min_key,uint min_key_flag, char *max_key,
  1937.  uint max_key_flag)
  1938. {
  1939.   ha_rows records=0,tmp;
  1940.   param->max_key_part=max(param->max_key_part,key_tree->part);
  1941.   if (key_tree->left != &null_element)
  1942.   {
  1943.     records=check_quick_keys(param,idx,key_tree->left,min_key,min_key_flag,
  1944.      max_key,max_key_flag);
  1945.     if (records == HA_POS_ERROR) // Impossible
  1946.       return records;
  1947.   }
  1948.   uint tmp_min_flag,tmp_max_flag,keynr;
  1949.   char *tmp_min_key=min_key,*tmp_max_key=max_key;
  1950.   key_tree->store(param->key[idx][key_tree->part].part_length,
  1951.   &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
  1952.   uint min_key_length= (uint) (tmp_min_key- param->min_key);
  1953.   uint max_key_length= (uint) (tmp_max_key- param->max_key);
  1954.   if (key_tree->next_key_part &&
  1955.       key_tree->next_key_part->part == key_tree->part+1 &&
  1956.       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
  1957.   { // const key as prefix
  1958.     if (min_key_length == max_key_length &&
  1959. !memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
  1960. !key_tree->min_flag && !key_tree->max_flag)
  1961.     {
  1962.       tmp=check_quick_keys(param,idx,key_tree->next_key_part,
  1963.    tmp_min_key, min_key_flag | key_tree->min_flag,
  1964.    tmp_max_key, max_key_flag | key_tree->max_flag);
  1965.       goto end; // Ugly, but efficient
  1966.     }
  1967.     tmp_min_flag=key_tree->min_flag;
  1968.     tmp_max_flag=key_tree->max_flag;
  1969.     if (!tmp_min_flag)
  1970.       key_tree->next_key_part->store_min_key(param->key[idx], &tmp_min_key,
  1971.      &tmp_min_flag);
  1972.     if (!tmp_max_flag)
  1973.       key_tree->next_key_part->store_max_key(param->key[idx], &tmp_max_key,
  1974.      &tmp_max_flag);
  1975.     min_key_length= (uint) (tmp_min_key- param->min_key);
  1976.     max_key_length= (uint) (tmp_max_key- param->max_key);
  1977.   }
  1978.   else
  1979.   {
  1980.     tmp_min_flag=min_key_flag | key_tree->min_flag;
  1981.     tmp_max_flag=max_key_flag | key_tree->max_flag;
  1982.   }
  1983.   keynr=param->real_keynr[idx];
  1984.   if (!tmp_min_flag && ! tmp_max_flag &&
  1985.       (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
  1986.       (param->table->key_info[keynr].flags & HA_NOSAME) &&
  1987.       min_key_length == max_key_length &&
  1988.       !memcmp(param->min_key,param->max_key,min_key_length))
  1989.     tmp=1; // Max one record
  1990.   else
  1991.       tmp=param->table->file->
  1992. records_in_range((int) keynr,
  1993.  (byte*) (!min_key_length ? NullS :
  1994.   param->min_key),
  1995.  min_key_length,
  1996.  (tmp_min_flag & NEAR_MIN ?
  1997.   HA_READ_AFTER_KEY : HA_READ_KEY_EXACT),
  1998.  (byte*) (!max_key_length ? NullS :
  1999.   param->max_key),
  2000.  max_key_length,
  2001.  (tmp_max_flag & NEAR_MAX ?
  2002.   HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY));
  2003.  end:
  2004.   if (tmp == HA_POS_ERROR) // Impossible range
  2005.     return tmp;
  2006.   records+=tmp;
  2007.   if (key_tree->right != &null_element)
  2008.   {
  2009.     tmp=check_quick_keys(param,idx,key_tree->right,min_key,min_key_flag,
  2010.  max_key,max_key_flag);
  2011.     if (tmp == HA_POS_ERROR)
  2012.       return tmp;
  2013.     records+=tmp;
  2014.   }
  2015.   return records;
  2016. }
  2017. /****************************************************************************
  2018. ** change a tree to a structure to be used by quick_select
  2019. ** This uses it's own malloc tree
  2020. ****************************************************************************/
  2021. static QUICK_SELECT *
  2022. get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
  2023. {
  2024.   QUICK_SELECT *quick;
  2025.   DBUG_ENTER("get_quick_select");
  2026.   if ((quick=new QUICK_SELECT(param->table,param->real_keynr[idx])))
  2027.   {
  2028.     if (quick->error ||
  2029. get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
  2030.        param->max_key,0))
  2031.     {
  2032.       delete quick;
  2033.       quick=0;
  2034.     }
  2035.     else
  2036.     {
  2037.       quick->key_parts=(KEY_PART*)
  2038. sql_memdup(param->key[idx],
  2039.    sizeof(KEY_PART)*
  2040.    param->table->key_info[param->real_keynr[idx]].key_parts);
  2041.     }
  2042.   }
  2043.   DBUG_RETURN(quick);
  2044. }
  2045. /*
  2046. ** Fix this to get all possible sub_ranges
  2047. */
  2048. static bool
  2049. get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
  2050.        SEL_ARG *key_tree,char *min_key,uint min_key_flag,
  2051.        char *max_key, uint max_key_flag)
  2052. {
  2053.   QUICK_RANGE *range;
  2054.   uint flag;
  2055.   if (key_tree->left != &null_element)
  2056.   {
  2057.     if (get_quick_keys(param,quick,key,key_tree->left,
  2058.        min_key,min_key_flag, max_key, max_key_flag))
  2059.       return 1;
  2060.   }
  2061.   char *tmp_min_key=min_key,*tmp_max_key=max_key;
  2062.   key_tree->store(key[key_tree->part].part_length,
  2063.   &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
  2064.   if (key_tree->next_key_part &&
  2065.       key_tree->next_key_part->part == key_tree->part+1 &&
  2066.       key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
  2067.   {   // const key as prefix
  2068.     if (!((tmp_min_key - min_key) != (tmp_max_key - max_key) ||
  2069.   memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) ||
  2070.   key_tree->min_flag || key_tree->max_flag))
  2071.     {
  2072.       if (get_quick_keys(param,quick,key,key_tree->next_key_part,
  2073.  tmp_min_key, min_key_flag | key_tree->min_flag,
  2074.  tmp_max_key, max_key_flag | key_tree->max_flag))
  2075. return 1;
  2076.       goto end; // Ugly, but efficient
  2077.     }
  2078.     {
  2079.       uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
  2080.       if (!tmp_min_flag)
  2081. key_tree->next_key_part->store_min_key(key, &tmp_min_key,
  2082.        &tmp_min_flag);
  2083.       if (!tmp_max_flag)
  2084. key_tree->next_key_part->store_max_key(key, &tmp_max_key,
  2085.        &tmp_max_flag);
  2086.       flag=tmp_min_flag | tmp_max_flag;
  2087.     }
  2088.   }
  2089.   else
  2090.     flag=key_tree->min_flag | key_tree->max_flag;
  2091.   /* Ensure that some part of min_key and max_key are used.  If not,
  2092.      regard this as no lower/upper range */
  2093.   if (tmp_min_key != param->min_key)
  2094.     flag&= ~NO_MIN_RANGE;
  2095.   else
  2096.     flag|= NO_MIN_RANGE;
  2097.   if (tmp_max_key != param->max_key)
  2098.     flag&= ~NO_MAX_RANGE;
  2099.   else
  2100.     flag|= NO_MAX_RANGE;
  2101.   if (flag == 0)
  2102.   {
  2103.     uint length= (uint) (tmp_min_key - param->min_key);
  2104.     if (length == (uint) (tmp_max_key - param->max_key) &&
  2105. !memcmp(param->min_key,param->max_key,length))
  2106.     {
  2107.       KEY *table_key=quick->head->key_info+quick->index;
  2108.       flag=EQ_RANGE;
  2109.       if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1)
  2110. flag|= UNIQUE_RANGE;
  2111.     }
  2112.   }
  2113.   /* Get range for retrieving rows in QUICK_SELECT::get_next */
  2114.   range= new QUICK_RANGE(param->min_key,
  2115.  (uint) (tmp_min_key - param->min_key),
  2116.  param->max_key,
  2117.  (uint) (tmp_max_key - param->max_key),
  2118.  flag);
  2119.   set_if_bigger(quick->max_used_key_length,range->min_length);
  2120.   set_if_bigger(quick->max_used_key_length,range->max_length);
  2121.   if (!range) // Not enough memory
  2122.     return 1;
  2123.   quick->ranges.push_back(range);
  2124.  end:
  2125.   if (key_tree->right != &null_element)
  2126.     return get_quick_keys(param,quick,key,key_tree->right,
  2127.   min_key,min_key_flag,
  2128.   max_key,max_key_flag);
  2129.   return 0;
  2130. }
  2131. /*
  2132.   Return 1 if there is only one range and this uses the whole primary key
  2133. */
  2134. bool QUICK_SELECT::unique_key_range()
  2135. {
  2136.   if (ranges.elements == 1)
  2137.   {
  2138.     QUICK_RANGE *tmp;
  2139.     if ((tmp=ranges.head())->flag & EQ_RANGE)
  2140.     {
  2141.       KEY *key=head->key_info+index;
  2142.       return ((key->flags & HA_NOSAME) &&
  2143.       key->key_length == tmp->min_length);
  2144.     }
  2145.   }
  2146.   return 0;
  2147. }
  2148. /****************************************************************************
  2149. ** Create a QUICK RANGE based on a key
  2150. ****************************************************************************/
  2151. QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
  2152. {
  2153.   table->file->index_end(); // Remove old cursor
  2154.   QUICK_SELECT *quick=new QUICK_SELECT(table, ref->key, 1);
  2155.   KEY *key_info = &table->key_info[ref->key];
  2156.   KEY_PART *key_part;
  2157.   uint part;
  2158.   if (!quick)
  2159.     return 0;
  2160.   QUICK_RANGE *range= new QUICK_RANGE();
  2161.   if (!range || cp_buffer_from_ref(ref))
  2162.     goto err;
  2163.   range->min_key=range->max_key=(char*) ref->key_buff;
  2164.   range->min_length=range->max_length=ref->key_length;
  2165.   range->flag= ((ref->key_length == key_info->key_length &&
  2166.  (key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0);
  2167.   if (!(quick->key_parts=key_part=(KEY_PART *)
  2168. sql_alloc(sizeof(KEY_PART)*ref->key_parts)))
  2169.     goto err;
  2170.   for (part=0 ; part < ref->key_parts ;part++,key_part++)
  2171.   {
  2172.     key_part->part=part;
  2173.     key_part->field=        key_info->key_part[part].field;
  2174.     key_part->part_length=  key_info->key_part[part].length;
  2175.     if (key_part->field->type() == FIELD_TYPE_BLOB)
  2176.       key_part->part_length+=HA_KEY_BLOB_LENGTH;
  2177.     key_part->null_bit=     key_info->key_part[part].null_bit;
  2178.   }
  2179.   if (!quick->ranges.push_back(range))
  2180.     return quick;
  2181. err:
  2182.   delete quick;
  2183.   return 0;
  2184. }
  2185. /* get next possible record using quick-struct */
  2186. int QUICK_SELECT::get_next()
  2187. {
  2188.   DBUG_ENTER("get_next");
  2189.   for (;;)
  2190.   {
  2191.     if (range)
  2192.     { // Already read through key
  2193.       int result=((range->flag & EQ_RANGE) ?
  2194.   file->index_next_same(record, (byte*) range->min_key,
  2195. range->min_length) :
  2196.   file->index_next(record));
  2197.       if (!result && !cmp_next(*it.ref()))
  2198. DBUG_RETURN(0);
  2199.     }
  2200.     if (!(range=it++))
  2201.       DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
  2202.     if (range->flag & NO_MIN_RANGE) // Read first record
  2203.     {
  2204.       int error;
  2205.       if ((error=file->index_first(record)))
  2206. DBUG_RETURN(error); // Empty table
  2207.       if (cmp_next(range) == 0)
  2208. DBUG_RETURN(0); // No matching records
  2209.       range=0; // To next range
  2210.       continue;
  2211.     }
  2212.     if (file->index_read(record,(byte*) range->min_key,
  2213.  range->min_length,
  2214.  ((range->flag & NEAR_MIN) ?
  2215.   HA_READ_AFTER_KEY:
  2216.   (range->flag & EQ_RANGE) ?
  2217.   HA_READ_KEY_EXACT :
  2218.   HA_READ_KEY_OR_NEXT)))
  2219.     {
  2220.       range=0; // Not found, to next range
  2221.       continue;
  2222.     }
  2223.     if (cmp_next(range) == 0)
  2224.     {
  2225.       if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
  2226. range=0; // Stop searching
  2227.       DBUG_RETURN(0); // Found key is in range
  2228.     }
  2229.     range=0; // To next range
  2230.   }
  2231. }
  2232. /* compare if found key is over max-value */
  2233. /* Returns 0 if key <= range->max_key */
  2234. int QUICK_SELECT::cmp_next(QUICK_RANGE *range)
  2235. {
  2236.   if (range->flag & NO_MAX_RANGE)
  2237.     return (0); /* key can't be to large */
  2238.   KEY_PART *key_part=key_parts;
  2239.   for (char *key=range->max_key, *end=key+range->max_length;
  2240.        key < end;
  2241.        key+= key_part++->part_length)
  2242.   {
  2243.     int cmp;
  2244.     if (key_part->null_bit)
  2245.     {
  2246.       if (*key++)
  2247.       {
  2248. if (!key_part->field->is_null())
  2249.   return 1;
  2250. continue;
  2251.       }
  2252.       else if (key_part->field->is_null())
  2253. return 0;
  2254.     }
  2255.     if ((cmp=key_part->field->key_cmp((byte*) key, key_part->part_length)) < 0)
  2256.       return 0;
  2257.     if (cmp > 0)
  2258.       return 1;
  2259.   }
  2260.   return (range->flag & NEAR_MAX) ? 1 : 0; // Exact match
  2261. }
  2262. /*****************************************************************************
  2263. ** Print a quick range for debugging
  2264. ** TODO:
  2265. ** This should be changed to use a String to store each row instead
  2266. ** of locking the DEBUG stream !
  2267. *****************************************************************************/
  2268. #ifndef DBUG_OFF
  2269. static void
  2270. print_key(KEY_PART *key_part,const char *key,uint used_length)
  2271. {
  2272.   char buff[1024];
  2273.   String tmp(buff,sizeof(buff));
  2274.   for (uint length=0;
  2275.        length < used_length ;
  2276.        length+=key_part->part_length, key+=key_part->part_length, key_part++)
  2277.   {
  2278.     Field *field=key_part->field;
  2279.     if (length != 0)
  2280.       fputc('/',DBUG_FILE);
  2281.     if (field->real_maybe_null())
  2282.     {
  2283.       length++; // null byte is not in part_length 
  2284.       if (*key++)
  2285.       {
  2286. fwrite("NULL",sizeof(char),4,DBUG_FILE);
  2287. continue;
  2288.       }
  2289.     }
  2290.     field->set_key_image((char*) key,key_part->part_length -
  2291.  ((field->type() == FIELD_TYPE_BLOB) ?
  2292.   HA_KEY_BLOB_LENGTH : 0));
  2293.     field->val_str(&tmp,&tmp);
  2294.     fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
  2295.   }
  2296. }
  2297. static void print_quick(QUICK_SELECT *quick,key_map needed_reg)
  2298. {
  2299.   QUICK_RANGE *range;
  2300.   DBUG_ENTER("print_param");
  2301.   if (! _db_on_ || !quick)
  2302.     DBUG_VOID_RETURN;
  2303.   List_iterator<QUICK_RANGE> li(quick->ranges);
  2304.   DBUG_LOCK_FILE;
  2305.   fprintf(DBUG_FILE,"Used quick_range on key: %d (other_keys: %lu):n",
  2306.   quick->index, (ulong) needed_reg);
  2307.   while ((range=li++))
  2308.   {
  2309.     if (!(range->flag & NO_MIN_RANGE))
  2310.     {
  2311.       print_key(quick->key_parts,range->min_key,range->min_length);
  2312.       if (range->flag & NEAR_MIN)
  2313. fputs(" < ",DBUG_FILE);
  2314.       else
  2315. fputs(" <= ",DBUG_FILE);
  2316.     }
  2317.     fputs("X",DBUG_FILE);
  2318.     if (!(range->flag & NO_MAX_RANGE))
  2319.     {
  2320.       if (range->flag & NEAR_MAX)
  2321. fputs(" < ",DBUG_FILE);
  2322.       else
  2323. fputs(" <= ",DBUG_FILE);
  2324.       print_key(quick->key_parts,range->max_key,range->max_length);
  2325.     }
  2326.     fputs("n",DBUG_FILE);
  2327.   }
  2328.   DBUG_UNLOCK_FILE;
  2329.   DBUG_VOID_RETURN;
  2330. }
  2331. #endif
  2332. /*****************************************************************************
  2333. ** Instansiate templates
  2334. *****************************************************************************/
  2335. #ifdef __GNUC__
  2336. template class List<QUICK_RANGE>;
  2337. template class List_iterator<QUICK_RANGE>;
  2338. #endif