~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_sum.cc

Renamed namespace slot to namespace service.

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
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
52
#include <drizzled/item/sum.h>
58
53
#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,
 
54
 
 
55
static bool find_key_for_maxmin(bool max_fl, table_reference_st *ref, Field* field,
 
56
                                COND *cond, uint32_t *range_fl,
72
57
                                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);
 
58
static int reckey_in_range(bool max_fl, table_reference_st *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);
82
61
 
83
62
 
84
63
/*
96
75
    UINT64_MAX  Error: Could not calculate number of rows
97
76
    #                   Multiplication of number of rows in all tables
98
77
*/
 
78
 
99
79
static uint64_t get_exact_record_count(TableList *tables)
100
80
{
101
81
  uint64_t count= 1;
102
82
  for (TableList *tl= tables; tl; tl= tl->next_leaf)
103
83
  {
104
 
    ha_rows tmp= tl->table->cursor->records();
 
84
    ha_rows tmp= tl->table->file->records();
105
85
    if ((tmp == HA_POS_ERROR))
106
 
    {
107
86
      return UINT64_MAX;
108
 
    }
109
87
    count*= tmp;
110
88
  }
111
89
  return count;
112
90
}
113
91
 
114
92
 
115
 
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)
116
115
{
117
 
  List<Item>::iterator it(all_fields.begin());
 
116
  List_iterator_fast<Item> it(all_fields);
118
117
  int const_result= 1;
119
 
  bool recalc_const_item= false;
 
118
  bool recalc_const_item= 0;
120
119
  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;
 
120
  bool is_exact_count= true, maybe_exact_count= true;
 
121
  table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
126
122
  table_map where_tables= 0;
127
 
  Item *item= NULL;
 
123
  Item *item;
128
124
  int error;
129
125
 
130
126
  if (conds)
131
 
  {
132
127
    where_tables= conds->used_tables();
133
 
  }
134
128
 
135
129
  /*
136
 
     Analyze outer join dependencies, and, if possible, compute the number
137
 
     of returned rows.
138
 
   */
 
130
    Analyze outer join dependencies, and, if possible, compute the number
 
131
    of returned rows.
 
132
  */
139
133
  for (TableList *tl= tables; tl; tl= tl->next_leaf)
140
134
  {
141
 
    TableList *embedded= NULL;
142
 
    for (embedded= tl; embedded; embedded= embedded->getEmbedding())
 
135
    TableList *embedded;
 
136
    for (embedded= tl ; embedded; embedded= embedded->embedding)
143
137
    {
144
138
      if (embedded->on_expr)
145
139
        break;
146
140
    }
147
141
    if (embedded)
148
 
      /* 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 */
149
143
    {
150
144
      outer_tables|= tl->table->map;
151
145
 
152
146
      /*
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
 
       */
 
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
      */
158
152
      if (tl->table->map & where_tables)
159
153
        return 0;
160
154
    }
161
155
    else
162
 
    {
163
156
      used_tables|= tl->table->map;
164
 
    }
165
157
 
166
158
    /*
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)))
 
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)
174
167
    {
175
 
      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));
176
171
      is_exact_count= false;
177
 
      count= 1; // ensure count != 0
 
172
      count= 1;                                 // ensure count != 0
178
173
    }
179
174
    else
180
175
    {
181
 
      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);
182
177
      if(error)
183
178
      {
184
 
        tl->table->print_error(error, MYF(ME_FATALERROR));
 
179
        tl->table->file->print_error(error, MYF(ME_FATALERROR));
185
180
        return error;
186
181
      }
187
 
      count*= tl->table->cursor->stats.records;
 
182
      count*= tl->table->file->stats.records;
188
183
    }
189
184
  }
190
185
 
191
186
  /*
192
 
     Iterate through all items in the SELECT clause and replace
193
 
     COUNT(), MIN() and MAX() with constants (if possible).
194
 
   */
 
187
    Iterate through all items in the SELECT clause and replace
 
188
    COUNT(), MIN() and MAX() with constants (if possible).
 
189
  */
195
190
 
196
191
  while ((item= it++))
197
192
  {
198
193
    if (item->type() == Item::SUM_FUNC_ITEM)
199
194
    {
200
195
      Item_sum *item_sum= (((Item_sum*) item));
201
 
      switch (item_sum->sum_func())
202
 
      {
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)
213
 
            {
214
 
              if ((count= get_exact_record_count(tables)) == UINT64_MAX)
215
 
              {
216
 
                /* Error from handler in counting rows. Don't optimize count() */
217
 
                const_result= 0;
218
 
                continue;
219
 
              }
220
 
              is_exact_count= 1;                  // count is now exact
221
 
            }
222
 
            ((Item_sum_count*) item)->make_const_count((int64_t) count);
223
 
            recalc_const_item= 1;
224
 
          }
225
 
          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:
517
 
          const_result= 0;
518
 
          break;
 
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_count((int64_t) count);
 
217
          recalc_const_item= 1;
 
218
        }
 
219
        else
 
220
          const_result= 0;
 
221
        break;
 
222
      case Item_sum::MIN_FUNC:
 
223
      {
 
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_reference_st 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((uint32_t) 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
 
285
            {
 
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)))
 
316
              {
 
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);
 
322
              }
 
323
            }
 
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_reference_st 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((uint32_t) ref.key, 1);
 
