~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_sum.cc

  • Committer: Brian Aker
  • Date: 2008-10-29 13:46:43 UTC
  • Revision ID: brian@tangent.org-20081029134643-z6jcwjvyruhk2vlu
Updates for ignore file.

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