~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/sum.cc

  • Committer: Brian Aker
  • Date: 2010-01-27 18:58:12 UTC
  • Revision ID: brian@gaz-20100127185812-n62n0vwetnx8jrjy
Remove dead code.

Show diffs side-by-side

added added

removed removed

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