404
 
 
405
          if (!ref.key_length)
 
406
            error= table->file->index_last(table->record[0]);
 
407
          else
 
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
          */
 
443
          const_result= 0;
 
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;
519
460
      }
520
461
    }
521
462
    else if (const_result)
522
463
    {
523
464
      if (recalc_const_item)
524
 
      {
525
465
        item->update_used_tables();
526
 
      }
527
 
      if (! item->const_item())
528
 
      {
 
466
      if (!item->const_item())
529
467
        const_result= 0;
530
 
      }
531
468
    }
532
469
  }
533
470
  /*
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
 
   */
 
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
  */
540
477
  if (removed_tables && used_tables != removed_tables)
541
 
  {
542
478
    const_result= 0;                            // We didn't remove all tables
543
 
  }
544
479
  return const_result;
545
480
}
546
481
 
547
482
 
548
 
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)
549
499
{
550
 
  Item *item= NULL;
551
 
  inv_order= false;
552
 
  switch (func_item->argument_count())
553
 
  {
 
500
  Item *item;
 
501
  *inv_order= 0;
 
502
  switch (func_item->argument_count()) {
554
503
  case 0:
555
504
    /* MULT_EQUAL_FUNC */
556
505
    {
558
507
      Item_equal_iterator it(*item_equal);
559
508
      args[0]= it++;
560
509
      if (it++)
561
 
      {
562
 
        return 0;
563
 
      }
564
 
      if (! (args[1]= item_equal->get_const()))
565
 
      {
566
 
        return 0;
567
 
      }
 
510
        return 0;
 
511
      if (!(args[1]= item_equal->get_const()))
 
512
        return 0;
568
513
    }
569
514
    break;
570
515
  case 1:
571
516
    /* field IS NULL */
572
517
    item= func_item->arguments()[0];
573
518
    if (item->type() != Item::FIELD_ITEM)
574
 
    {
575
519
      return 0;
576
 
    }
577
520
    args[0]= item;
578
521
    break;
579
522
  case 2:
583
526
    {
584
527
      args[0]= item;
585
528
      item= func_item->arguments()[1];
586
 
      if (! item->const_item())
587
 
      {
 
529
      if (!item->const_item())
588
530
        return 0;
589
 
      }
590
531
      args[1]= item;
591
532
    }
592
533
    else if (item->const_item())
594
535
      args[1]= item;
595
536
      item= func_item->arguments()[1];
596
537
      if (item->type() != Item::FIELD_ITEM)
597
 
      {
598
538
        return 0;
599
 
      }
600
539
      args[0]= item;
601
 
      inv_order= true;
 
540
      *inv_order= 1;
602
541
    }
603
542
    else
604
 
    {
605
543
      return 0;
606
 
    }
607
544
    break;
608
545
  case 3:
609
546
    /* field BETWEEN const AND const */
614
551
      for (int i= 1 ; i <= 2; i++)
615
552
      {
616
553
        item= func_item->arguments()[i];
617
 
        if (! item->const_item())
618
 
        {
 
554
        if (!item->const_item())
619
555
          return 0;
620
 
        }
621
556
        args[i]= item;
622
557
      }
623
558
    }
624
559
    else
625
 
    {
626
560
      return 0;
627
 
    }
628
561
  }
629
562
  return 1;
630
563
}
659
592
  @retval
660
593
    1        We can use index to get MIN/MAX value
