~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_sum.cc

  • Committer: Lee Bieber
  • Date: 2008-11-21 21:52:58 UTC
  • mto: (590.2.7 devel)
  • mto: This revision was merged to the branch mainline in revision 603.
  • Revision ID: lb4072@soe-t2000-8-20081121215258-s86ky54w5r676o4q
changes to get build working on Solaris

Show diffs side-by-side

added added

removed removed

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