Drizzled Public API Documentation

sum.cc
Go to the documentation of this file.
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008-2009 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
54 #include <config.h>
55 
56 #include <drizzled/sql_select.h>
57 #include <drizzled/item/sum.h>
58 #include <drizzled/item/cmpfunc.h>
59 #include <drizzled/optimizer/sum.h>
60 #include <drizzled/plugin/storage_engine.h>
61 #include <drizzled/table_list.h>
62 #include <drizzled/key.h>
63 #include <drizzled/error.h>
64 
65 namespace drizzled
66 {
67 
68 static bool find_key_for_maxmin(bool max_fl,
69  table_reference_st *ref,
70  Field* field,
71  COND *cond,
72  uint32_t *range_fl,
73  uint32_t *key_prefix_length);
74 
75 static int reckey_in_range(bool max_fl,
76  table_reference_st *ref,
77  Field* field,
78  COND *cond,
79  uint32_t range_fl,
80  uint32_t prefix_len);
81 
82 static int maxmin_in_range(bool max_fl, Field *field, COND *cond);
83 
84 
85 /*
86  Get exact count of rows in all tables
87 
88  SYNOPSIS
89  get_exact_records()
90  tables List of tables
91 
92  NOTES
93  When this is called, we know all table handlers supports HA_HAS_RECORDS
94  or HA_STATS_RECORDS_IS_EXACT
95 
96  RETURN
97  UINT64_MAX Error: Could not calculate number of rows
98  # Multiplication of number of rows in all tables
99 */
100 static uint64_t get_exact_record_count(TableList *tables)
101 {
102  uint64_t count= 1;
103  for (TableList *tl= tables; tl; tl= tl->next_leaf)
104  {
105  ha_rows tmp= tl->table->cursor->records();
106  if ((tmp == HA_POS_ERROR))
107  {
108  return UINT64_MAX;
109  }
110  count*= tmp;
111  }
112  return count;
113 }
114 
115 
116 int optimizer::sum_query(TableList *tables, List<Item> &all_fields, COND *conds)
117 {
118  List<Item>::iterator it(all_fields.begin());
119  int const_result= 1;
120  bool recalc_const_item= false;
121  uint64_t count= 1;
122  bool is_exact_count= true;
123  bool maybe_exact_count= true;
124  table_map removed_tables= 0;
125  table_map outer_tables= 0;
126  table_map used_tables= 0;
127  table_map where_tables= 0;
128  Item *item= NULL;
129  int error;
130 
131  if (conds)
132  {
133  where_tables= conds->used_tables();
134  }
135 
136  /*
137  Analyze outer join dependencies, and, if possible, compute the number
138  of returned rows.
139  */
140  for (TableList *tl= tables; tl; tl= tl->next_leaf)
141  {
142  TableList *embedded= NULL;
143  for (embedded= tl; embedded; embedded= embedded->getEmbedding())
144  {
145  if (embedded->on_expr)
146  break;
147  }
148  if (embedded)
149  /* Don't replace expression on a table that is part of an outer join */
150  {
151  outer_tables|= tl->table->map;
152 
153  /*
154  We can't optimise LEFT JOIN in cases where the WHERE condition
155  restricts the table that is used, like in:
156  SELECT MAX(t1.a) FROM t1 LEFT JOIN t2 join-condition
157  WHERE t2.field IS NULL;
158  */
159  if (tl->table->map & where_tables)
160  return 0;
161  }
162  else
163  {
164  used_tables|= tl->table->map;
165  }
166 
167  /*
168  If the storage manager of 'tl' gives exact row count as part of
169  statistics (cheap), compute the total number of rows. If there are
170  no outer table dependencies, this count may be used as the real count.
171  Schema tables are filled after this function is invoked, so we can't
172  get row count
173  */
174  if (! (tl->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT)))
175  {
176  maybe_exact_count&= test(tl->table->cursor->getEngine()->check_flag(HTON_BIT_HAS_RECORDS));
177  is_exact_count= false;
178  count= 1; // ensure count != 0
179  }
180  else
181  {
182  error= tl->table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
183  if(error)
184  {
185  tl->table->print_error(error, MYF(ME_FATALERROR));
186  return error;
187  }
188  count*= tl->table->cursor->stats.records;
189  }
190  }
191 
192  /*
193  Iterate through all items in the SELECT clause and replace
194  COUNT(), MIN() and MAX() with constants (if possible).
195  */
196 
197  while ((item= it++))
198  {
199  if (item->type() == Item::SUM_FUNC_ITEM)
200  {
201  Item_sum *item_sum= (((Item_sum*) item));
202  switch (item_sum->sum_func())
203  {
204  case Item_sum::COUNT_FUNC:
205  /*
206  If the expr in COUNT(expr) can never be null we can change this
207  to the number of rows in the tables if this number is exact and
208  there are no outer joins.
209  */
210  if (! conds && ! ((Item_sum_count*) item)->args[0]->maybe_null &&
211  ! outer_tables && maybe_exact_count)
212  {
213  if (! is_exact_count)
214  {
215  if ((count= get_exact_record_count(tables)) == UINT64_MAX)
216  {
217  /* Error from handler in counting rows. Don't optimize count() */
218  const_result= 0;
219  continue;
220  }
221  is_exact_count= 1; // count is now exact
222  }
223  ((Item_sum_count*) item)->make_const_count((int64_t) count);
224  recalc_const_item= 1;
225  }
226  else
227  {
228  const_result= 0;
229  }
230  break;
231  case Item_sum::MIN_FUNC:
232  {
233  /*
234  If MIN(expr) is the first part of a key or if all previous
235  parts of the key is found in the COND, then we can use
236  indexes to find the key.
237  */
238  Item *expr=item_sum->args[0];
239  if (expr->real_item()->type() == Item::FIELD_ITEM)
240  {
241  unsigned char key_buff[MAX_KEY_LENGTH];
242  table_reference_st ref;
243  uint32_t range_fl, prefix_len;
244 
245  ref.key_buff= key_buff;
246  Item_field *item_field= (Item_field*) (expr->real_item());
247  Table *table= item_field->field->getTable();
248 
249  /*
250  Look for a partial key that can be used for optimization.
251  If we succeed, ref.key_length will contain the length of
252  this key, while prefix_len will contain the length of
253  the beginning of this key without field used in MIN().
254  Type of range for the key part for this field will be
255  returned in range_fl.
256  */
257  if (table->cursor->inited ||
258  (outer_tables & table->map) ||
260  &ref,
261  item_field->field,
262  conds,
263  &range_fl,
264  &prefix_len))
265  {
266  const_result= 0;
267  break;
268  }
269  error= table->cursor->startIndexScan(static_cast<uint32_t>(ref.key), 1);
270  if (error)
271  {
272  if (table->key_read)
273  {
274  table->key_read= 0;
275  table->cursor->extra(HA_EXTRA_NO_KEYREAD);
276  }
277  table->print_error(error, MYF(0));
278  return error;
279  }
280 
281  if (! ref.key_length)
282  {
283  error= table->cursor->index_first(table->record[0]);
284  }
285  else
286  {
287  /*
288  Use index to replace MIN/MAX functions with their values
289  according to the following rules:
290 
291  1) Insert the minimum non-null values where the WHERE clause still
292  matches, or
293  2) a NULL value if there are only NULL values for key_part_k.
294  3) Fail, producing a row of nulls
295 
296  Implementation: Read the smallest value using the search key. If
297  the interval is open, read the next value after the search
298  key. If read fails, and we're looking for a MIN() value for a
299  nullable column, test if there is an exact match for the key.
300  */
301  if (! (range_fl & NEAR_MIN))
302  {
303  /*
304  Closed interval: Either The MIN argument is non-nullable, or
305  we have a >= predicate for the MIN argument.
306  */
307  error= table->cursor->index_read_map(table->record[0],
308  ref.key_buff,
309  make_prev_keypart_map(ref.key_parts),
310  HA_READ_KEY_OR_NEXT);
311  }
312  else
313  {
314  /*
315  Open interval: There are two cases:
316  1) We have only MIN() and the argument column is nullable, or
317  2) there is a > predicate on it, nullability is irrelevant.
318  We need to scan the next bigger record first.
319  */
320  error= table->cursor->index_read_map(table->record[0],
321  ref.key_buff,
322  make_prev_keypart_map(ref.key_parts),
323  HA_READ_AFTER_KEY);
324  /*
325  If the found record is outside the group formed by the search
326  prefix, or there is no such record at all, check if all
327  records in that group have NULL in the MIN argument
328  column. If that is the case return that NULL.
329 
330  Check if case 1 from above holds. If it does, we should read
331  the skipped tuple.
332  */
333  if (item_field->field->real_maybe_null() &&
334  ref.key_buff[prefix_len] == 1 &&
335  /*
336  Last keypart (i.e. the argument to MIN) is set to NULL by
337  find_key_for_maxmin only if all other keyparts are bound
338  to constants in a conjunction of equalities. Hence, we
339  can detect this by checking only if the last keypart is
340  NULL.
341  */
342  (error == HA_ERR_KEY_NOT_FOUND ||
343  key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len)))
344  {
345  assert(item_field->field->real_maybe_null());
346  error= table->cursor->index_read_map(table->record[0],
347  ref.key_buff,
348  make_prev_keypart_map(ref.key_parts),
349  HA_READ_KEY_EXACT);
350  }
351  }
352  }
353  /* Verify that the read tuple indeed matches the search key */
354  if (! error &&
355  reckey_in_range(0,
356  &ref,
357  item_field->field,
358  conds,
359  range_fl,
360  prefix_len))
361  {
362  error= HA_ERR_KEY_NOT_FOUND;
363  }
364  if (table->key_read)
365  {
366  table->key_read= 0;
367  table->cursor->extra(HA_EXTRA_NO_KEYREAD);
368  }
369  table->cursor->endIndexScan();
370  if (error)
371  {
372  if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
373  {
374  return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
375  }
376  /* HA_ERR_LOCK_DEADLOCK or some other error */
377  table->print_error(error, MYF(0));
378  return error;
379  }
380  removed_tables|= table->map;
381  }
382  else if (! expr->const_item() || ! is_exact_count)
383  {
384  /*
385  The optimization is not applicable in both cases:
386  (a) 'expr' is a non-constant expression. Then we can't
387  replace 'expr' by a constant.
388  (b) 'expr' is a costant. According to ANSI, MIN/MAX must return
389  NULL if the query does not return any rows. Thus, if we are not
390  able to determine if the query returns any rows, we can't apply
391  the optimization and replace MIN/MAX with a constant.
392  */
393  const_result= 0;
394  break;
395  }
396  if (! count)
397  {
398  /* If count == 0, then we know that is_exact_count == true. */
399  ((Item_sum_min*) item_sum)->clear(); /* Set to NULL. */
400  }
401  else
402  {
403  ((Item_sum_min*) item_sum)->reset(); /* Set to the constant value. */
404  }
405  ((Item_sum_min*) item_sum)->make_const();
406  recalc_const_item= 1;
407  break;
408  }
409  case Item_sum::MAX_FUNC:
410  {
411  /*
412  If MAX(expr) is the first part of a key or if all previous
413  parts of the key is found in the COND, then we can use
414  indexes to find the key.
415  */
416  Item *expr= item_sum->args[0];
417  if (expr->real_item()->type() == Item::FIELD_ITEM)
418  {
419  unsigned char key_buff[MAX_KEY_LENGTH];
420  table_reference_st ref;
421  uint32_t range_fl, prefix_len;
422 
423  ref.key_buff= key_buff;
424  Item_field *item_field= (Item_field*) (expr->real_item());
425  Table *table= item_field->field->getTable();
426 
427  /*
428  Look for a partial key that can be used for optimization.
429  If we succeed, ref.key_length will contain the length of
430  this key, while prefix_len will contain the length of
431  the beginning of this key without field used in MAX().
432  Type of range for the key part for this field will be
433  returned in range_fl.
434  */
435  if (table->cursor->inited ||
436  (outer_tables & table->map) ||
438  &ref,
439  item_field->field,
440  conds,
441  &range_fl,
442  &prefix_len))
443  {
444  const_result= 0;
445  break;
446  }
447  error= table->cursor->startIndexScan(static_cast<uint32_t>(ref.key), 1);
448 
449  if (! ref.key_length)
450  {
451  error= table->cursor->index_last(table->record[0]);
452  }
453  else
454  {
455  error= table->cursor->index_read_map(table->record[0],
456  key_buff,
457  make_prev_keypart_map(ref.key_parts),
458  range_fl & NEAR_MAX ?
459  HA_READ_BEFORE_KEY :
460  HA_READ_PREFIX_LAST_OR_PREV);
461  }
462  if (! error &&
463  reckey_in_range(1,
464  &ref,
465  item_field->field,
466  conds,
467  range_fl,
468  prefix_len))
469  {
470  error= HA_ERR_KEY_NOT_FOUND;
471  }
472  if (table->key_read)
473  {
474  table->key_read= 0;
475  table->cursor->extra(HA_EXTRA_NO_KEYREAD);
476  }
477  table->cursor->endIndexScan();
478  if (error)
479  {
480  if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
481  {
482  return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
483  }
484  /* HA_ERR_LOCK_DEADLOCK or some other error */
485  table->print_error(error, MYF(ME_FATALERROR));
486  return error;
487  }
488  removed_tables|= table->map;
489  }
490  else if (! expr->const_item() || ! is_exact_count)
491  {
492  /*
493  The optimization is not applicable in both cases:
494  (a) 'expr' is a non-constant expression. Then we can't
495  replace 'expr' by a constant.
496  (b) 'expr' is a costant. According to ANSI, MIN/MAX must return
497  NULL if the query does not return any rows. Thus, if we are not
498  able to determine if the query returns any rows, we can't apply
499  the optimization and replace MIN/MAX with a constant.
500  */
501  const_result= 0;
502  break;
503  }
504  if (! count)
505  {
506  /* If count != 1, then we know that is_exact_count == true. */
507  ((Item_sum_max*) item_sum)->clear(); /* Set to NULL. */
508  }
509  else
510  {
511  ((Item_sum_max*) item_sum)->reset(); /* Set to the constant value. */
512  }
513  ((Item_sum_max*) item_sum)->make_const();
514  recalc_const_item= 1;
515  break;
516  }
517  default:
518  const_result= 0;
519  break;
520  }
521  }
522  else if (const_result)
523  {
524  if (recalc_const_item)
525  {
526  item->update_used_tables();
527  }
528  if (! item->const_item())
529  {
530  const_result= 0;
531  }
532  }
533  }
534  /*
535  If we have a where clause, we can only ignore searching in the
536  tables if MIN/MAX optimisation replaced all used tables
537  We do not use replaced values in case of:
538  SELECT MIN(key) FROM table_1, empty_table
539  removed_tables is != 0 if we have used MIN() or MAX().
540  */
541  if (removed_tables && used_tables != removed_tables)
542  {
543  const_result= 0; // We didn't remove all tables
544  }
545  return const_result;
546 }
547 
548 
549 bool optimizer::simple_pred(Item_func *func_item, Item **args, bool &inv_order)
550 {
551  Item *item= NULL;
552  inv_order= false;
553  switch (func_item->argument_count())
554  {
555  case 0:
556  /* MULT_EQUAL_FUNC */
557  {
558  Item_equal *item_equal= (Item_equal *) func_item;
559  Item_equal_iterator it(item_equal->begin());
560  args[0]= it++;
561  if (it++)
562  {
563  return 0;
564  }
565  if (! (args[1]= item_equal->get_const()))
566  {
567  return 0;
568  }
569  }
570  break;
571  case 1:
572  /* field IS NULL */
573  item= func_item->arguments()[0];
574  if (item->type() != Item::FIELD_ITEM)
575  {
576  return 0;
577  }
578  args[0]= item;
579  break;
580  case 2:
581  /* 'field op const' or 'const op field' */
582  item= func_item->arguments()[0];
583  if (item->type() == Item::FIELD_ITEM)
584  {
585  args[0]= item;
586  item= func_item->arguments()[1];
587  if (! item->const_item())
588  {
589  return 0;
590  }
591  args[1]= item;
592  }
593  else if (item->const_item())
594  {
595  args[1]= item;
596  item= func_item->arguments()[1];
597  if (item->type() != Item::FIELD_ITEM)
598  {
599  return 0;
600  }
601  args[0]= item;
602  inv_order= true;
603  }
604  else
605  {
606  return 0;
607  }
608  break;
609  case 3:
610  /* field BETWEEN const AND const */
611  item= func_item->arguments()[0];
612  if (item->type() == Item::FIELD_ITEM)
613  {
614  args[0]= item;
615  for (int i= 1 ; i <= 2; i++)
616  {
617  item= func_item->arguments()[i];
618  if (! item->const_item())
619  {
620  return 0;
621  }
622  args[i]= item;
623  }
624  }
625  else
626  {
627  return 0;
628  }
629  }
630  return 1;
631 }
632 
633 
663 static bool matching_cond(bool max_fl,
664  table_reference_st *ref,
665  KeyInfo *keyinfo,
666  KeyPartInfo *field_part,
667  COND *cond,
668  key_part_map *key_part_used,
669  uint32_t *range_fl,
670  uint32_t *prefix_len)
671 {
672  if (! cond)
673  {
674  return 1;
675  }
676  Field *field= field_part->field;
677 
678  field->setWriteSet();
679 
680  if (! (cond->used_tables() & field->getTable()->map))
681  {
682  /* Condition doesn't restrict the used table */
683  return 1;
684  }
685  if (cond->type() == Item::COND_ITEM)
686  {
687  if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
688  {
689  return 0;
690  }
691 
692  /* AND */
693  List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
694  Item *item;
695  while ((item= li++))
696  {
697  if (! matching_cond(max_fl,
698  ref,
699  keyinfo,
700  field_part,
701  item,
702  key_part_used,
703  range_fl,
704  prefix_len))
705  {
706  return 0;
707  }
708  }
709  return 1;
710  }
711 
712  if (cond->type() != Item::FUNC_ITEM)
713  {
714  return 0; // Not operator, can't optimize
715  }
716 
717  bool eq_type= false; // =, <=> or IS NULL
718  bool noeq_type= false; // < or >
719  bool less_fl= false; // < or <=
720  bool is_null= false;
721  bool between= false;
722 
723  switch (((Item_func*) cond)->functype())
724  {
725  case Item_func::ISNULL_FUNC:
726  is_null= 1; /* fall through */
727  case Item_func::EQ_FUNC:
728  case Item_func::EQUAL_FUNC:
729  eq_type= 1;
730  break;
731  case Item_func::LT_FUNC:
732  noeq_type= 1; /* fall through */
733  case Item_func::LE_FUNC:
734  less_fl= 1;
735  break;
736  case Item_func::GT_FUNC:
737  noeq_type= 1; /* fall through */
738  case Item_func::GE_FUNC:
739  break;
740  case Item_func::BETWEEN:
741  between= 1;
742  break;
743  case Item_func::MULT_EQUAL_FUNC:
744  eq_type= 1;
745  break;
746  default:
747  return 0; // Can't optimize function
748  }
749 
750  Item *args[3];
751  bool inv;
752 
753  /* Test if this is a comparison of a field and constant */
754  if (! optimizer::simple_pred((Item_func*) cond, args, inv))
755  {
756  return 0;
757  }
758 
759  if (inv && ! eq_type)
760  {
761  less_fl= 1 - less_fl; // Convert '<' -> '>' (etc)
762  }
763 
764  /* Check if field is part of the tested partial key */
765  unsigned char *key_ptr= ref->key_buff;
766  KeyPartInfo *part= NULL;
767  for (part= keyinfo->key_part; ; key_ptr+= part++->store_length)
768 
769  {
770  if (part > field_part)
771  {
772  return 0; // Field is beyond the tested parts
773  }
774  if (part->field->eq(((Item_field*) args[0])->field))
775  {
776  break; // Found a part of the key for the field
777  }
778  }
779 
780  bool is_field_part= part == field_part;
781  if (! (is_field_part || eq_type))
782  {
783  return 0;
784  }
785 
786  key_part_map org_key_part_used= *key_part_used;
787  if (eq_type || between || max_fl == less_fl)
788  {
789  uint32_t length= (key_ptr-ref->key_buff)+part->store_length;
790  if (ref->key_length < length)
791  {
792  /* Ultimately ref->key_length will contain the length of the search key */
793  ref->key_length= length;
794  ref->key_parts= (part - keyinfo->key_part) + 1;
795  }
796  if (! *prefix_len && part + 1 == field_part)
797  {
798  *prefix_len= length;
799  }
800  if (is_field_part && eq_type)
801  {
802  *prefix_len= ref->key_length;
803  }
804 
805  *key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
806  }
807 
808  if (org_key_part_used != *key_part_used ||
809  (is_field_part &&
810  (between || eq_type || max_fl == less_fl) && ! cond->val_int()))
811  {
812  /*
813  It's the first predicate for this part or a predicate of the
814  following form that moves upper/lower bounds for max/min values:
815  - field BETWEEN const AND const
816  - field = const
817  - field {<|<=} const, when searching for MAX
818  - field {>|>=} const, when searching for MIN
819  */
820 
821  if (is_null)
822  {
823  part->field->set_null();
824  *key_ptr= (unsigned char) 1;
825  }
826  else
827  {
828  store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
829  CHECK_FIELD_IGNORE);
830  if (part->null_bit)
831  {
832  *key_ptr++= (unsigned char) test(part->field->is_null());
833  }
834  part->field->get_key_image(key_ptr, part->length);
835  }
836  if (is_field_part)
837  {
838  if (between || eq_type)
839  {
840  *range_fl&= ~(NO_MAX_RANGE | NO_MIN_RANGE);
841  }
842  else
843  {
844  *range_fl&= ~(max_fl ? NO_MAX_RANGE : NO_MIN_RANGE);
845  if (noeq_type)
846  {
847  *range_fl|= (max_fl ? NEAR_MAX : NEAR_MIN);
848  }
849  else
850  {
851  *range_fl&= ~(max_fl ? NEAR_MAX : NEAR_MIN);
852  }
853  }
854  }
855  }
856  else if (eq_type)
857  {
858  if ((! is_null && !cond->val_int()) ||
859  (is_null && !test(part->field->is_null())))
860  {
861  return 0; // Impossible test
862  }
863  }
864  else if (is_field_part)
865  {
866  *range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
867  }
868  return 1;
869 }
870 
871 
913 static bool find_key_for_maxmin(bool max_fl,
914  table_reference_st *ref,
915  Field* field,
916  COND *cond,
917  uint32_t *range_fl,
918  uint32_t *prefix_len)
919 {
920  if (! (field->flags & PART_KEY_FLAG))
921  {
922  return 0; // Not key field
923  }
924 
925  Table *table= field->getTable();
926  uint32_t idx= 0;
927 
928  KeyInfo *keyinfo,*keyinfo_end= NULL;
929  for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->getShare()->sizeKeys();
930  keyinfo != keyinfo_end;
931  keyinfo++,idx++)
932  {
933  KeyPartInfo *part= NULL;
934  KeyPartInfo *part_end= NULL;
935  key_part_map key_part_to_use= 0;
936  /*
937  Perform a check if index is not disabled by ALTER Table
938  or IGNORE INDEX.
939  */
940  if (! table->keys_in_use_for_query.test(idx))
941  {
942  continue;
943  }
944  uint32_t jdx= 0;
945  *prefix_len= 0;
946  for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts;
947  part != part_end;
948  part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1)
949  {
950  if (! (table->index_flags(idx) & HA_READ_ORDER))
951  {
952  return 0;
953  }
954 
955  /* Check whether the index component is partial */
956  Field *part_field= table->getField(part->fieldnr-1);
957  part_field->setWriteSet();
958 
959  if ((part_field->flags & BLOB_FLAG) ||
960  part->length < part_field->key_length())
961  {
962  break;
963  }
964 
965  if (field->eq(part->field))
966  {
967  ref->key= idx;
968  ref->key_length= 0;
969  ref->key_parts= 0;
970  key_part_map key_part_used= 0;
971  *range_fl= NO_MIN_RANGE | NO_MAX_RANGE;
972  if (matching_cond(max_fl,
973  ref,
974  keyinfo,
975  part,
976  cond,
977  &key_part_used,
978  range_fl,
979  prefix_len) &&
980  ! (key_part_to_use & ~key_part_used))
981  {
982  if (! max_fl && key_part_used == key_part_to_use && part->null_bit)
983  {
984  /*
985  The query is on this form:
986 
987  SELECT MIN(key_part_k)
988  FROM t1
989  WHERE key_part_1 = const and ... and key_part_k-1 = const
990 
991  If key_part_k is nullable, we want to find the first matching row
992  where key_part_k is not null. The key buffer is now {const, ...,
993  NULL}. This will be passed to the handler along with a flag
994  indicating open interval. If a tuple is read that does not match
995  these search criteria, an attempt will be made to read an exact
996  match for the key buffer.
997  */
998  /* Set the first byte of key_part_k to 1, that means NULL */
999  ref->key_buff[ref->key_length]= 1;
1000  ref->key_length+= part->store_length;
1001  ref->key_parts++;
1002  assert(ref->key_parts == jdx+1);
1003  *range_fl&= ~NO_MIN_RANGE;
1004  *range_fl|= NEAR_MIN; // Open interval
1005  }
1006  /*
1007  The following test is false when the key in the key tree is
1008  converted (for example to upper case)
1009  */
1010  if (field->part_of_key.test(idx))
1011  {
1012  table->key_read= 1;
1013  table->cursor->extra(HA_EXTRA_KEYREAD);
1014  }
1015  return 1;
1016  }
1017  }
1018  }
1019  }
1020  return 0;
1021 }
1022 
1023 
1039 static int reckey_in_range(bool max_fl,
1040  table_reference_st *ref,
1041  Field* field,
1042  COND *cond,
1043  uint32_t range_fl,
1044  uint32_t prefix_len)
1045 {
1046  if (key_cmp_if_same(field->getTable(), ref->key_buff, ref->key, prefix_len))
1047  {
1048  return 1;
1049  }
1050  if (! cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE)))
1051  {
1052  return 0;
1053  }
1054  return maxmin_in_range(max_fl, field, cond);
1055 }
1056 
1057 
1070 static int maxmin_in_range(bool max_fl, Field* field, COND *cond)
1071 {
1072  /* If AND/OR condition */
1073  if (cond->type() == Item::COND_ITEM)
1074  {
1075  List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
1076  while (Item* item= li++)
1077  {
1078  if (maxmin_in_range(max_fl, field, item))
1079  return 1;
1080  }
1081  return 0;
1082  }
1083 
1084  if (cond->used_tables() != field->getTable()->map)
1085  {
1086  return 0;
1087  }
1088  bool less_fl= false;
1089  switch (((Item_func*) cond)->functype())
1090  {
1091  case Item_func::BETWEEN:
1092  return cond->val_int() == 0; // Return 1 if WHERE is false
1093  case Item_func::LT_FUNC:
1094  case Item_func::LE_FUNC:
1095  less_fl= 1;
1096  case Item_func::GT_FUNC:
1097  case Item_func::GE_FUNC:
1098  {
1099  Item *item= ((Item_func*) cond)->arguments()[1];
1100  /* In case of 'const op item' we have to swap the operator */
1101  if (! item->const_item())
1102  {
1103  less_fl= 1-less_fl;
1104  }
1105  /*
1106  We only have to check the expression if we are using an expression like
1107  SELECT MAX(b) FROM t1 WHERE a=const AND b>const
1108  not for
1109  SELECT MAX(b) FROM t1 WHERE a=const AND b<const
1110  */
1111  if (max_fl != less_fl)
1112  {
1113  return cond->val_int() == 0; // Return 1 if WHERE is false
1114  }
1115  return 0;
1116  }
1117  case Item_func::EQ_FUNC:
1118  case Item_func::EQUAL_FUNC:
1119  break;
1120  default:
1121  ; // assert(false); // Impossible; Olaf: Not really, assert is hit. BUG?
1122  }
1123  return 0;
1124 }
1125 
1126 } /* namespace drizzled */
1127 
virtual bool const_item() const
Definition: item.h:495
table_map map
ID bit of table (1,2,4,8,16...)
Definition: table.h:270
virtual int64_t val_int()=0
virtual uint32_t get_key_image(unsigned char *buff, uint32_t length)
Definition: field.h:421
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
Definition: sql_select.cc:975
static bool matching_cond(bool max_fl, table_reference_st *ref, KeyInfo *keyinfo, KeyPartInfo *field_part, COND *cond, key_part_map *key_part_used, uint32_t *range_fl, uint32_t *prefix_len)
Definition: sum.cc:663
static int reckey_in_range(bool max_fl, table_reference_st *ref, Field *field, COND *cond, uint32_t range_fl, uint32_t prefix_len)
Definition: sum.cc:1039
KeyInfo * key_info
Definition: table.h:141
Cursor * cursor
Definition: table.h:68
virtual table_map used_tables() const
Definition: item.h:451
static int maxmin_in_range(bool max_fl, Field *field, COND *cond)
Definition: sum.cc:1070
static bool find_key_for_maxmin(bool max_fl, table_reference_st *ref, Field *field, COND *cond, uint32_t *range_fl, uint32_t *key_prefix_length)
Definition: sum.cc:913
bool key_cmp_if_same(Table *table, const unsigned char *key, uint32_t idx, uint32_t key_length)
Definition: key.cc:266