661
594
*/
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,
 
595
 
 
596
static bool matching_cond(bool max_fl, table_reference_st *ref, KEY *keyinfo,
 
597
                          KEY_PART_INFO *field_part, COND *cond,
 
598
                          key_part_map *key_part_used, uint32_t *range_fl,
669
599
                          uint32_t *prefix_len)
670
600
{
671
 
  if (! cond)
672
 
  {
 
601
  if (!cond)
673
602
    return 1;
674
 
  }
675
603
  Field *field= field_part->field;
676
604
 
677
605
  field->setWriteSet();
678
606
 
679
 
  if (! (cond->used_tables() & field->getTable()->map))
 
607
  if (!(cond->used_tables() & field->table->map))
680
608
  {
681
609
    /* Condition doesn't restrict the used table */
682
610
    return 1;
684
612
  if (cond->type() == Item::COND_ITEM)
685
613
  {
686
614
    if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
687
 
    {
688
615
      return 0;
689
 
    }
690
616
 
691
617
    /* AND */
692
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
618
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
693
619
    Item *item;
694
620
    while ((item= li++))
695
621
    {
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
 
      {
 
622
      if (!matching_cond(max_fl, ref, keyinfo, field_part, item,
 
623
                         key_part_used, range_fl, prefix_len))
705
624
        return 0;
706
 
      }
707
625
    }
708
626
    return 1;
709
627
  }
710
628
 
711
629
  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
 
  {
 
630
    return 0;                                 // Not operator, can't optimize
 
631
 
 
632
  bool eq_type= 0;                            // =, <=> or IS NULL
 
633
  bool noeq_type= 0;                          // < or >
 
634
  bool less_fl= 0;                            // < or <=
 
635
  bool is_null= 0;
 
636
  bool between= 0;
 
637
 
 
638
  switch (((Item_func*) cond)->functype()) {
724
639
  case Item_func::ISNULL_FUNC:
725
640
    is_null= 1;     /* fall through */
726
641
  case Item_func::EQ_FUNC:
743
658
    eq_type= 1;
744
659
    break;
745
660
  default:
746
 
    return 0; // Can't optimize function
 
661
    return 0;                                        // Can't optimize function
747
662
  }
748
663
 
749
664
  Item *args[3];
750
665
  bool inv;
751
666
 
752
667
  /* Test if this is a comparison of a field and constant */
753
 
  if (! optimizer::simple_pred((Item_func*) cond, args, inv))
754
 
  {
 
668
  if (!simple_pred((Item_func*) cond, args, &inv))
755
669
    return 0;
756
 
  }
757
670
 
758
 
  if (inv && ! eq_type)
759
 
  {
760
 
    less_fl= 1 - less_fl; // Convert '<' -> '>' (etc)
761
 
  }
 
671
  if (inv && !eq_type)
 
672
    less_fl= 1-less_fl;                         // Convert '<' -> '>' (etc)
762
673
 
763
674
  /* Check if field is part of the tested partial key */
764
675
  unsigned char *key_ptr= ref->key_buff;
765
 
  KeyPartInfo *part= NULL;
 
676
  KEY_PART_INFO *part;
766
677
  for (part= keyinfo->key_part; ; key_ptr+= part++->store_length)
767
678
 
768
679
  {
769
680
    if (part > field_part)
770
 
    {
771
681
      return 0;                     // Field is beyond the tested parts
772
 
    }
773
682
    if (part->field->eq(((Item_field*) args[0])->field))
774
 
    {
775
683
      break;                        // Found a part of the key for the field
776
 
    }
777
684
  }
778
685
 
779
686
  bool is_field_part= part == field_part;
780
 
  if (! (is_field_part || eq_type))
781
 
  {
 
687
  if (!(is_field_part || eq_type))
782
688
    return 0;
783
 
  }
784
689
 
785
690
  key_part_map org_key_part_used= *key_part_used;
786
691
  if (eq_type || between || max_fl == less_fl)
792
697
      ref->key_length= length;
793
698
      ref->key_parts= (part - keyinfo->key_part) + 1;
794
699
    }
795
 
    if (! *prefix_len && part + 1 == field_part)
796
 
    {
 
700
    if (!*prefix_len && part+1 == field_part)
797
701
      *prefix_len= length;
798
 
    }
799
702
    if (is_field_part && eq_type)
800
 
    {
801
703
      *prefix_len= ref->key_length;
802
 
    }
803
704
 
804
705
    *key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
805
706
  }
806
707
 
807
708
  if (org_key_part_used != *key_part_used ||
808
709
      (is_field_part &&
809
 
       (between || eq_type || max_fl == less_fl) && ! cond->val_int()))
 
710
       (between || eq_type || max_fl == less_fl) && !cond->val_int()))
810
711
  {
811
712
    /*
812
713
      It's the first predicate for this part or a predicate of the
827
728
      store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
828
729
                         CHECK_FIELD_IGNORE);
829
730
      if (part->null_bit)
830
 
      {
831
731
        *key_ptr++= (unsigned char) test(part->field->is_null());
832
 
      }
833
732
      part->field->get_key_image(key_ptr, part->length);
834
733
    }
835
734
    if (is_field_part)
836
735
    {
837
736
      if (between || eq_type)
838
 
      {
839
737
        *range_fl&= ~(NO_MAX_RANGE | NO_MIN_RANGE);
840
 
      }
841
738
      else
842
739
      {
843
740
        *range_fl&= ~(max_fl ? NO_MAX_RANGE : NO_MIN_RANGE);
844
741
        if (noeq_type)
845
 
        {
846
742
          *range_fl|=  (max_fl ? NEAR_MAX : NEAR_MIN);
847
 
        }
848
743
        else
849
 
        {
850
744
          *range_fl&= ~(max_fl ? NEAR_MAX : NEAR_MIN);
851
 
        }
852
745
      }
853
746
    }
854
747
  }
855
748
  else if (eq_type)
856
749
  {
857
 
    if ((! is_null && !cond->val_int()) ||
 
750
    if ((!is_null && !cond->val_int()) ||
858
751
        (is_null && !test(part->field->is_null())))
859
 
    {
860
752
     return 0;                       // Impossible test
861
 
    }
862
753
  }
863
754
  else if (is_field_part)
864
 
  {
865
755
    *range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
866
 
  }
867
756
  return 1;
868
757
}
869
758
 
909
798
    1   Can use key to optimize MIN()/MAX().
910
799
    In this case ref, range_fl and prefix_len are updated
911
800
*/
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)
 
801
 
 
802
 
 
803
static bool find_key_for_maxmin(bool max_fl, table_reference_st *ref,
 
804
                                Field* field, COND *cond,
 
805
                                uint32_t *range_fl, uint32_t *prefix_len)
918
806
{
919
 
  if (! (field->flags & PART_KEY_FLAG))
920
 
  {
921
 
    return 0; // Not key field
922
 
  }
 
807
  if (!(field->flags & PART_KEY_FLAG))
 
808
    return 0;                                        // Not key field
923
809
 
924
 
  Table *table= field->getTable();
 
810
  Table *table= field->table;
925
811
  uint32_t idx= 0;
926
812
 
927
 
  KeyInfo *keyinfo,*keyinfo_end= NULL;
928
 
  for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->getShare()->sizeKeys();
 
813
  KEY *keyinfo,*keyinfo_end;
 
814
  for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->s->keys ;
929
815
       keyinfo != keyinfo_end;
930
816
       keyinfo++,idx++)
931
817
  {
932
 
    KeyPartInfo *part= NULL;
933
 
    KeyPartInfo *part_end= NULL;
 
818
    KEY_PART_INFO *part,*part_end;
934
819
    key_part_map key_part_to_use= 0;
935
820
    /*
936
821
      Perform a check if index is not disabled by ALTER Table
937
822
      or IGNORE INDEX.
938
823
    */
939
 
    if (! table->keys_in_use_for_query.test(idx))
940
 
    {
 
824
    if (!table->keys_in_use_for_query.test(idx))
941
825
      continue;
942
 
    }
943
826
    uint32_t jdx= 0;
944
827
    *prefix_len= 0;
945
 
    for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts;
946
 
         part != part_end;
 
828
    for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts ;
 
829
         part != part_end ;
947
830
         part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1)
948
831
    {
949
 
      if (! (table->index_flags(idx) & HA_READ_ORDER))
950
 
      {
 
832
      if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
951
833
        return 0;
952
 
      }
953
834
 
954
835
      /* Check whether the index component is partial */
955
 
      Field *part_field= table->getField(part->fieldnr-1);
 
836
      Field *part_field= table->field[part->fieldnr-1];
956
837
      part_field->setWriteSet();
957
838
 
958
839
      if ((part_field->flags & BLOB_FLAG) ||
959
840
          part->length < part_field->key_length())
960
 
      {
961
841
        break;
962
 
      }
963
842
 
964
843
      if (field->eq(part->field))
965
844
      {
968
847
        ref->key_parts= 0;
969
848
        key_part_map key_part_used= 0;
970
849
        *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))
 
850
        if (matching_cond(max_fl, ref, keyinfo, part, cond,
 
851
                          &key_part_used, range_fl, prefix_len) &&
 
852
            !(key_part_to_use & ~key_part_used))
980
853
        {
981
 
          if (! max_fl && key_part_used == key_part_to_use && part->null_bit)
 
854
          if (!max_fl && key_part_used == key_part_to_use && part->null_bit)
982
855
          {
983
856
            /*
984
857
              The query is on this form:
1009
882
          if (field->part_of_key.test(idx))
1010
883
          {
1011
884
            table->key_read= 1;
1012
 
            table->cursor->extra(HA_EXTRA_KEYREAD);
 
885
            table->file->extra(HA_EXTRA_KEYREAD);
1013
886
          }
1014
887
          return 1;
1015
888
        }
1035
908
  @retval
1036
909
    1        WHERE was not true for the found row
1037
910
*/
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)
 
911
 
 
912
static int reckey_in_range(bool max_fl, table_reference_st *ref, Field* field,
 
913
                            COND *cond, uint32_t range_fl, uint32_t prefix_len)
1044
914
{
1045
 
  if (key_cmp_if_same(field->getTable(), ref->key_buff, ref->key, prefix_len))
1046
 
  {
 
915
  if (key_cmp_if_same(field->table, ref->key_buff, ref->key, prefix_len))
1047
916
    return 1;
1048
 
  }
1049
 
  if (! cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE)))
1050
 
  {
 
917
  if (!cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE)))
1051
918
    return 0;
1052
 
  }
1053
919
  return maxmin_in_range(max_fl, field, cond);
1054
920
}
1055
921
 
1066
932
  @retval
1067
933
    1        WHERE was not true for the found row
1068
934
*/
 
935
 
1069
936
static int maxmin_in_range(bool max_fl, Field* field, COND *cond)
1070
937
{
1071
938
  /* If AND/OR condition */
1072
939
  if (cond->type() == Item::COND_ITEM)
1073
940
  {
1074
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
941
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
1075
942
    Item *item;
1076
943
    while ((item= li++))
1077
944
    {
1078
945
      if (maxmin_in_range(max_fl, field, item))
1079
 
      {
1080
946
        return 1;
1081
 
      }
1082
947
    }
1083
948
    return 0;
1084
949
  }
1085
950
 
1086
 
  if (cond->used_tables() != field->getTable()->map)
1087
 
  {
 
951
  if (cond->used_tables() != field->table->map)
1088
952
    return 0;
1089
 
  }
1090
 
  bool less_fl= false;
1091
 
  switch (((Item_func*) cond)->functype())
1092
 
  {
 
953
  bool less_fl= 0;
 
954
  switch (((Item_func*) cond)->functype()) {
1093
955
  case Item_func::BETWEEN:
1094
956
    return cond->val_int() == 0;                // Return 1 if WHERE is false
1095
957
  case Item_func::LT_FUNC:
1100
962
  {
1101
963
    Item *item= ((Item_func*) cond)->arguments()[1];
1102
964
    /* In case of 'const op item' we have to swap the operator */
1103
 
    if (! item->const_item())
1104
 
    {
 
965
    if (!item->const_item())
1105
966
      less_fl= 1-less_fl;
1106
 
    }
1107
967
    /*
1108
968
      We only have to check the expression if we are using an expression like
1109
969
      SELECT MAX(b) FROM t1 WHERE a=const AND b>const
1111
971
      SELECT MAX(b) FROM t1 WHERE a=const AND b<const
1112
972
    */
1113
973
    if (max_fl != less_fl)
1114
 
    {
1115
974
      return cond->val_int() == 0;                // Return 1 if WHERE is false
1116
 
    }
1117
975
    return 0;
1118
976
  }
1119
977
  case Item_func::EQ_FUNC:
1126
984
  return 0;
1127
985
}
1128
986
 
1129
 
} /* namespace drizzled */
1130