~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.cc

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/**
21
21
  This file defines all compare functions
22
22
*/
23
23
 
24
 
#include <config.h>
25
 
 
26
 
#include <drizzled/cached_item.h>
27
 
#include <drizzled/check_stack_overrun.h>
28
 
#include <drizzled/current_session.h>
29
 
#include <drizzled/error.h>
30
 
#include <drizzled/internal/my_sys.h>
31
 
#include <drizzled/item/cache_int.h>
32
 
#include <drizzled/item/cmpfunc.h>
33
 
#include <drizzled/item/int_with_ref.h>
34
 
#include <drizzled/item/subselect.h>
35
 
#include <drizzled/session.h>
36
 
#include <drizzled/sql_select.h>
37
 
#include <drizzled/temporal.h>
38
 
#include <drizzled/time_functions.h>
39
 
 
40
 
#include <math.h>
41
 
#include <algorithm>
42
 
 
43
 
using namespace std;
44
 
 
45
 
namespace drizzled
46
 
{
47
 
 
48
 
extern const double log_10[309];
49
 
 
50
 
static Eq_creator eq_creator;
51
 
static Ne_creator ne_creator;
52
 
static Gt_creator gt_creator;
53
 
static Lt_creator lt_creator;
54
 
static Ge_creator ge_creator;
55
 
static Le_creator le_creator;
56
 
 
57
 
static bool convert_constant_item(Session *, Item_field *, Item **);
 
24
#ifdef USE_PRAGMA_IMPLEMENTATION
 
25
#pragma implementation                          // gcc: Class implementation
 
26
#endif
 
27
 
 
28
#include "mysql_priv.h"
 
29
#include "sql_select.h"
 
30
 
 
31
static bool convert_constant_item(THD *, Item_field *, Item **);
58
32
 
59
33
static Item_result item_store_type(Item_result a, Item *item,
60
 
                                   bool unsigned_flag)
 
34
                                   my_bool unsigned_flag)
61
35
{
62
36
  Item_result b= item->result_type();
63
37
 
72
46
    return INT_RESULT;
73
47
}
74
48
 
75
 
static void agg_result_type(Item_result *type, Item **items, uint32_t nitems)
 
49
static void agg_result_type(Item_result *type, Item **items, uint nitems)
76
50
{
77
51
  Item **item, **item_end;
78
 
  bool unsigned_flag= 0;
 
52
  my_bool unsigned_flag= 0;
79
53
 
80
54
  *type= STRING_RESULT;
81
55
  /* Skip beginning NULL items */
109
83
  DESCRIPTION
110
84
    The function checks that two expressions have compatible row signatures
111
85
    i.e. that the number of columns they return are the same and that if they
112
 
    are both row expressions then each component from the first expression has
 
86
    are both row expressions then each component from the first expression has 
113
87
    a row signature compatible with the signature of the corresponding component
114
88
    of the second expression.
115
89
 
120
94
 
121
95
static int cmp_row_type(Item* item1, Item* item2)
122
96
{
123
 
  uint32_t n= item1->cols();
 
97
  uint n= item1->cols();
124
98
  if (item2->check_cols(n))
125
99
    return 1;
126
 
  for (uint32_t i=0; i<n; i++)
 
100
  for (uint i=0; i<n; i++)
127
101
  {
128
102
    if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
129
103
        (item1->element_index(i)->result_type() == ROW_RESULT &&
157
131
    0  otherwise
158
132
*/
159
133
 
160
 
static int agg_cmp_type(Item_result *type, Item **items, uint32_t nitems)
 
134
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
161
135
{
162
 
  uint32_t i;
 
136
  uint i;
163
137
  type[0]= items[0]->result_type();
164
138
  for (i= 1 ; i < nitems ; i++)
165
139
  {
170
144
      of the first row expression has a compatible row signature with
171
145
      the signature of the corresponding component of the second row
172
146
      expression.
173
 
    */
 
147
    */ 
174
148
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
175
149
      return 1;     // error found: invalid usage of rows
176
150
  }
196
170
  @return aggregated field type.
197
171
*/
198
172
 
199
 
enum_field_types agg_field_type(Item **items, uint32_t nitems)
 
173
enum_field_types agg_field_type(Item **items, uint nitems)
200
174
{
201
 
  uint32_t i;
 
175
  uint i;
202
176
  if (!nitems || items[0]->result_type() == ROW_RESULT )
203
177
    return (enum_field_types)-1;
204
178
  enum_field_types res= items[0]->field_type();
214
188
    collect_cmp_types()
215
189
      items             Array of items to collect types from
216
190
      nitems            Number of items in the array
217
 
      skip_nulls        Don't collect types of NULL items if TRUE
218
191
 
219
192
  DESCRIPTION
220
193
    This function collects different result types for comparison of the first
225
198
    Bitmap of collected types - otherwise
226
199
*/
227
200
 
228
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
 
201
static uint collect_cmp_types(Item **items, uint nitems)
229
202
{
230
 
  uint32_t i;
231
 
  uint32_t found_types;
 
203
  uint i;
 
204
  uint found_types;
232
205
  Item_result left_result= items[0]->result_type();
233
206
  assert(nitems > 1);
234
207
  found_types= 0;
235
208
  for (i= 1; i < nitems ; i++)
236
209
  {
237
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
238
 
      continue; // Skip NULL constant items
239
 
    if ((left_result == ROW_RESULT ||
 
210
    if ((left_result == ROW_RESULT || 
240
211
         items[i]->result_type() == ROW_RESULT) &&
241
212
        cmp_row_type(items[0], items[i]))
242
213
      return 0;
243
 
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
 
214
    found_types|= 1<< (uint)item_cmp_type(left_result,
244
215
                                           items[i]->result_type());
245
216
  }
246
 
  /*
247
 
   Even if all right-hand items are NULLs and we are skipping them all, we need
248
 
   at least one type bit in the found_type bitmask.
249
 
  */
250
 
  if (skip_nulls && !found_types)
251
 
    found_types= 1 << (uint)left_result;
252
217
  return found_types;
253
218
}
254
219
 
 
220
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
 
221
                              const char *fname)
 
222
{
 
223
  my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
 
224
           c1.collation->name,c1.derivation_name(),
 
225
           c2.collation->name,c2.derivation_name(),
 
226
           fname);
 
227
}
 
228
 
255
229
 
256
230
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
257
231
{
259
233
}
260
234
 
261
235
 
262
 
const Eq_creator* Eq_creator::instance()
263
 
{
264
 
  return &eq_creator;
265
 
}
266
 
 
267
 
 
268
236
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
269
237
{
270
238
  return new Item_func_ne(a, b);
271
239
}
272
240
 
273
241
 
274
 
const Ne_creator* Ne_creator::instance()
275
 
{
276
 
  return &ne_creator;
277
 
}
278
 
 
279
 
 
280
242
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
281
243
{
282
244
  return new Item_func_gt(a, b);
283
245
}
284
246
 
285
247
 
286
 
const Gt_creator* Gt_creator::instance()
287
 
{
288
 
  return &gt_creator;
289
 
}
290
 
 
291
 
 
292
248
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
293
249
{
294
250
  return new Item_func_lt(a, b);
295
251
}
296
252
 
297
253
 
298
 
const Lt_creator* Lt_creator::instance()
299
 
{
300
 
  return &lt_creator;
301
 
}
302
 
 
303
 
 
304
254
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
305
255
{
306
256
  return new Item_func_ge(a, b);
307
257
}
308
258
 
309
259
 
310
 
const Ge_creator* Ge_creator::instance()
311
 
{
312
 
  return &ge_creator;
313
 
}
314
 
 
315
 
 
316
260
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
317
261
{
318
262
  return new Item_func_le(a, b);
319
263
}
320
264
 
321
 
const Le_creator* Le_creator::instance()
322
 
{
323
 
  return &le_creator;
324
 
}
325
 
 
326
 
 
327
265
/*
328
266
  Test functions
329
267
  Most of these  returns 0LL if false and 1LL if true and
427
365
    also when comparing bigint to strings (in which case strings
428
366
    are converted to bigints).
429
367
 
430
 
  @param  session             thread handle
 
368
  @param  thd             thread handle
431
369
  @param  field_item      item will be converted using the type of this field
432
370
  @param[in,out] item     reference to the item to convert
433
371
 
444
382
    1  Item was replaced with an integer version of the item
445
383
*/
446
384
 
447
 
static bool convert_constant_item(Session *session, Item_field *field_item,
 
385
static bool convert_constant_item(THD *thd, Item_field *field_item,
448
386
                                  Item **item)
449
387
{
450
388
  Field *field= field_item->field;
451
389
  int result= 0;
452
390
 
453
 
  field->setWriteSet();
454
 
 
455
391
  if (!(*item)->with_subselect && (*item)->const_item())
456
392
  {
457
 
    ulong orig_sql_mode= session->variables.sql_mode;
458
 
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
 
393
    TABLE *table= field->table;
 
394
    ulong orig_sql_mode= thd->variables.sql_mode;
 
395
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
 
396
    my_bitmap_map *old_write_map;
 
397
    my_bitmap_map *old_read_map;
459
398
    uint64_t orig_field_val= 0; /* original field value if valid */
460
399
 
 
400
    if (table)
 
401
    {
 
402
      old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
 
403
      old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
 
404
    }
461
405
    /* For comparison purposes allow invalid dates like 2000-01-32 */
462
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
 
406
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
463
407
                             MODE_INVALID_DATES;
464
 
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
408
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
465
409
 
466
410
    /*
467
411
      Store the value of the field if it references an outer field because
468
412
      the call to save_in_field below overrides that value.
469
413
    */
470
414
    if (field_item->depended_from)
471
 
    {
472
415
      orig_field_val= field->val_int();
473
 
    }
474
 
 
475
416
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
476
417
    {
477
418
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
478
419
                                       test(field->flags & UNSIGNED_FLAG));
479
420
      if (tmp)
480
 
        session->change_item_tree(item, tmp);
 
421
        thd->change_item_tree(item, tmp);
481
422
      result= 1;                                        // Item was replaced
482
423
    }
483
 
 
484
424
    /* Restore the original field value. */
485
425
    if (field_item->depended_from)
486
426
    {
487
 
      result= field->store(orig_field_val, field->isUnsigned());
 
427
      result= field->store(orig_field_val, true);
488
428
      /* orig_field_val must be a valid value that can be restored back. */
489
429
      assert(!result);
490
430
    }
491
 
    session->variables.sql_mode= orig_sql_mode;
492
 
    session->count_cuted_fields= orig_count_cuted_fields;
 
431
    thd->variables.sql_mode= orig_sql_mode;
 
432
    thd->count_cuted_fields= orig_count_cuted_fields;
 
433
    if (table)
 
434
    {
 
435
      dbug_tmp_restore_column_map(table->write_set, old_write_map);
 
436
      dbug_tmp_restore_column_map(table->read_set, old_read_map);
 
437
    }
493
438
  }
494
439
  return result;
495
440
}
498
443
void Item_bool_func2::fix_length_and_dec()
499
444
{
500
445
  max_length= 1;                                     // Function returns 0 or 1
 
446
  THD *thd;
501
447
 
502
448
  /*
503
449
    As some compare functions are generated after sql_yacc,
506
452
  if (!args[0] || !args[1])
507
453
    return;
508
454
 
509
 
  /*
 
455
  /* 
510
456
    We allow to convert to Unicode character sets in some cases.
511
457
    The conditions when conversion is possible are:
512
458
    - arguments A and B have different charsets
513
459
    - A wins according to coercibility rules
514
460
    - character set of A is superset for character set of B
515
 
 
 
461
   
516
462
    If all of the above is true, then it's possible to convert
517
463
    B into the character set of A, and then compare according
518
464
    to the collation of A.
519
465
  */
520
466
 
521
 
 
 
467
  
522
468
  DTCollation coll;
523
469
  if (args[0]->result_type() == STRING_RESULT &&
524
470
      args[1]->result_type() == STRING_RESULT &&
525
471
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
526
472
    return;
527
 
 
 
473
    
528
474
  args[0]->cmp_context= args[1]->cmp_context=
529
475
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
530
476
  // Make a special case of compare with fields to get nicer DATE comparisons
535
481
    return;
536
482
  }
537
483
 
538
 
  Item_field *field_item= NULL;
 
484
  thd= current_thd;
539
485
 
540
486
  if (args[0]->real_item()->type() == FIELD_ITEM)
541
487
  {
542
 
    field_item= static_cast<Item_field*>(args[0]->real_item());
 
488
    Item_field *field_item= (Item_field*) (args[0]->real_item());
543
489
    if (field_item->field->can_be_compared_as_int64_t() &&
544
490
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
545
491
    {
546
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
492
      if (convert_constant_item(thd, field_item, &args[1]))
547
493
      {
548
494
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
549
495
                         INT_RESULT);           // Works for all types.
554
500
 
555
501
    if (args[1]->real_item()->type() == FIELD_ITEM)
556
502
    {
557
 
      field_item= static_cast<Item_field*>(args[1]->real_item());
 
503
      Item_field *field_item= (Item_field*) (args[1]->real_item());
558
504
      if (field_item->field->can_be_compared_as_int64_t() &&
559
505
          !(field_item->is_datetime() &&
560
506
            args[0]->result_type() == STRING_RESULT))
561
507
      {
562
 
        if (convert_constant_item(&getSession(), field_item, &args[0]))
 
508
        if (convert_constant_item(thd, field_item, &args[0]))
563
509
        {
564
510
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
565
511
                           INT_RESULT); // Works for all types.
572
518
  set_cmp_func();
573
519
}
574
520
 
575
 
Arg_comparator::Arg_comparator():
576
 
  session(current_session),
577
 
  a_cache(0),
578
 
  b_cache(0)
579
 
{}
580
 
 
581
 
Arg_comparator::Arg_comparator(Item **a1, Item **a2):
582
 
  a(a1),
583
 
  b(a2),
584
 
  session(current_session),
585
 
  a_cache(0),
586
 
  b_cache(0)
587
 
{}
588
521
 
589
522
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
590
523
{
591
524
  owner= item;
592
525
  func= comparator_matrix[type]
593
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
594
 
 
 
526
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
595
527
  switch (type) {
596
528
  case ROW_RESULT:
597
 
    {
598
 
      uint32_t n= (*a)->cols();
599
 
      if (n != (*b)->cols())
600
 
      {
601
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
602
 
        comparators= 0;
603
 
        return 1;
604
 
      }
605
 
      if (!(comparators= new Arg_comparator[n]))
606
 
        return 1;
607
 
      for (uint32_t i=0; i < n; i++)
608
 
      {
609
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
610
 
        {
611
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
612
 
          return 1;
613
 
        }
614
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
615
 
      }
616
 
      break;
617
 
    }
618
 
 
 
529
  {
 
530
    uint n= (*a)->cols();
 
531
    if (n != (*b)->cols())
 
532
    {
 
533
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
534
      comparators= 0;
 
535
      return 1;
 
536
    }
 
537
    if (!(comparators= new Arg_comparator[n]))
 
538
      return 1;
 
539
    for (uint i=0; i < n; i++)
 
540
    {
 
541
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
542
      {
 
543
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
544
        return 1;
 
545
      }
 
546
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
547
    }
 
548
    break;
 
549
  }
619
550
  case STRING_RESULT:
 
551
  {
 
552
    /*
 
553
      We must set cmp_charset here as we may be called from for an automatic
 
554
      generated item, like in natural join
 
555
    */
 
556
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
557
        cmp_collation.derivation == DERIVATION_NONE)
 
558
    {
 
559
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
560
      return 1;
 
561
    }
 
562
    if (cmp_collation.collation == &my_charset_bin)
620
563
    {
621
564
      /*
622
 
        We must set cmp_charset here as we may be called from for an automatic
623
 
        generated item, like in natural join
 
565
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
566
        without removing end space
624
567
      */
625
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
626
 
          cmp_collation.derivation == DERIVATION_NONE)
627
 
      {
628
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
629
 
        return 1;
630
 
      }
631
 
      if (cmp_collation.collation == &my_charset_bin)
632
 
      {
633
 
        /*
634
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
635
 
          without removing end space
636
 
        */
637
 
        if (func == &Arg_comparator::compare_string)
638
 
          func= &Arg_comparator::compare_binary_string;
639
 
        else if (func == &Arg_comparator::compare_e_string)
640
 
          func= &Arg_comparator::compare_e_binary_string;
 
568
      if (func == &Arg_comparator::compare_string)
 
569
        func= &Arg_comparator::compare_binary_string;
 
570
      else if (func == &Arg_comparator::compare_e_string)
 
571
        func= &Arg_comparator::compare_e_binary_string;
641
572
 
642
 
        /*
643
 
          As this is binary compassion, mark all fields that they can't be
644
 
          transformed. Otherwise we would get into trouble with comparisons
645
 
like:
646
 
WHERE col= 'j' AND col LIKE BINARY 'j'
647
 
which would be transformed to:
648
 
WHERE col= 'j'
 
573
      /*
 
574
        As this is binary compassion, mark all fields that they can't be
 
575
        transformed. Otherwise we would get into trouble with comparisons
 
576
        like:
 
577
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
578
        which would be transformed to:
 
579
        WHERE col= 'j'
649
580
      */
650
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
651
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
652
 
      }
653
 
      break;
 
581
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
582
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
654
583
    }
 
584
    break;
 
585
  }
655
586
  case INT_RESULT:
656
 
    {
657
 
      if (func == &Arg_comparator::compare_int_signed)
658
 
      {
659
 
        if ((*a)->unsigned_flag)
660
 
          func= (((*b)->unsigned_flag)?
661
 
                 &Arg_comparator::compare_int_unsigned :
662
 
                 &Arg_comparator::compare_int_unsigned_signed);
663
 
        else if ((*b)->unsigned_flag)
664
 
          func= &Arg_comparator::compare_int_signed_unsigned;
665
 
      }
666
 
      else if (func== &Arg_comparator::compare_e_int)
667
 
      {
668
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
669
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
670
 
      }
671
 
      break;
672
 
    }
 
587
  {
 
588
    if (func == &Arg_comparator::compare_int_signed)
 
589
    {
 
590
      if ((*a)->unsigned_flag)
 
591
        func= (((*b)->unsigned_flag)?
 
592
               &Arg_comparator::compare_int_unsigned :
 
593
               &Arg_comparator::compare_int_unsigned_signed);
 
594
      else if ((*b)->unsigned_flag)
 
595
        func= &Arg_comparator::compare_int_signed_unsigned;
 
596
    }
 
597
    else if (func== &Arg_comparator::compare_e_int)
 
598
    {
 
599
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
600
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
601
    }
 
602
    break;
 
603
  }
673
604
  case DECIMAL_RESULT:
674
605
    break;
675
606
  case REAL_RESULT:
 
607
  {
 
608
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
676
609
    {
677
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
678
 
      {
679
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
680
 
        if (func == &Arg_comparator::compare_real)
681
 
          func= &Arg_comparator::compare_real_fixed;
682
 
        else if (func == &Arg_comparator::compare_e_real)
683
 
          func= &Arg_comparator::compare_e_real_fixed;
684
 
      }
685
 
      break;
 
610
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
 
611
      if (func == &Arg_comparator::compare_real)
 
612
        func= &Arg_comparator::compare_real_fixed;
 
613
      else if (func == &Arg_comparator::compare_e_real)
 
614
        func= &Arg_comparator::compare_e_real_fixed;
686
615
    }
687
 
  }
688
 
 
 
616
    break;
 
617
  }
 
618
  default:
 
619
    assert(0);
 
620
  }
689
621
  return 0;
690
622
}
691
623
 
693
625
/**
694
626
  @brief Convert date provided in a string to the int representation.
695
627
 
696
 
  @param[in]   session        thread handle
 
628
  @param[in]   thd        thread handle
697
629
  @param[in]   str        a string to convert
698
630
  @param[in]   warn_type  type of the timestamp for issuing the warning
699
631
  @param[in]   warn_name  field name for issuing the warning
712
644
    converted value. 0 on error and on zero-dates -- check 'failure'
713
645
*/
714
646
 
715
 
static int64_t
716
 
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
 
647
static uint64_t
 
648
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
717
649
                  char *warn_name, bool *error_arg)
718
650
{
719
 
  int64_t value= 0;
720
 
  type::cut_t error= type::VALID;
721
 
  type::Time l_time;
722
 
  type::timestamp_t ret;
723
 
 
724
 
  ret= l_time.store(str->ptr(), str->length(),
725
 
                    (TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
726
 
                    error);
727
 
 
728
 
  if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
 
651
  uint64_t value= 0;
 
652
  int error;
 
653
  DRIZZLE_TIME l_time;
 
654
  enum_drizzle_timestamp_type ret;
 
655
 
 
656
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
 
657
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
 
658
                        (thd->variables.sql_mode &
 
659
                         (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
 
660
                       &error);
 
661
 
 
662
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
729
663
  {
730
664
    /*
731
665
      Do not return yet, we may still want to throw a "trailing garbage"
732
666
      warning.
733
667
    */
734
668
    *error_arg= false;
735
 
    l_time.convert(value);
 
669
    value= TIME_to_uint64_t_datetime(&l_time);
736
670
  }
737
671
  else
738
672
  {
739
673
    *error_arg= true;
740
 
    error= type::CUT;                                   /* force warning */
 
674
    error= 1;                                   /* force warning */
741
675
  }
742
676
 
743
 
  if (error != type::VALID)
744
 
  {
745
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
677
  if (error > 0)
 
678
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
746
679
                                 str->ptr(), str->length(),
747
680
                                 warn_type, warn_name);
748
 
  }
749
681
 
750
682
  return value;
751
683
}
768
700
         int result and the other item (b or a) is an item with string result.
769
701
         If the second item is a constant one then it's checked to be
770
702
         convertible to the DATE/DATETIME type. If the constant can't be
771
 
         converted to a DATE/DATETIME then an error is issued back to the Session.
 
703
         converted to a DATE/DATETIME then the compare_datetime() comparator
 
704
         isn't used and the warning about wrong DATE/DATETIME value is issued.
772
705
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
773
706
      the comparison is handled by other comparators.
774
 
 
775
707
    If the datetime comparator can be used and one the operands of the
776
708
    comparison is a string constant that was successfully converted to a
777
709
    DATE/DATETIME type then the result of the conversion is returned in the
784
716
*/
785
717
 
786
718
enum Arg_comparator::enum_date_cmp_type
787
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
788
 
                                     int64_t *const_value)
 
719
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
789
720
{
790
721
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
791
722
  Item *str_arg= 0, *date_arg= 0;
792
723
 
793
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
724
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
794
725
    return CMP_DATE_DFLT;
795
726
 
796
 
  if (in_a->is_datetime())
 
727
  if (a->is_datetime())
797
728
  {
798
 
    if (in_b->is_datetime())
799
 
    {
 
729
    if (b->is_datetime())
800
730
      cmp_type= CMP_DATE_WITH_DATE;
801
 
    }
802
 
    else if (in_b->result_type() == STRING_RESULT)
 
731
    else if (b->result_type() == STRING_RESULT)
803
732
    {
804
733
      cmp_type= CMP_DATE_WITH_STR;
805
 
      date_arg= in_a;
806
 
      str_arg= in_b;
 
734
      date_arg= a;
 
735
      str_arg= b;
807
736
    }
808
737
  }
809
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
738
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
810
739
  {
811
740
    cmp_type= CMP_STR_WITH_DATE;
812
 
    date_arg= in_b;
813
 
    str_arg= in_a;
 
741
    date_arg= b;
 
742
    str_arg= a;
814
743
  }
815
744
 
816
745
  if (cmp_type != CMP_DATE_DFLT)
823
752
        (str_arg->type() != Item::FUNC_ITEM ||
824
753
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
825
754
    {
826
 
      /*
827
 
       * OK, we are here if we've got a date field (or something which can be 
828
 
       * compared as a date field) on one side of the equation, and a constant
829
 
       * string on the other side.  In this case, we must verify that the constant
830
 
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
831
 
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
832
 
       * produce an error, and no implicit conversion or truncation should take place.
833
 
       *
834
 
       * If the conversion to a DateTime temporal is successful, then we convert
835
 
       * the Temporal instance to a uint64_t for the comparison operator, which
836
 
       * compares date(times) using int64_t semantics.
837
 
       *
838
 
       * @TODO
839
 
       *
840
 
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
841
 
       * from val_int(), not uint64_t...
842
 
       */
843
 
      int64_t value;
844
 
      String *str_val;
845
 
      String tmp;
846
 
      /* DateTime used to pick up as many string conversion possibilities as possible. */
847
 
      DateTime temporal;
 
755
      THD *thd= current_thd;
 
756
      uint64_t value;
 
757
      bool error;
 
758
      String tmp, *str_val= 0;
 
759
      timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
 
760
                              DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
848
761
 
849
762
      str_val= str_arg->val_str(&tmp);
850
 
      if (! str_val)
851
 
      {
852
 
        /* 
853
 
         * If we are here, it is most likely due to the comparison item
854
 
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
855
 
         * be used, not = NULL since no item can be equal to NULL).
856
 
         *
857
 
         * So, return gracefully.
858
 
         */
859
 
        return CMP_DATE_DFLT;
860
 
      }
861
 
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
862
 
      {
863
 
        /* Chuck an error. Bad datetime input. */
864
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
865
 
        return CMP_DATE_DFLT; /* :( What else can I return... */
866
 
      }
867
 
 
868
 
      /* String conversion was good.  Convert to an integer for comparison purposes. */
869
 
      temporal.to_int64_t(&value);
870
 
 
 
763
      if (str_arg->null_value)
 
764
        return CMP_DATE_DFLT;
 
765
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
766
      if (error)
 
767
        return CMP_DATE_DFLT;
871
768
      if (const_value)
872
769
        *const_value= value;
873
770
    }
876
773
}
877
774
 
878
775
 
 
776
/*
 
777
  Retrieves correct TIME value from the given item.
 
778
 
 
779
  SYNOPSIS
 
780
    get_time_value()
 
781
    thd                 thread handle
 
782
    item_arg   [in/out] item to retrieve TIME value from
 
783
    cache_arg  [in/out] pointer to place to store the cache item to
 
784
    warn_item  [in]     unused
 
785
    is_null    [out]    true <=> the item_arg is null
 
786
 
 
787
  DESCRIPTION
 
788
    Retrieves the correct TIME value from given item for comparison by the
 
789
    compare_datetime() function.
 
790
    If item's result can be compared as int64_t then its int value is used
 
791
    and a value returned by get_time function is used otherwise.
 
792
    If an item is a constant one then its value is cached and it isn't
 
793
    get parsed again. An Item_cache_int object is used for for cached values.
 
794
    It seamlessly substitutes the original item.  The cache item is marked as
 
795
    non-constant to prevent re-caching it again.
 
796
 
 
797
  RETURN
 
798
    obtained value
 
799
*/
 
800
 
 
801
uint64_t
 
802
get_time_value(THD *thd __attribute__((unused)),
 
803
               Item ***item_arg, Item **cache_arg,
 
804
               Item *warn_item __attribute__((unused)),
 
805
               bool *is_null)
 
806
{
 
807
  uint64_t value;
 
808
  Item *item= **item_arg;
 
809
  DRIZZLE_TIME ltime;
 
810
 
 
811
  if (item->result_as_int64_t())
 
812
  {
 
813
    value= item->val_int();
 
814
    *is_null= item->null_value;
 
815
  }
 
816
  else
 
817
  {
 
818
    *is_null= item->get_time(&ltime);
 
819
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
 
820
  }
 
821
  /*
 
822
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
823
    for the current thread but it still may change during the execution.
 
824
  */
 
825
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
826
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
827
  {
 
828
    Item_cache_int *cache= new Item_cache_int();
 
829
    /* Mark the cache as non-const to prevent re-caching. */
 
830
    cache->set_used_tables(1);
 
831
    cache->store(item, value);
 
832
    *cache_arg= cache;
 
833
    *item_arg= cache_arg;
 
834
  }
 
835
  return value;
 
836
}
 
837
 
 
838
 
879
839
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
880
840
                                        Item **a1, Item **a2,
881
841
                                        Item_result type)
882
842
{
883
 
  enum_date_cmp_type cmp_type;
884
 
  int64_t const_value= -1;
 
843
  enum enum_date_cmp_type cmp_type;
 
844
  uint64_t const_value= (uint64_t)-1;
885
845
  a= a1;
886
846
  b= a2;
887
847
 
888
848
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
889
849
  {
 
850
    thd= current_thd;
890
851
    owner= owner_arg;
891
852
    a_type= (*a)->field_type();
892
853
    b_type= (*b)->field_type();
893
854
    a_cache= 0;
894
855
    b_cache= 0;
895
856
 
896
 
    if (const_value != -1)
 
857
    if (const_value != (uint64_t)-1)
897
858
    {
898
859
      Item_cache_int *cache= new Item_cache_int();
899
860
      /* Mark the cache as non-const to prevent re-caching. */
914
875
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
915
876
    func= &Arg_comparator::compare_datetime;
916
877
    get_value_func= &get_datetime_value;
917
 
 
 
878
    return 0;
 
879
  }
 
880
  else if (type == STRING_RESULT && (*a)->field_type() == DRIZZLE_TYPE_TIME &&
 
881
           (*b)->field_type() == DRIZZLE_TYPE_TIME)
 
882
  {
 
883
    /* Compare TIME values as integers. */
 
884
    thd= current_thd;
 
885
    owner= owner_arg;
 
886
    a_cache= 0;
 
887
    b_cache= 0;
 
888
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
 
889
    func= &Arg_comparator::compare_datetime;
 
890
    get_value_func= &get_time_value;
918
891
    return 0;
919
892
  }
920
893
 
924
897
 
925
898
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
926
899
{
 
900
  thd= current_thd;
927
901
  /* A caller will handle null values by itself. */
928
902
  owner= NULL;
929
903
  a= a1;
943
917
 
944
918
  SYNOPSIS
945
919
    get_datetime_value()
946
 
    session                 thread handle
 
920
    thd                 thread handle
947
921
    item_arg   [in/out] item to retrieve DATETIME value from
948
922
    cache_arg  [in/out] pointer to place to store the caching item to
949
923
    warn_item  [in]     item for issuing the conversion warning
967
941
    obtained value
968
942
*/
969
943
 
970
 
int64_t
971
 
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
 
944
uint64_t
 
945
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
972
946
                   Item *warn_item, bool *is_null)
973
947
{
974
 
  int64_t value= 0;
 
948
  uint64_t value= 0;
975
949
  String buf, *str= 0;
976
950
  Item *item= **item_arg;
977
951
 
986
960
      compare it with 100000000L - any DATE value should be less than it.
987
961
      Don't shift cached DATETIME values up for the second time.
988
962
    */
989
 
    if (f_type == DRIZZLE_TYPE_DATE ||
 
963
    if (f_type == DRIZZLE_TYPE_NEWDATE ||
990
964
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
991
965
      value*= 1000000L;
992
966
  }
995
969
    str= item->val_str(&buf);
996
970
    *is_null= item->null_value;
997
971
  }
998
 
 
999
972
  if (*is_null)
1000
973
    return ~(uint64_t) 0;
1001
 
 
1002
974
  /*
1003
975
    Convert strings to the integer DATE/DATETIME representation.
1004
976
    Even if both dates provided in strings we can't compare them directly as
1009
981
  {
1010
982
    bool error;
1011
983
    enum_field_types f_type= warn_item->field_type();
1012
 
    type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
1013
 
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
 
984
    timestamp_type t_type= f_type ==
 
985
      DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
 
986
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
1014
987
    /*
1015
988
      If str did not contain a valid date according to the current
1016
989
      SQL_MODE, get_date_from_str() has already thrown a warning,
1032
1005
    *cache_arg= cache;
1033
1006
    *item_arg= cache_arg;
1034
1007
  }
1035
 
 
1036
1008
  return value;
1037
1009
}
1038
1010
 
1063
1035
  uint64_t a_value, b_value;
1064
1036
 
1065
1037
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1066
 
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
 
1038
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
1067
1039
  if (!is_nulls_eq && is_null)
1068
1040
  {
1069
1041
    if (owner)
1072
1044
  }
1073
1045
 
1074
1046
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1075
 
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
 
1047
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
1076
1048
  if (is_null)
1077
1049
  {
1078
1050
    if (owner)
1086
1058
  /* Compare values. */
1087
1059
  if (is_nulls_eq)
1088
1060
    return (a_value == b_value);
1089
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1061
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1090
1062
}
1091
1063
 
1092
1064
 
1125
1097
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
1126
1098
    {
1127
1099
      owner->null_value= 0;
1128
 
      uint32_t res1_length= res1->length();
1129
 
      uint32_t res2_length= res2->length();
 
1100
      uint res1_length= res1->length();
 
1101
      uint res2_length= res2->length();
1130
1102
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1131
1103
      return cmp ? cmp : (int) (res1_length - res2_length);
1132
1104
    }
1189
1161
 
1190
1162
int Arg_comparator::compare_decimal()
1191
1163
{
1192
 
  type::Decimal value1;
1193
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
 
1164
  my_decimal value1;
 
1165
  my_decimal *val1= (*a)->val_decimal(&value1);
1194
1166
  if (!(*a)->null_value)
1195
1167
  {
1196
 
    type::Decimal value2;
1197
 
    type::Decimal *val2= (*b)->val_decimal(&value2);
 
1168
    my_decimal value2;
 
1169
    my_decimal *val2= (*b)->val_decimal(&value2);
1198
1170
    if (!(*b)->null_value)
1199
1171
    {
1200
1172
      owner->null_value= 0;
1201
 
      return class_decimal_cmp(val1, val2);
 
1173
      return my_decimal_cmp(val1, val2);
1202
1174
    }
1203
1175
  }
1204
1176
  owner->null_value= 1;
1216
1188
 
1217
1189
int Arg_comparator::compare_e_decimal()
1218
1190
{
1219
 
  type::Decimal value1, value2;
1220
 
  type::Decimal *val1= (*a)->val_decimal(&value1);
1221
 
  type::Decimal *val2= (*b)->val_decimal(&value2);
 
1191
  my_decimal value1, value2;
 
1192
  my_decimal *val1= (*a)->val_decimal(&value1);
 
1193
  my_decimal *val2= (*b)->val_decimal(&value2);
1222
1194
  if ((*a)->null_value || (*b)->null_value)
1223
1195
    return test((*a)->null_value && (*b)->null_value);
1224
 
  return test(class_decimal_cmp(val1, val2) == 0);
 
1196
  return test(my_decimal_cmp(val1, val2) == 0);
1225
1197
}
1226
1198
 
1227
1199
 
1383
1355
  bool was_null= 0;
1384
1356
  (*a)->bring_value();
1385
1357
  (*b)->bring_value();
1386
 
  uint32_t n= (*a)->cols();
1387
 
  for (uint32_t i= 0; i<n; i++)
 
1358
  uint n= (*a)->cols();
 
1359
  for (uint i= 0; i<n; i++)
1388
1360
  {
1389
1361
    res= comparators[i].compare();
1390
1362
    if (owner->null_value)
1426
1398
{
1427
1399
  (*a)->bring_value();
1428
1400
  (*b)->bring_value();
1429
 
  uint32_t n= (*a)->cols();
1430
 
  for (uint32_t i= 0; i<n; i++)
 
1401
  uint n= (*a)->cols();
 
1402
  for (uint i= 0; i<n; i++)
1431
1403
  {
1432
1404
    if (!comparators[i].compare())
1433
1405
      return 0;
1489
1461
}
1490
1462
 
1491
1463
 
1492
 
bool Item_in_optimizer::fix_left(Session *session, Item **)
 
1464
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
1493
1465
{
1494
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1466
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1495
1467
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1496
1468
    return 1;
1497
1469
 
1505
1477
  }
1506
1478
  else
1507
1479
  {
1508
 
    uint32_t n= cache->cols();
1509
 
    for (uint32_t i= 0; i < n; i++)
 
1480
    uint n= cache->cols();
 
1481
    for (uint i= 0; i < n; i++)
1510
1482
    {
1511
1483
      if (args[0]->element_index(i)->used_tables())
1512
1484
        ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1523
1495
}
1524
1496
 
1525
1497
 
1526
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1498
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1527
1499
{
1528
1500
  assert(fixed == 0);
1529
 
  if (fix_left(session, ref))
 
1501
  if (fix_left(thd, ref))
1530
1502
    return true;
1531
1503
  if (args[0]->maybe_null)
1532
1504
    maybe_null=1;
1533
1505
 
1534
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1506
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1535
1507
    return true;
1536
1508
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1537
1509
  if (args[0]->cols() != sub->engine->cols())
1555
1527
  bool tmp;
1556
1528
  assert(fixed == 1);
1557
1529
  cache->store(args[0]);
1558
 
 
 
1530
  
1559
1531
  if (cache->null_value)
1560
1532
  {
1561
1533
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1583
1555
          We disable the predicates we've pushed down into subselect, run the
1584
1556
          subselect and see if it has produced any rows.
1585
1557
        */
1586
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
 
1558
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1587
1559
        if (cache->cols() == 1)
1588
1560
        {
1589
1561
          item_subs->set_cond_guard_var(0, false);
1593
1565
        }
1594
1566
        else
1595
1567
        {
1596
 
          uint32_t i;
1597
 
          uint32_t ncols= cache->cols();
 
1568
          uint i;
 
1569
          uint ncols= cache->cols();
1598
1570
          /*
1599
1571
            Turn off the predicates that are based on column compares for
1600
1572
            which the left part is currently NULL
1604
1576
            if (cache->element_index(i)->null_value)
1605
1577
              item_subs->set_cond_guard_var(i, false);
1606
1578
          }
1607
 
 
 
1579
          
1608
1580
          (void) args[1]->val_bool_result();
1609
1581
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1610
 
 
 
1582
          
1611
1583
          /* Turn all predicates back on */
1612
1584
          for (i= 0; i < ncols; i++)
1613
1585
            item_subs->set_cond_guard_var(i, true);
1631
1603
 
1632
1604
void Item_in_optimizer::cleanup()
1633
1605
{
1634
 
  item::function::Boolean::cleanup();
 
1606
  Item_bool_func::cleanup();
1635
1607
  if (!save_cache)
1636
1608
    cache= 0;
1637
1609
  return;
1667
1639
    @retval NULL if an error occurred
1668
1640
*/
1669
1641
 
1670
 
Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
 
1642
Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
1671
1643
{
1672
1644
  Item *new_item;
1673
1645
 
1678
1650
  if (!new_item)
1679
1651
    return 0;
1680
1652
  /*
1681
 
    Session::change_item_tree() should be called only if the tree was
 
1653
    THD::change_item_tree() should be called only if the tree was
1682
1654
    really transformed, i.e. when a new item has been created.
1683
1655
    Otherwise we'll be allocating a lot of unnecessary memory for
1684
1656
    change records at each execution.
1685
1657
  */
1686
1658
  if ((*args) != new_item)
1687
 
    getSession().change_item_tree(args, new_item);
 
1659
    current_thd->change_item_tree(args, new_item);
1688
1660
 
1689
1661
  /*
1690
1662
    Transform the right IN operand which should be an Item_in_subselect or a
1799
1771
    return 0;
1800
1772
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
1801
1773
    return 0;
1802
 
  for (uint32_t i=0; i < arg_count ; i++)
 
1774
  for (uint i=0; i < arg_count ; i++)
1803
1775
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
1804
1776
      return 0;
1805
1777
  return 1;
1808
1780
 
1809
1781
void Item_func_interval::fix_length_and_dec()
1810
1782
{
1811
 
  uint32_t rows= row->cols();
1812
 
 
 
1783
  uint rows= row->cols();
 
1784
  
1813
1785
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1814
1786
                            DECIMAL_RESULT) ||
1815
1787
                           (row->element_index(0)->result_type() ==
1818
1790
  {
1819
1791
    bool not_null_consts= true;
1820
1792
 
1821
 
    for (uint32_t i= 1; not_null_consts && i < rows; i++)
 
1793
    for (uint i= 1; not_null_consts && i < rows; i++)
1822
1794
    {
1823
1795
      Item *el= row->element_index(i);
1824
1796
      not_null_consts&= el->const_item() & !el->is_null();
1826
1798
 
1827
1799
    if (not_null_consts &&
1828
1800
        (intervals=
1829
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1801
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1830
1802
    {
1831
1803
      if (use_decimal_comparison)
1832
1804
      {
1833
 
        for (uint32_t i= 1; i < rows; i++)
 
1805
        for (uint i= 1; i < rows; i++)
1834
1806
        {
1835
1807
          Item *el= row->element_index(i);
1836
1808
          interval_range *range= intervals + (i-1);
1839
1811
          {
1840
1812
            range->type= DECIMAL_RESULT;
1841
1813
            range->dec.init();
1842
 
            type::Decimal *dec= el->val_decimal(&range->dec);
 
1814
            my_decimal *dec= el->val_decimal(&range->dec);
1843
1815
            if (dec != &range->dec)
1844
1816
            {
1845
1817
              range->dec= *dec;
1855
1827
      }
1856
1828
      else
1857
1829
      {
1858
 
        for (uint32_t i= 1; i < rows; i++)
 
1830
        for (uint i= 1; i < rows; i++)
1859
1831
        {
1860
1832
          intervals[i-1].dbl= row->element_index(i)->val_real();
1861
1833
        }
1889
1861
{
1890
1862
  assert(fixed == 1);
1891
1863
  double value;
1892
 
  type::Decimal dec_buf, *dec= NULL;
1893
 
  uint32_t i;
 
1864
  my_decimal dec_buf, *dec= NULL;
 
1865
  uint i;
1894
1866
 
1895
1867
  if (use_decimal_comparison)
1896
1868
  {
1897
1869
    dec= row->element_index(0)->val_decimal(&dec_buf);
1898
1870
    if (row->element_index(0)->null_value)
1899
1871
      return -1;
1900
 
    class_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
 
1872
    my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1901
1873
  }
1902
1874
  else
1903
1875
  {
1908
1880
 
1909
1881
  if (intervals)
1910
1882
  {                                     // Use binary search to find interval
1911
 
    uint32_t start,end;
 
1883
    uint start,end;
1912
1884
    start= 0;
1913
1885
    end=   row->cols()-2;
1914
1886
    while (start != end)
1915
1887
    {
1916
 
      uint32_t mid= (start + end + 1) / 2;
 
1888
      uint mid= (start + end + 1) / 2;
1917
1889
      interval_range *range= intervals + mid;
1918
 
      bool cmp_result;
 
1890
      my_bool cmp_result;
1919
1891
      /*
1920
1892
        The values in the range intervall may have different types,
1921
1893
        Only do a decimal comparision of the first argument is a decimal
1922
1894
        and we are comparing against a decimal
1923
1895
      */
1924
1896
      if (dec && range->type == DECIMAL_RESULT)
1925
 
        cmp_result= class_decimal_cmp(&range->dec, dec) <= 0;
 
1897
        cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
1926
1898
      else
1927
1899
        cmp_result= (range->dbl <= value);
1928
1900
      if (cmp_result)
1932
1904
    }
1933
1905
    interval_range *range= intervals+start;
1934
1906
    return ((dec && range->type == DECIMAL_RESULT) ?
1935
 
            class_decimal_cmp(dec, &range->dec) < 0 :
 
1907
            my_decimal_cmp(dec, &range->dec) < 0 :
1936
1908
            value < range->dbl) ? 0 : start + 1;
1937
1909
  }
1938
1910
 
1943
1915
        ((el->result_type() == DECIMAL_RESULT) ||
1944
1916
         (el->result_type() == INT_RESULT)))
1945
1917
    {
1946
 
      type::Decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
 
1918
      my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
1947
1919
      /* Skip NULL ranges. */
1948
1920
      if (el->null_value)
1949
1921
        continue;
1950
 
      if (class_decimal_cmp(e_dec, dec) > 0)
 
1922
      if (my_decimal_cmp(e_dec, dec) > 0)
1951
1923
        return i - 1;
1952
1924
    }
1953
 
    else
 
1925
    else 
1954
1926
    {
1955
1927
      double val= el->val_real();
1956
1928
      /* Skip NULL ranges. */
1972
1944
    The function saves in ref the pointer to the item or to a newly created
1973
1945
    item that is considered as a replacement for the original one.
1974
1946
 
1975
 
  @param session     reference to the global context of the query thread
 
1947
  @param thd     reference to the global context of the query thread
1976
1948
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1977
1949
                 item is to be assigned
1978
1950
 
1992
1964
    1   got error
1993
1965
*/
1994
1966
 
1995
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1967
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1996
1968
{
1997
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1969
  if (Item_func_opt_neg::fix_fields(thd, ref))
1998
1970
    return 1;
1999
1971
 
2000
 
  session->getLex()->current_select->between_count++;
 
1972
  thd->lex->current_select->between_count++;
2001
1973
 
2002
1974
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
2003
1975
  if (pred_level && !negated)
2017
1989
  max_length= 1;
2018
1990
  int i;
2019
1991
  bool datetime_found= false;
 
1992
  int time_items_found= 0;
2020
1993
  compare_as_dates= true;
 
1994
  THD *thd= current_thd;
2021
1995
 
2022
1996
  /*
2023
1997
    As some compare functions are generated after sql_yacc,
2045
2019
        datetime_found= true;
2046
2020
        continue;
2047
2021
      }
 
2022
      if (args[i]->field_type() == DRIZZLE_TYPE_TIME &&
 
2023
          args[i]->result_as_int64_t())
 
2024
        time_items_found++;
2048
2025
    }
2049
2026
  }
2050
2027
  if (!datetime_found)
2055
2032
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2056
2033
    le_cmp.set_datetime_cmp_func(args, args + 2);
2057
2034
  }
2058
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2035
  else if (time_items_found == 3)
 
2036
  {
 
2037
    /* Compare TIME items as integers. */
 
2038
    cmp_type= INT_RESULT;
 
2039
  }
 
2040
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2041
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2059
2042
  {
2060
2043
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2061
2044
    if (field_item->field->can_be_compared_as_int64_t())
2064
2047
        The following can't be recoded with || as convert_constant_item
2065
2048
        changes the argument
2066
2049
      */
2067
 
      if (convert_constant_item(&getSession(), field_item, &args[1]))
 
2050
      if (convert_constant_item(thd, field_item, &args[1]))
2068
2051
        cmp_type=INT_RESULT;                    // Works for all types.
2069
 
      if (convert_constant_item(&getSession(), field_item, &args[2]))
 
2052
      if (convert_constant_item(thd, field_item, &args[2]))
2070
2053
        cmp_type=INT_RESULT;                    // Works for all types.
2071
2054
    }
2072
2055
  }
2125
2108
  {
2126
2109
    int64_t value=args[0]->val_int(), a, b;
2127
2110
    if ((null_value=args[0]->null_value))
2128
 
      return 0;
 
2111
      return 0;                                 /* purecov: inspected */
2129
2112
    a=args[1]->val_int();
2130
2113
    b=args[2]->val_int();
2131
2114
    if (!args[1]->null_value && !args[2]->null_value)
2143
2126
  }
2144
2127
  else if (cmp_type == DECIMAL_RESULT)
2145
2128
  {
2146
 
    type::Decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
 
2129
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2147
2130
               a_buf, *a_dec, b_buf, *b_dec;
2148
2131
    if ((null_value=args[0]->null_value))
2149
 
      return 0;
 
2132
      return 0;                                 /* purecov: inspected */
2150
2133
    a_dec= args[1]->val_decimal(&a_buf);
2151
2134
    b_dec= args[2]->val_decimal(&b_buf);
2152
2135
    if (!args[1]->null_value && !args[2]->null_value)
2153
 
      return (int64_t) ((class_decimal_cmp(dec, a_dec) >= 0 &&
2154
 
                          class_decimal_cmp(dec, b_dec) <= 0) != negated);
 
2136
      return (int64_t) ((my_decimal_cmp(dec, a_dec) >= 0 &&
 
2137
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
2155
2138
    if (args[1]->null_value && args[2]->null_value)
2156
2139
      null_value=1;
2157
2140
    else if (args[1]->null_value)
2158
 
      null_value= (class_decimal_cmp(dec, b_dec) <= 0);
 
2141
      null_value= (my_decimal_cmp(dec, b_dec) <= 0);
2159
2142
    else
2160
 
      null_value= (class_decimal_cmp(dec, a_dec) >= 0);
 
2143
      null_value= (my_decimal_cmp(dec, a_dec) >= 0);
2161
2144
  }
2162
2145
  else
2163
2146
  {
2164
2147
    double value= args[0]->val_real(),a,b;
2165
2148
    if ((null_value=args[0]->null_value))
2166
 
      return 0;
 
2149
      return 0;                                 /* purecov: inspected */
2167
2150
    a= args[1]->val_real();
2168
2151
    b= args[2]->val_real();
2169
2152
    if (!args[1]->null_value && !args[2]->null_value)
2200
2183
Item_func_ifnull::fix_length_and_dec()
2201
2184
{
2202
2185
  agg_result_type(&hybrid_type, args, 2);
2203
 
  maybe_null= args[1]->maybe_null;
 
2186
  maybe_null=args[1]->maybe_null;
2204
2187
  decimals= max(args[0]->decimals, args[1]->decimals);
2205
2188
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2206
2189
 
2207
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
 
2190
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2208
2191
  {
2209
2192
    int len0= args[0]->max_length - args[0]->decimals
2210
2193
      - (args[0]->unsigned_flag ? 0 : 1);
2215
2198
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2216
2199
  }
2217
2200
  else
2218
 
  {
2219
2201
    max_length= max(args[0]->max_length, args[1]->max_length);
2220
 
  }
2221
2202
 
2222
 
  switch (hybrid_type)
2223
 
  {
 
2203
  switch (hybrid_type) {
2224
2204
  case STRING_RESULT:
2225
2205
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2226
2206
    break;
2227
 
 
2228
2207
  case DECIMAL_RESULT:
2229
2208
  case REAL_RESULT:
2230
2209
    break;
2231
 
 
2232
2210
  case INT_RESULT:
2233
2211
    decimals= 0;
2234
2212
    break;
2235
 
 
2236
2213
  case ROW_RESULT:
 
2214
  default:
2237
2215
    assert(0);
2238
2216
  }
2239
 
 
2240
2217
  cached_field_type= agg_field_type(args, 2);
2241
2218
}
2242
2219
 
2243
2220
 
2244
 
uint32_t Item_func_ifnull::decimal_precision() const
 
2221
uint Item_func_ifnull::decimal_precision() const
2245
2222
{
2246
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2223
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2247
2224
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2248
2225
}
2249
2226
 
2250
2227
 
2251
 
enum_field_types Item_func_ifnull::field_type() const
 
2228
enum_field_types Item_func_ifnull::field_type() const 
2252
2229
{
2253
2230
  return cached_field_type;
2254
2231
}
2255
2232
 
2256
 
Field *Item_func_ifnull::tmp_table_field(Table *table)
 
2233
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2257
2234
{
2258
2235
  return tmp_table_field_from_field_type(table, 0);
2259
2236
}
2291
2268
}
2292
2269
 
2293
2270
 
2294
 
type::Decimal *Item_func_ifnull::decimal_op(type::Decimal *decimal_value)
 
2271
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
2295
2272
{
2296
2273
  assert(fixed == 1);
2297
 
  type::Decimal *value= args[0]->val_decimal(decimal_value);
 
2274
  my_decimal *value= args[0]->val_decimal(decimal_value);
2298
2275
  if (!args[0]->null_value)
2299
2276
  {
2300
2277
    null_value= 0;
2334
2311
    The function saves in ref the pointer to the item or to a newly created
2335
2312
    item that is considered as a replacement for the original one.
2336
2313
 
2337
 
  @param session     reference to the global context of the query thread
 
2314
  @param thd     reference to the global context of the query thread
2338
2315
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2339
2316
                 item is to be assigned
2340
2317
 
2353
2330
*/
2354
2331
 
2355
2332
bool
2356
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2333
Item_func_if::fix_fields(THD *thd, Item **ref)
2357
2334
{
2358
2335
  assert(fixed == 0);
2359
2336
  args[0]->top_level_item();
2360
2337
 
2361
 
  if (Item_func::fix_fields(session, ref))
 
2338
  if (Item_func::fix_fields(thd, ref))
2362
2339
    return 1;
2363
2340
 
2364
2341
  not_null_tables_cache= (args[1]->not_null_tables() &
2371
2348
void
2372
2349
Item_func_if::fix_length_and_dec()
2373
2350
{
2374
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
 
2351
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2375
2352
  decimals= max(args[1]->decimals, args[2]->decimals);
2376
 
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2353
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2377
2354
 
2378
 
  enum Item_result arg1_type= args[1]->result_type();
2379
 
  enum Item_result arg2_type= args[2]->result_type();
2380
 
  bool null1= args[1]->const_item() && args[1]->null_value;
2381
 
  bool null2= args[2]->const_item() && args[2]->null_value;
 
2355
  enum Item_result arg1_type=args[1]->result_type();
 
2356
  enum Item_result arg2_type=args[2]->result_type();
 
2357
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2358
  bool null2=args[2]->const_item() && args[2]->null_value;
2382
2359
 
2383
2360
  if (null1)
2384
2361
  {
2416
2393
    int len2= args[2]->max_length - args[2]->decimals
2417
2394
      - (args[2]->unsigned_flag ? 0 : 1);
2418
2395
 
2419
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2396
    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2420
2397
  }
2421
2398
  else
2422
2399
    max_length= max(args[1]->max_length, args[2]->max_length);
2423
2400
}
2424
2401
 
2425
2402
 
2426
 
uint32_t Item_func_if::decimal_precision() const
 
2403
uint Item_func_if::decimal_precision() const
2427
2404
{
2428
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2429
 
                  decimals);
 
2405
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2406
                 decimals);
2430
2407
  return min(precision, DECIMAL_MAX_PRECISION);
2431
2408
}
2432
2409
 
2464
2441
}
2465
2442
 
2466
2443
 
2467
 
type::Decimal *
2468
 
Item_func_if::val_decimal(type::Decimal *decimal_value)
 
2444
my_decimal *
 
2445
Item_func_if::val_decimal(my_decimal *decimal_value)
2469
2446
{
2470
2447
  assert(fixed == 1);
2471
2448
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2472
 
  type::Decimal *value= arg->val_decimal(decimal_value);
 
2449
  my_decimal *value= arg->val_decimal(decimal_value);
2473
2450
  null_value= arg->null_value;
2474
2451
  return value;
2475
2452
}
2549
2526
}
2550
2527
 
2551
2528
 
2552
 
type::Decimal *
2553
 
Item_func_nullif::val_decimal(type::Decimal * decimal_value)
 
2529
my_decimal *
 
2530
Item_func_nullif::val_decimal(my_decimal * decimal_value)
2554
2531
{
2555
2532
  assert(fixed == 1);
2556
 
  type::Decimal *res;
 
2533
  my_decimal *res;
2557
2534
  if (!cmp.compare())
2558
2535
  {
2559
2536
    null_value=1;
2568
2545
bool
2569
2546
Item_func_nullif::is_null()
2570
2547
{
2571
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
 
2548
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2572
2549
}
2573
2550
 
2574
2551
 
2593
2570
           failed
2594
2571
*/
2595
2572
 
2596
 
Item *Item_func_case::find_item(String *)
 
2573
Item *Item_func_case::find_item(String *str __attribute__((unused)))
2597
2574
{
2598
 
  uint32_t value_added_map= 0;
 
2575
  uint value_added_map= 0;
2599
2576
 
2600
2577
  if (first_expr_num == -1)
2601
2578
  {
2602
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2579
    for (uint i=0 ; i < ncases ; i+=2)
2603
2580
    {
2604
2581
      // No expression between CASE and the first WHEN
2605
2582
      if (args[i]->val_bool())
2610
2587
  else
2611
2588
  {
2612
2589
    /* Compare every WHEN argument with it and return the first match */
2613
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2590
    for (uint i=0 ; i < ncases ; i+=2)
2614
2591
    {
2615
2592
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2616
2593
      assert(cmp_type != ROW_RESULT);
2617
 
      assert(cmp_items[(uint32_t)cmp_type]);
2618
 
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
 
2594
      assert(cmp_items[(uint)cmp_type]);
 
2595
      if (!(value_added_map & (1<<(uint)cmp_type)))
2619
2596
      {
2620
 
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
 
2597
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2621
2598
        if ((null_value=args[first_expr_num]->null_value))
2622
2599
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2623
 
        value_added_map|= 1<<(uint32_t)cmp_type;
 
2600
        value_added_map|= 1<<(uint)cmp_type;
2624
2601
      }
2625
 
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2602
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2626
2603
        return args[i + 1];
2627
2604
    }
2628
2605
  }
2686
2663
}
2687
2664
 
2688
2665
 
2689
 
type::Decimal *Item_func_case::val_decimal(type::Decimal *decimal_value)
 
2666
my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
2690
2667
{
2691
2668
  assert(fixed == 1);
2692
2669
  char buff[MAX_FIELD_WIDTH];
2693
2670
  String dummy_str(buff, sizeof(buff), default_charset());
2694
2671
  Item *item= find_item(&dummy_str);
2695
 
  type::Decimal *res;
 
2672
  my_decimal *res;
2696
2673
 
2697
2674
  if (!item)
2698
2675
  {
2706
2683
}
2707
2684
 
2708
2685
 
2709
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2686
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2710
2687
{
2711
2688
  /*
2712
2689
    buff should match stack usage from
2713
2690
    Item_func_case::val_int() -> Item_func_case::find_item()
2714
2691
  */
2715
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2716
 
                     +sizeof(double)*2+sizeof(int64_t)*2];
2717
 
  bool res= Item_func::fix_fields(session, ref);
 
2692
  uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
 
2693
  bool res= Item_func::fix_fields(thd, ref);
2718
2694
  /*
2719
2695
    Call check_stack_overrun after fix_fields to be sure that stack variable
2720
2696
    is not optimized away
2721
2697
  */
2722
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2698
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2723
2699
    return true;                                // Fatal error flag is set!
2724
2700
  return res;
2725
2701
}
2735
2711
 
2736
2712
void Item_func_case::agg_num_lengths(Item *arg)
2737
2713
{
2738
 
  uint32_t len= class_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2714
  uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2739
2715
                                           arg->unsigned_flag) - arg->decimals;
2740
 
  set_if_bigger(max_length, len);
 
2716
  set_if_bigger(max_length, len); 
2741
2717
  set_if_bigger(decimals, arg->decimals);
2742
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
 
2718
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
2743
2719
}
2744
2720
 
2745
2721
 
2746
2722
void Item_func_case::fix_length_and_dec()
2747
2723
{
2748
2724
  Item **agg;
2749
 
  uint32_t nagg;
2750
 
  uint32_t found_types= 0;
2751
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2725
  uint nagg;
 
2726
  uint found_types= 0;
 
2727
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2752
2728
    return;
2753
 
 
 
2729
  
2754
2730
  /*
2755
2731
    Aggregate all THEN and ELSE expression types
2756
2732
    and collations when string result
2757
2733
  */
2758
 
 
 
2734
  
2759
2735
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2760
2736
    agg[nagg]= args[nagg*2+1];
2761
 
 
 
2737
  
2762
2738
  if (else_expr_num != -1)
2763
2739
    agg[nagg++]= args[else_expr_num];
2764
 
 
 
2740
  
2765
2741
  agg_result_type(&cached_result_type, agg, nagg);
2766
2742
  if ((cached_result_type == STRING_RESULT) &&
2767
2743
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2768
2744
    return;
2769
 
 
 
2745
  
2770
2746
  cached_field_type= agg_field_type(agg, nagg);
2771
2747
  /*
2772
2748
    Aggregate first expression and all THEN expression types
2774
2750
  */
2775
2751
  if (first_expr_num != -1)
2776
2752
  {
 
2753
    uint i;
2777
2754
    agg[0]= args[first_expr_num];
2778
2755
    left_result_type= agg[0]->result_type();
2779
2756
 
2783
2760
    if (!(found_types= collect_cmp_types(agg, nagg)))
2784
2761
      return;
2785
2762
 
2786
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2763
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2787
2764
    {
2788
2765
      if (found_types & (1 << i) && !cmp_items[i])
2789
2766
      {
2801
2778
 
2802
2779
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2803
2780
    maybe_null=1;
2804
 
 
 
2781
  
2805
2782
  max_length=0;
2806
2783
  decimals=0;
2807
2784
  unsigned_flag= true;
2808
2785
  if (cached_result_type == STRING_RESULT)
2809
2786
  {
2810
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2787
    for (uint i= 0; i < ncases; i+= 2)
2811
2788
      agg_str_lengths(args[i + 1]);
2812
2789
    if (else_expr_num != -1)
2813
2790
      agg_str_lengths(args[else_expr_num]);
2814
2791
  }
2815
2792
  else
2816
2793
  {
2817
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2794
    for (uint i= 0; i < ncases; i+= 2)
2818
2795
      agg_num_lengths(args[i + 1]);
2819
 
    if (else_expr_num != -1)
 
2796
    if (else_expr_num != -1) 
2820
2797
      agg_num_lengths(args[else_expr_num]);
2821
 
    max_length= class_decimal_precision_to_length(max_length + decimals, decimals,
 
2798
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2822
2799
                                               unsigned_flag);
2823
2800
  }
2824
2801
}
2825
2802
 
2826
2803
 
2827
 
uint32_t Item_func_case::decimal_precision() const
 
2804
uint Item_func_case::decimal_precision() const
2828
2805
{
2829
2806
  int max_int_part=0;
2830
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2807
  for (uint i=0 ; i < ncases ; i+=2)
2831
2808
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2832
2809
 
2833
 
  if (else_expr_num != -1)
 
2810
  if (else_expr_num != -1) 
2834
2811
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2835
2812
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2836
2813
}
2849
2826
    args[first_expr_num]->print(str, query_type);
2850
2827
    str->append(' ');
2851
2828
  }
2852
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2829
  for (uint i=0 ; i < ncases ; i+=2)
2853
2830
  {
2854
2831
    str->append(STRING_WITH_LEN("when "));
2855
2832
    args[i]->print(str, query_type);
2869
2846
 
2870
2847
void Item_func_case::cleanup()
2871
2848
{
 
2849
  uint i;
2872
2850
  Item_func::cleanup();
2873
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2851
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2874
2852
  {
2875
2853
    delete cmp_items[i];
2876
2854
    cmp_items[i]= 0;
2877
2855
  }
 
2856
  return;
2878
2857
}
2879
2858
 
2880
2859
 
2886
2865
{
2887
2866
  assert(fixed == 1);
2888
2867
  null_value=0;
2889
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2868
  for (uint i=0 ; i < arg_count ; i++)
2890
2869
  {
2891
2870
    String *res;
2892
2871
    if ((res=args[i]->val_str(str)))
2900
2879
{
2901
2880
  assert(fixed == 1);
2902
2881
  null_value=0;
2903
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2882
  for (uint i=0 ; i < arg_count ; i++)
2904
2883
  {
2905
2884
    int64_t res=args[i]->val_int();
2906
2885
    if (!args[i]->null_value)
2914
2893
{
2915
2894
  assert(fixed == 1);
2916
2895
  null_value=0;
2917
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2896
  for (uint i=0 ; i < arg_count ; i++)
2918
2897
  {
2919
2898
    double res= args[i]->val_real();
2920
2899
    if (!args[i]->null_value)
2925
2904
}
2926
2905
 
2927
2906
 
2928
 
type::Decimal *Item_func_coalesce::decimal_op(type::Decimal *decimal_value)
 
2907
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
2929
2908
{
2930
2909
  assert(fixed == 1);
2931
2910
  null_value= 0;
2932
 
  for (uint32_t i= 0; i < arg_count; i++)
 
2911
  for (uint i= 0; i < arg_count; i++)
2933
2912
  {
2934
 
    type::Decimal *res= args[i]->val_decimal(decimal_value);
 
2913
    my_decimal *res= args[i]->val_decimal(decimal_value);
2935
2914
    if (!args[i]->null_value)
2936
2915
      return res;
2937
2916
  }
2944
2923
{
2945
2924
  cached_field_type= agg_field_type(args, arg_count);
2946
2925
  agg_result_type(&hybrid_type, args, arg_count);
2947
 
 
2948
2926
  switch (hybrid_type) {
2949
2927
  case STRING_RESULT:
2950
2928
    count_only_length();
2951
2929
    decimals= NOT_FIXED_DEC;
2952
2930
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2953
2931
    break;
2954
 
 
2955
2932
  case DECIMAL_RESULT:
2956
2933
    count_decimal_length();
2957
2934
    break;
2958
 
 
2959
2935
  case REAL_RESULT:
2960
2936
    count_real_length();
2961
2937
    break;
2962
 
 
2963
2938
  case INT_RESULT:
2964
2939
    count_only_length();
2965
2940
    decimals= 0;
2966
2941
    break;
2967
 
 
2968
2942
  case ROW_RESULT:
 
2943
  default:
2969
2944
    assert(0);
2970
2945
  }
2971
2946
}
3023
2998
 
3024
2999
 
3025
3000
/*
3026
 
  Compare two integers in IN value list format (packed_int64_t)
 
3001
  Compare two integers in IN value list format (packed_int64_t) 
3027
3002
 
3028
3003
  SYNOPSIS
3029
3004
    cmp_int64_t()
3045
3020
    0           left argument is equal to the right argument.
3046
3021
    1           left argument is greater than the right argument.
3047
3022
*/
3048
 
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3049
 
                in_int64_t::packed_int64_t *b)
 
3023
int cmp_int64_t(void *cmp_arg __attribute__((unused)),
 
3024
                 in_int64_t::packed_int64_t *a,
 
3025
                 in_int64_t::packed_int64_t *b)
3050
3026
{
3051
3027
  if (a->unsigned_flag != b->unsigned_flag)
3052
 
  {
3053
 
    /*
3054
 
      One of the args is unsigned and is too big to fit into the
 
3028
  { 
 
3029
    /* 
 
3030
      One of the args is unsigned and is too big to fit into the 
3055
3031
      positive signed range. Report no match.
3056
 
    */
 
3032
    */  
3057
3033
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3058
3034
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3059
3035
      return a->unsigned_flag ? 1 : -1;
3060
3036
    /*
3061
 
      Although the signedness differs both args can fit into the signed
 
3037
      Although the signedness differs both args can fit into the signed 
3062
3038
      positive range. Make them signed and compare as usual.
3063
 
    */
 
3039
    */  
3064
3040
    return cmp_longs (a->val, b->val);
3065
3041
  }
3066
3042
  if (a->unsigned_flag)
3069
3045
    return cmp_longs (a->val, b->val);
3070
3046
}
3071
3047
 
3072
 
static int cmp_double(void *, double *a, double *b)
 
3048
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3073
3049
{
3074
3050
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3075
3051
}
3076
3052
 
3077
 
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
 
3053
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
3078
3054
{
3079
3055
  return a->compare(b);
3080
3056
}
3081
3057
 
3082
3058
 
3083
 
static int cmp_decimal(void *, type::Decimal *a, type::Decimal *b)
 
3059
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
3084
3060
{
3085
3061
  /*
3086
3062
    We need call of fixing buffer pointer, because fast sort just copy
3088
3064
  */
3089
3065
  a->fix_buffer_pointer();
3090
3066
  b->fix_buffer_pointer();
3091
 
  return class_decimal_cmp(a, b);
3092
 
}
3093
 
 
3094
 
 
3095
 
void in_vector::sort()
3096
 
{
3097
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
 
3067
  return my_decimal_cmp(a, b);
3098
3068
}
3099
3069
 
3100
3070
 
3101
3071
int in_vector::find(Item *item)
3102
3072
{
3103
 
  unsigned char *result=get_value(item);
 
3073
  uchar *result=get_value(item);
3104
3074
  if (!result || !used_count)
3105
3075
    return 0;                           // Null value
3106
3076
 
3107
 
  uint32_t start,end;
 
3077
  uint start,end;
3108
3078
  start=0; end=used_count-1;
3109
3079
  while (start != end)
3110
3080
  {
3111
 
    uint32_t mid=(start+end+1)/2;
 
3081
    uint mid=(start+end+1)/2;
3112
3082
    int res;
3113
3083
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3114
3084
      return 1;
3120
3090
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3121
3091
}
3122
3092
 
3123
 
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3093
in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs)
3124
3094
  :in_vector(elements, sizeof(String), cmp_func, cs),
3125
3095
   tmp(buff, sizeof(buff), &my_charset_bin)
3126
3096
{}
3129
3099
{
3130
3100
  if (base)
3131
3101
  {
3132
 
    // base was allocated with help of memory::sql_alloc => following is OK
3133
 
    for (uint32_t i=0 ; i < count ; i++)
 
3102
    // base was allocated with help of sql_alloc => following is OK
 
3103
    for (uint i=0 ; i < count ; i++)
3134
3104
      ((String*) base)[i].free();
3135
3105
  }
3136
3106
}
3137
3107
 
3138
 
void in_string::set(uint32_t pos,Item *item)
 
3108
void in_string::set(uint pos,Item *item)
3139
3109
{
3140
3110
  String *str=((String*) base)+pos;
3141
3111
  String *res=item->val_str(str);
3150
3120
  }
3151
3121
  if (!str->charset())
3152
3122
  {
3153
 
    const CHARSET_INFO *cs;
 
3123
    CHARSET_INFO *cs;
3154
3124
    if (!(cs= item->collation.collation))
3155
3125
      cs= &my_charset_bin;              // Should never happen for STR items
3156
3126
    str->set_charset(cs);
3158
3128
}
3159
3129
 
3160
3130
 
3161
 
unsigned char *in_string::get_value(Item *item)
 
3131
uchar *in_string::get_value(Item *item)
3162
3132
{
3163
 
  return (unsigned char*) item->val_str(&tmp);
 
3133
  return (uchar*) item->val_str(&tmp);
3164
3134
}
3165
3135
 
3166
 
in_row::in_row(uint32_t elements, Item *)
 
3136
in_row::in_row(uint elements, Item * item __attribute__((unused)))
3167
3137
{
3168
3138
  base= (char*) new cmp_item_row[count= elements];
3169
3139
  size= sizeof(cmp_item_row);
3182
3152
    delete [] (cmp_item_row*) base;
3183
3153
}
3184
3154
 
3185
 
unsigned char *in_row::get_value(Item *item)
 
3155
uchar *in_row::get_value(Item *item)
3186
3156
{
3187
3157
  tmp.store_value(item);
3188
3158
  if (item->is_null())
3189
3159
    return 0;
3190
 
  return (unsigned char *)&tmp;
 
3160
  return (uchar *)&tmp;
3191
3161
}
3192
3162
 
3193
 
void in_row::set(uint32_t pos, Item *item)
 
3163
void in_row::set(uint pos, Item *item)
3194
3164
{
3195
3165
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3196
3166
  return;
3197
3167
}
3198
3168
 
3199
 
in_int64_t::in_int64_t(uint32_t elements) :
3200
 
  in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3169
in_int64_t::in_int64_t(uint elements)
 
3170
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3201
3171
{}
3202
3172
 
3203
 
void in_int64_t::set(uint32_t pos,Item *item)
 
3173
void in_int64_t::set(uint pos,Item *item)
3204
3174
{
3205
3175
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3206
 
 
 
3176
  
3207
3177
  buff->val= item->val_int();
3208
3178
  buff->unsigned_flag= item->unsigned_flag;
3209
3179
}
3210
3180
 
3211
 
unsigned char *in_int64_t::get_value(Item *item)
 
3181
uchar *in_int64_t::get_value(Item *item)
3212
3182
{
3213
3183
  tmp.val= item->val_int();
3214
3184
  if (item->null_value)
3215
3185
    return 0;
3216
3186
  tmp.unsigned_flag= item->unsigned_flag;
3217
 
  return (unsigned char*) &tmp;
 
3187
  return (uchar*) &tmp;
3218
3188
}
3219
3189
 
3220
 
in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
3221
 
  in_int64_t(elements),
3222
 
  session(current_session),
3223
 
  warn_item(warn_item_arg),
3224
 
  lval_cache(0)
3225
 
{}
3226
 
 
3227
 
void in_datetime::set(uint32_t pos, Item *item)
 
3190
void in_datetime::set(uint pos,Item *item)
3228
3191
{
3229
3192
  Item **tmp_item= &item;
3230
3193
  bool is_null;
3231
3194
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3232
3195
 
3233
 
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3196
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3234
3197
  buff->unsigned_flag= 1L;
3235
3198
}
3236
3199
 
3237
 
unsigned char *in_datetime::get_value(Item *item)
 
3200
uchar *in_datetime::get_value(Item *item)
3238
3201
{
3239
3202
  bool is_null;
3240
3203
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3241
 
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3204
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3242
3205
  if (item->null_value)
3243
3206
    return 0;
3244
3207
  tmp.unsigned_flag= 1L;
3245
 
  return (unsigned char*) &tmp;
 
3208
  return (uchar*) &tmp;
3246
3209
}
3247
3210
 
3248
 
in_double::in_double(uint32_t elements)
 
3211
in_double::in_double(uint elements)
3249
3212
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3250
3213
{}
3251
3214
 
3252
 
void in_double::set(uint32_t pos,Item *item)
 
3215
void in_double::set(uint pos,Item *item)
3253
3216
{
3254
3217
  ((double*) base)[pos]= item->val_real();
3255
3218
}
3256
3219
 
3257
 
unsigned char *in_double::get_value(Item *item)
 
3220
uchar *in_double::get_value(Item *item)
3258
3221
{
3259
3222
  tmp= item->val_real();
3260
3223
  if (item->null_value)
3261
 
    return 0;
3262
 
  return (unsigned char*) &tmp;
 
3224
    return 0;                                   /* purecov: inspected */
 
3225
  return (uchar*) &tmp;
3263
3226
}
3264
3227
 
3265
3228
 
3266
 
in_decimal::in_decimal(uint32_t elements)
3267
 
  :in_vector(elements, sizeof(type::Decimal),(qsort2_cmp) cmp_decimal, 0)
 
3229
in_decimal::in_decimal(uint elements)
 
3230
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3268
3231
{}
3269
3232
 
3270
3233
 
3271
 
void in_decimal::set(uint32_t pos, Item *item)
 
3234
void in_decimal::set(uint pos, Item *item)
3272
3235
{
3273
 
  /* as far as 'item' is constant, we can store reference on type::Decimal */
3274
 
  type::Decimal *dec= ((type::Decimal *)base) + pos;
 
3236
  /* as far as 'item' is constant, we can store reference on my_decimal */
 
3237
  my_decimal *dec= ((my_decimal *)base) + pos;
3275
3238
  dec->len= DECIMAL_BUFF_LENGTH;
3276
3239
  dec->fix_buffer_pointer();
3277
 
  type::Decimal *res= item->val_decimal(dec);
3278
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
 
3240
  my_decimal *res= item->val_decimal(dec);
 
3241
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
3279
3242
  if (!item->null_value && res != dec)
3280
 
    class_decimal2decimal(res, dec);
 
3243
    my_decimal2decimal(res, dec);
3281
3244
}
3282
3245
 
3283
3246
 
3284
 
unsigned char *in_decimal::get_value(Item *item)
 
3247
uchar *in_decimal::get_value(Item *item)
3285
3248
{
3286
 
  type::Decimal *result= item->val_decimal(&val);
 
3249
  my_decimal *result= item->val_decimal(&val);
3287
3250
  if (item->null_value)
3288
3251
    return 0;
3289
 
  return (unsigned char *)result;
 
3252
  return (uchar *)result;
3290
3253
}
3291
3254
 
3292
3255
 
3293
3256
cmp_item* cmp_item::get_comparator(Item_result type,
3294
 
                                   const CHARSET_INFO * const cs)
 
3257
                                   CHARSET_INFO *cs)
3295
3258
{
3296
3259
  switch (type) {
3297
3260
  case STRING_RESULT:
3298
3261
    return new cmp_item_sort_string(cs);
3299
 
 
3300
3262
  case INT_RESULT:
3301
3263
    return new cmp_item_int;
3302
 
 
3303
3264
  case REAL_RESULT:
3304
3265
    return new cmp_item_real;
3305
 
 
3306
3266
  case ROW_RESULT:
3307
3267
    return new cmp_item_row;
3308
 
 
3309
3268
  case DECIMAL_RESULT:
3310
3269
    return new cmp_item_decimal;
 
3270
  default:
 
3271
    assert(0);
 
3272
    break;
3311
3273
  }
3312
 
 
3313
3274
  return 0; // to satisfy compiler :)
3314
3275
}
3315
3276
 
3339
3300
{
3340
3301
  if (comparators)
3341
3302
  {
3342
 
    for (uint32_t i= 0; i < n; i++)
 
3303
    for (uint i= 0; i < n; i++)
3343
3304
    {
3344
3305
      if (comparators[i])
3345
3306
        delete comparators[i];
3352
3313
void cmp_item_row::alloc_comparators()
3353
3314
{
3354
3315
  if (!comparators)
3355
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3316
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3356
3317
}
3357
3318
 
3358
3319
 
3364
3325
  {
3365
3326
    item->bring_value();
3366
3327
    item->null_value= 0;
3367
 
    for (uint32_t i=0; i < n; i++)
 
3328
    for (uint i=0; i < n; i++)
3368
3329
    {
3369
3330
      if (!comparators[i])
3370
3331
        if (!(comparators[i]=
3388
3349
    return;
3389
3350
  }
3390
3351
  n= tmpl->n;
3391
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3352
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3392
3353
  {
3393
3354
    item->bring_value();
3394
3355
    item->null_value= 0;
3395
 
    for (uint32_t i=0; i < n; i++)
 
3356
    for (uint i=0; i < n; i++)
3396
3357
    {
3397
3358
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3398
3359
        break;                                  // new failed
3414
3375
  }
3415
3376
  bool was_null= 0;
3416
3377
  arg->bring_value();
3417
 
  for (uint32_t i=0; i < n; i++)
 
3378
  for (uint i=0; i < n; i++)
3418
3379
  {
3419
3380
    if (comparators[i]->cmp(arg->element_index(i)))
3420
3381
    {
3430
3391
int cmp_item_row::compare(cmp_item *c)
3431
3392
{
3432
3393
  cmp_item_row *l_cmp= (cmp_item_row *) c;
3433
 
  for (uint32_t i=0; i < n; i++)
 
3394
  for (uint i=0; i < n; i++)
3434
3395
  {
3435
3396
    int res;
3436
3397
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3442
3403
 
3443
3404
void cmp_item_decimal::store_value(Item *item)
3444
3405
{
3445
 
  type::Decimal *val= item->val_decimal(&value);
 
3406
  my_decimal *val= item->val_decimal(&value);
3446
3407
  /* val may be zero if item is nnull */
3447
3408
  if (val && val != &value)
3448
 
    class_decimal2decimal(val, &value);
 
3409
    my_decimal2decimal(val, &value);
3449
3410
}
3450
3411
 
3451
3412
 
3452
3413
int cmp_item_decimal::cmp(Item *arg)
3453
3414
{
3454
 
  type::Decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
 
3415
  my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
3455
3416
  if (arg->null_value)
3456
3417
    return 1;
3457
 
  return class_decimal_cmp(&value, tmp);
 
3418
  return my_decimal_cmp(&value, tmp);
3458
3419
}
3459
3420
 
3460
3421
 
3461
3422
int cmp_item_decimal::compare(cmp_item *arg)
3462
3423
{
3463
3424
  cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
3464
 
  return class_decimal_cmp(&value, &l_cmp->value);
 
3425
  return my_decimal_cmp(&value, &l_cmp->value);
3465
3426
}
3466
3427
 
3467
3428
 
3475
3436
{
3476
3437
  bool is_null;
3477
3438
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3478
 
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3439
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3479
3440
}
3480
3441
 
3481
3442
 
3484
3445
  bool is_null;
3485
3446
  Item **tmp_item= &arg;
3486
3447
  return value !=
3487
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3448
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3488
3449
}
3489
3450
 
3490
3451
 
3521
3482
    The function saves in ref the pointer to the item or to a newly created
3522
3483
    item that is considered as a replacement for the original one.
3523
3484
 
3524
 
  @param session     reference to the global context of the query thread
 
3485
  @param thd     reference to the global context of the query thread
3525
3486
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3526
3487
                 item is to be assigned
3527
3488
 
3542
3503
*/
3543
3504
 
3544
3505
bool
3545
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3506
Item_func_in::fix_fields(THD *thd, Item **ref)
3546
3507
{
3547
3508
  Item **arg, **arg_end;
3548
3509
 
3549
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3510
  if (Item_func_opt_neg::fix_fields(thd, ref))
3550
3511
    return 1;
3551
3512
 
3552
3513
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3562
3523
}
3563
3524
 
3564
3525
 
3565
 
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
 
3526
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
3566
3527
{
3567
3528
  return cs->coll->strnncollsp(cs,
3568
 
                               (unsigned char *) x->ptr(),x->length(),
3569
 
                               (unsigned char *) y->ptr(),y->length(), 0);
 
3529
                               (uchar *) x->ptr(),x->length(),
 
3530
                               (uchar *) y->ptr(),y->length(), 0);
3570
3531
}
3571
3532
 
3572
3533
 
3574
3535
{
3575
3536
  Item **arg, **arg_end;
3576
3537
  bool const_itm= 1;
 
3538
  THD *thd= current_thd;
3577
3539
  bool datetime_found= false;
3578
3540
  /* true <=> arguments values will be compared as DATETIMEs. */
3579
3541
  bool compare_as_datetime= false;
3580
3542
  Item *date_arg= 0;
3581
 
  uint32_t found_types= 0;
3582
 
  uint32_t type_cnt= 0;
 
3543
  uint found_types= 0;
 
3544
  uint type_cnt= 0, i;
3583
3545
  Item_result cmp_type= STRING_RESULT;
3584
3546
  left_result_type= args[0]->result_type();
3585
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3547
  if (!(found_types= collect_cmp_types(args, arg_count)))
3586
3548
    return;
3587
 
 
 
3549
  
3588
3550
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3589
3551
  {
3590
3552
    if (!arg[0]->const_item())
3593
3555
      break;
3594
3556
    }
3595
3557
  }
3596
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3558
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
3597
3559
  {
3598
3560
    if (found_types & 1 << i)
3599
3561
    {
3604
3566
 
3605
3567
  if (type_cnt == 1)
3606
3568
  {
3607
 
    if (cmp_type == STRING_RESULT &&
 
3569
    if (cmp_type == STRING_RESULT && 
3608
3570
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3609
3571
      return;
3610
3572
    arg_types_compatible= true;
3635
3597
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3636
3598
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3637
3599
    {
3638
 
      uint32_t col, num_cols= args[0]->cols();
 
3600
      uint col, cols= args[0]->cols();
3639
3601
 
3640
 
      for (col= 0; col < num_cols; col++)
 
3602
      for (col= 0; col < cols; col++)
3641
3603
      {
3642
3604
        bool skip_column= false;
3643
3605
        /*
3700
3662
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3701
3663
  {
3702
3664
    if (compare_as_datetime)
3703
 
    {
3704
3665
      array= new in_datetime(date_arg, arg_count - 1);
3705
 
    }
3706
3666
    else
3707
3667
    {
3708
3668
      /*
3709
3669
        IN must compare INT columns and constants as int values (the same
3710
3670
        way as equality does).
3711
 
        So we must check here if the column on the left and all the constant
3712
 
        values on the right can be compared as integers and adjust the
 
3671
        So we must check here if the column on the left and all the constant 
 
3672
        values on the right can be compared as integers and adjust the 
3713
3673
        comparison type accordingly.
3714
 
      */
 
3674
      */  
3715
3675
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3676
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3716
3677
          cmp_type != INT_RESULT)
3717
3678
      {
3718
3679
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3721
3682
          bool all_converted= true;
3722
3683
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3723
3684
          {
3724
 
            if (!convert_constant_item (&getSession(), field_item, &arg[0]))
 
3685
            if (!convert_constant_item (thd, field_item, &arg[0]))
3725
3686
              all_converted= false;
3726
3687
          }
3727
3688
          if (all_converted)
3728
3689
            cmp_type= INT_RESULT;
3729
3690
        }
3730
3691
      }
3731
 
 
3732
3692
      switch (cmp_type) {
3733
3693
      case STRING_RESULT:
3734
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
 
3694
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
3735
3695
                            cmp_collation.collation);
3736
3696
        break;
3737
 
 
3738
3697
      case INT_RESULT:
3739
3698
        array= new in_int64_t(arg_count-1);
3740
3699
        break;
3741
 
 
3742
3700
      case REAL_RESULT:
3743
3701
        array= new in_double(arg_count-1);
3744
3702
        break;
3745
 
 
3746
3703
      case ROW_RESULT:
3747
3704
        /*
3748
3705
          The row comparator was created at the beginning but only DATETIME
3751
3708
        */
3752
3709
        ((in_row*)array)->tmp.store_value(args[0]);
3753
3710
        break;
3754
 
 
3755
3711
      case DECIMAL_RESULT:
3756
3712
        array= new in_decimal(arg_count - 1);
3757
3713
        break;
 
3714
      default:
 
3715
        assert(0);
 
3716
        return;
3758
3717
      }
3759
3718
    }
3760
 
 
3761
 
    if (array && !(getSession().is_fatal_error))                // If not EOM
 
3719
    if (array && !(thd->is_fatal_error))                // If not EOM
3762
3720
    {
3763
 
      uint32_t j=0;
3764
 
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
 
3721
      uint j=0;
 
3722
      for (uint i=1 ; i < arg_count ; i++)
3765
3723
      {
3766
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
3767
 
        {
3768
 
          array->set(j,args[arg_num]);
3769
 
          j++;
3770
 
        }
3771
 
        else
3772
 
          have_null= 1;
 
3724
        array->set(j,args[i]);
 
3725
        if (!args[i]->null_value)                       // Skip NULL values
 
3726
          j++;
 
3727
        else
 
3728
          have_null= 1;
3773
3729
      }
3774
3730
      if ((array->used_count= j))
3775
 
        array->sort();
 
3731
        array->sort();
3776
3732
    }
3777
3733
  }
3778
3734
  else
3781
3737
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3782
3738
    else
3783
3739
    {
3784
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3740
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
3785
3741
      {
3786
3742
        if (found_types & (1 << i) && !cmp_items[i])
3787
3743
        {
3842
3798
{
3843
3799
  cmp_item *in_item;
3844
3800
  assert(fixed == 1);
3845
 
  uint32_t value_added_map= 0;
 
3801
  uint value_added_map= 0;
3846
3802
  if (array)
3847
3803
  {
3848
3804
    int tmp=array->find(args[0]);
3850
3806
    return (int64_t) (!null_value && tmp != negated);
3851
3807
  }
3852
3808
 
3853
 
  for (uint32_t i= 1 ; i < arg_count ; i++)
 
3809
  for (uint i= 1 ; i < arg_count ; i++)
3854
3810
  {
3855
3811
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3856
 
    in_item= cmp_items[(uint32_t)cmp_type];
 
3812
    in_item= cmp_items[(uint)cmp_type];
3857
3813
    assert(in_item);
3858
 
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
 
3814
    if (!(value_added_map & (1 << (uint)cmp_type)))
3859
3815
    {
3860
3816
      in_item->store_value(args[0]);
3861
3817
      if ((null_value=args[0]->null_value))
3862
3818
        return 0;
3863
3819
      have_null= 0;
3864
 
      value_added_map|= 1 << (uint32_t)cmp_type;
 
3820
      value_added_map|= 1 << (uint)cmp_type;
3865
3821
    }
3866
3822
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3867
3823
      return (int64_t) (!negated);
3873
3829
}
3874
3830
 
3875
3831
 
3876
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3877
 
  :item::function::Boolean(session, item),
 
3832
int64_t Item_func_bit_or::val_int()
 
3833
{
 
3834
  assert(fixed == 1);
 
3835
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3836
  if (args[0]->null_value)
 
3837
  {
 
3838
    null_value=1; /* purecov: inspected */
 
3839
    return 0; /* purecov: inspected */
 
3840
  }
 
3841
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3842
  if (args[1]->null_value)
 
3843
  {
 
3844
    null_value=1;
 
3845
    return 0;
 
3846
  }
 
3847
  null_value=0;
 
3848
  return (int64_t) (arg1 | arg2);
 
3849
}
 
3850
 
 
3851
 
 
3852
int64_t Item_func_bit_and::val_int()
 
3853
{
 
3854
  assert(fixed == 1);
 
3855
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3856
  if (args[0]->null_value)
 
3857
  {
 
3858
    null_value=1; /* purecov: inspected */
 
3859
    return 0; /* purecov: inspected */
 
3860
  }
 
3861
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3862
  if (args[1]->null_value)
 
3863
  {
 
3864
    null_value=1; /* purecov: inspected */
 
3865
    return 0; /* purecov: inspected */
 
3866
  }
 
3867
  null_value=0;
 
3868
  return (int64_t) (arg1 & arg2);
 
3869
}
 
3870
 
 
3871
Item_cond::Item_cond(THD *thd, Item_cond *item)
 
3872
  :Item_bool_func(thd, item),
3878
3873
   abort_on_null(item->abort_on_null),
3879
3874
   and_tables_cache(item->and_tables_cache)
3880
3875
{
3884
3879
}
3885
3880
 
3886
3881
 
3887
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3882
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3888
3883
{
3889
 
  List<Item>::iterator li(item->list.begin());
 
3884
  List_iterator_fast<Item> li(item->list);
3890
3885
  while (Item *it= li++)
3891
 
    list.push_back(it->copy_andor_structure(session));
 
3886
    list.push_back(it->copy_andor_structure(thd));
3892
3887
}
3893
3888
 
3894
3889
 
3895
3890
bool
3896
 
Item_cond::fix_fields(Session *session, Item **)
 
3891
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3897
3892
{
3898
3893
  assert(fixed == 0);
3899
 
  List<Item>::iterator li(list.begin());
 
3894
  List_iterator<Item> li(list);
3900
3895
  Item *item;
3901
 
  void *orig_session_marker= session->session_marker;
3902
 
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
 
3896
  void *orig_thd_marker= thd->thd_marker;
 
3897
  uchar buff[sizeof(char*)];                    // Max local vars in function
3903
3898
  not_null_tables_cache= used_tables_cache= 0;
3904
 
  const_item_cache= true;
 
3899
  const_item_cache= 1;
3905
3900
 
3906
3901
  if (functype() == COND_OR_FUNC)
3907
 
    session->session_marker= 0;
 
3902
    thd->thd_marker= 0;
3908
3903
  /*
3909
3904
    and_table_cache is the value that Item_cond_or() returns for
3910
3905
    not_null_tables()
3911
3906
  */
3912
3907
  and_tables_cache= ~(table_map) 0;
3913
3908
 
3914
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3909
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3915
3910
    return true;                                // Fatal error flag is set!
3916
3911
  /*
3917
3912
    The following optimization reduces the depth of an AND-OR tree.
3936
3931
           !((Item_cond*) item)->list.is_empty())
3937
3932
    {                                           // Identical function
3938
3933
      li.replace(((Item_cond*) item)->list);
3939
 
      ((Item_cond*) item)->list.clear();
 
3934
      ((Item_cond*) item)->list.empty();
3940
3935
      item= *li.ref();                          // new current item
3941
3936
    }
3942
3937
    if (abort_on_null)
3944
3939
 
3945
3940
    // item can be substituted in fix_fields
3946
3941
    if ((!item->fixed &&
3947
 
         item->fix_fields(session, li.ref())) ||
 
3942
         item->fix_fields(thd, li.ref())) ||
3948
3943
        (item= *li.ref())->check_cols(1))
3949
 
      return true;
 
3944
      return true; /* purecov: inspected */
3950
3945
    used_tables_cache|=     item->used_tables();
3951
3946
    if (item->const_item())
3952
3947
      and_tables_cache= (table_map) 0;
3956
3951
      not_null_tables_cache|= tmp_table_map;
3957
3952
      and_tables_cache&= tmp_table_map;
3958
3953
      const_item_cache= false;
3959
 
    }
 
3954
    }  
3960
3955
    with_sum_func=          with_sum_func || item->with_sum_func;
3961
3956
    with_subselect|=        item->with_subselect;
3962
3957
    if (item->maybe_null)
3963
3958
      maybe_null=1;
3964
3959
  }
3965
 
  session->getLex()->current_select->cond_count+= list.elements;
3966
 
  session->session_marker= orig_session_marker;
 
3960
  thd->lex->current_select->cond_count+= list.elements;
 
3961
  thd->thd_marker= orig_thd_marker;
3967
3962
  fix_length_and_dec();
3968
3963
  fixed= 1;
3969
3964
  return false;
3970
3965
}
3971
3966
 
3972
3967
 
3973
 
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
 
3968
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
3974
3969
{
3975
 
  List<Item>::iterator li(list.begin());
 
3970
  List_iterator<Item> li(list);
3976
3971
  Item *item;
3977
3972
 
3978
3973
  used_tables_cache=0;
3979
 
  const_item_cache= true;
 
3974
  const_item_cache=1;
3980
3975
 
3981
3976
  and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
3982
3977
  not_null_tables_cache= 0;
3997
3992
      not_null_tables_cache|= tmp_table_map;
3998
3993
      and_tables_cache&= tmp_table_map;
3999
3994
      const_item_cache= false;
4000
 
    }
 
3995
    }  
4001
3996
  }
4002
3997
}
4003
3998
 
4004
3999
 
4005
 
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
4000
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
4006
4001
{
4007
 
  List<Item>::iterator li(list.begin());
 
4002
  List_iterator_fast<Item> li(list);
4008
4003
  Item *item;
4009
4004
  while ((item= li++))
4010
4005
    if (item->walk(processor, walk_subquery, arg))
4015
4010
 
4016
4011
/**
4017
4012
  Transform an Item_cond object with a transformer callback function.
4018
 
 
 
4013
  
4019
4014
    The function recursively applies the transform method to each
4020
4015
     member item of the condition list.
4021
4016
    If the call of the method for a member item returns a new item
4022
4017
    the old item is substituted for a new one.
4023
4018
    After this the transformer is applied to the root node
4024
 
    of the Item_cond object.
4025
 
 
 
4019
    of the Item_cond object. 
 
4020
     
4026
4021
  @param transformer   the transformer callback function to be applied to
4027
4022
                       the nodes of the tree of the object
4028
4023
  @param arg           parameter to be passed to the transformer
4029
4024
 
4030
4025
  @return
4031
 
    Item returned as the result of transformation of the root node
 
4026
    Item returned as the result of transformation of the root node 
4032
4027
*/
4033
4028
 
4034
 
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
 
4029
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
4035
4030
{
4036
 
  List<Item>::iterator li(list.begin());
 
4031
  List_iterator<Item> li(list);
4037
4032
  Item *item;
4038
4033
  while ((item= li++))
4039
4034
  {
4042
4037
      return 0;
4043
4038
 
4044
4039
    /*
4045
 
      Session::change_item_tree() should be called only if the tree was
 
4040
      THD::change_item_tree() should be called only if the tree was
4046
4041
      really transformed, i.e. when a new item has been created.
4047
4042
      Otherwise we'll be allocating a lot of unnecessary memory for
4048
4043
      change records at each execution.
4049
4044
    */
4050
4045
    if (new_item != item)
4051
 
      getSession().change_item_tree(li.ref(), new_item);
 
4046
      current_thd->change_item_tree(li.ref(), new_item);
4052
4047
  }
4053
4048
  return Item_func::transform(transformer, arg);
4054
4049
}
4057
4052
/**
4058
4053
  Compile Item_cond object with a processor and a transformer
4059
4054
  callback functions.
4060
 
 
 
4055
  
4061
4056
    First the function applies the analyzer to the root node of
4062
4057
    the Item_func object. Then if the analyzer succeeeds (returns true)
4063
4058
    the function recursively applies the compile method to member
4065
4060
    If the call of the method for a member item returns a new item
4066
4061
    the old item is substituted for a new one.
4067
4062
    After this the transformer is applied to the root node
4068
 
    of the Item_cond object.
4069
 
 
 
4063
    of the Item_cond object. 
 
4064
     
4070
4065
  @param analyzer      the analyzer callback function to be applied to the
4071
4066
                       nodes of the tree of the object
4072
4067
  @param[in,out] arg_p parameter to be passed to the analyzer
4075
4070
  @param arg_t         parameter to be passed to the transformer
4076
4071
 
4077
4072
  @return
4078
 
    Item returned as the result of transformation of the root node
 
4073
    Item returned as the result of transformation of the root node 
4079
4074
*/
4080
4075
 
4081
 
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4082
 
                         Item_transformer transformer, unsigned char *arg_t)
 
4076
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
 
4077
                         Item_transformer transformer, uchar *arg_t)
4083
4078
{
4084
4079
  if (!(this->*analyzer)(arg_p))
4085
4080
    return 0;
4086
 
 
4087
 
  List<Item>::iterator li(list.begin());
 
4081
  
 
4082
  List_iterator<Item> li(list);
4088
4083
  Item *item;
4089
4084
  while ((item= li++))
4090
4085
  {
4091
 
    /*
 
4086
    /* 
4092
4087
      The same parameter value of arg_p must be passed
4093
4088
      to analyze any argument of the condition formula.
4094
 
    */
4095
 
    unsigned char *arg_v= *arg_p;
 
4089
    */   
 
4090
    uchar *arg_v= *arg_p;
4096
4091
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4097
4092
    if (new_item && new_item != item)
4098
4093
      li.replace(new_item);
4103
4098
void Item_cond::traverse_cond(Cond_traverser traverser,
4104
4099
                              void *arg, traverse_order order)
4105
4100
{
4106
 
  List<Item>::iterator li(list.begin());
 
4101
  List_iterator<Item> li(list);
4107
4102
  Item *item;
4108
4103
 
4109
 
  switch (order) {
4110
 
  case (T_PREFIX):
 
4104
  switch(order) {
 
4105
  case(PREFIX):
4111
4106
    (*traverser)(this, arg);
4112
4107
    while ((item= li++))
4113
4108
    {
4115
4110
    }
4116
4111
    (*traverser)(NULL, arg);
4117
4112
    break;
4118
 
  case (T_POSTFIX):
 
4113
  case(POSTFIX):
4119
4114
    while ((item= li++))
4120
4115
    {
4121
4116
      item->traverse_cond(traverser, arg, order);
4132
4127
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4133
4128
  sql_select.cc)
4134
4129
 
4135
 
  @param session                        Thread handler
 
4130
  @param thd                    Thread handler
4136
4131
  @param ref_pointer_array      Pointer to array of reference fields
4137
4132
  @param fields         All fields in select
4138
4133
 
4141
4136
    that have or refer (HAVING) to a SUM expression.
4142
4137
*/
4143
4138
 
4144
 
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
 
4139
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
4145
4140
                               List<Item> &fields)
4146
4141
{
4147
 
  List<Item>::iterator li(list.begin());
 
4142
  List_iterator<Item> li(list);
4148
4143
  Item *item;
4149
4144
  while ((item= li++))
4150
 
    item->split_sum_func(session, ref_pointer_array,
4151
 
                         fields, li.ref(), true);
 
4145
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4152
4146
}
4153
4147
 
4154
4148
 
4161
4155
 
4162
4156
void Item_cond::update_used_tables()
4163
4157
{
4164
 
  List<Item>::iterator li(list.begin());
 
4158
  List_iterator_fast<Item> li(list);
4165
4159
  Item *item;
4166
4160
 
4167
4161
  used_tables_cache=0;
4168
 
  const_item_cache= true;
 
4162
  const_item_cache=1;
4169
4163
  while ((item=li++))
4170
4164
  {
4171
4165
    item->update_used_tables();
4178
4172
void Item_cond::print(String *str, enum_query_type query_type)
4179
4173
{
4180
4174
  str->append('(');
4181
 
  List<Item>::iterator li(list.begin());
 
4175
  List_iterator_fast<Item> li(list);
4182
4176
  Item *item;
4183
4177
  if ((item=li++))
4184
4178
    item->print(str, query_type);
4193
4187
}
4194
4188
 
4195
4189
 
4196
 
void Item_cond::neg_arguments(Session *session)
 
4190
void Item_cond::neg_arguments(THD *thd)
4197
4191
{
4198
 
  List<Item>::iterator li(list.begin());
 
4192
  List_iterator<Item> li(list);
4199
4193
  Item *item;
4200
4194
  while ((item= li++))          /* Apply not transformation to the arguments */
4201
4195
  {
4202
 
    Item *new_item= item->neg_transformer(session);
 
4196
    Item *new_item= item->neg_transformer(thd);
4203
4197
    if (!new_item)
4204
4198
    {
4205
4199
      if (!(new_item= new Item_func_not(item)))
4206
4200
        return;                                 // Fatal OEM error
4207
4201
    }
4208
 
    li.replace(new_item);
 
4202
    VOID(li.replace(new_item));
4209
4203
  }
4210
4204
}
4211
4205
 
4233
4227
int64_t Item_cond_and::val_int()
4234
4228
{
4235
4229
  assert(fixed == 1);
4236
 
  List<Item>::iterator li(list.begin());
 
4230
  List_iterator_fast<Item> li(list);
4237
4231
  Item *item;
4238
4232
  null_value= 0;
4239
4233
  while ((item=li++))
4251
4245
int64_t Item_cond_or::val_int()
4252
4246
{
4253
4247
  assert(fixed == 1);
4254
 
  List<Item>::iterator li(list.begin());
 
4248
  List_iterator_fast<Item> li(list);
4255
4249
  Item *item;
4256
4250
  null_value=0;
4257
4251
  while ((item=li++))
4394
4388
  if (canDoTurboBM)
4395
4389
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4396
4390
  return my_wildcmp(cmp.cmp_collation.collation,
4397
 
                    res->ptr(),res->ptr()+res->length(),
 
4391
                    res->ptr(),res->ptr()+res->length(),
4398
4392
                    res2->ptr(),res2->ptr()+res2->length(),
4399
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4400
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4393
                    escape,wild_one,wild_many) ? 0 : 1;
4401
4394
}
4402
4395
 
4403
4396
 
4414
4407
    if (!res2)
4415
4408
      return OPTIMIZE_NONE;
4416
4409
 
4417
 
    if (*res2->ptr() != internal::wild_many)
 
4410
    if (*res2->ptr() != wild_many)
4418
4411
    {
4419
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4412
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4420
4413
        return OPTIMIZE_OP;
4421
4414
    }
4422
4415
  }
4424
4417
}
4425
4418
 
4426
4419
 
4427
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4420
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4428
4421
{
4429
4422
  assert(fixed == 0);
4430
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4431
 
      escape_item->fix_fields(session, &escape_item))
 
4423
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4424
      escape_item->fix_fields(thd, &escape_item))
4432
4425
    return true;
4433
4426
 
4434
4427
  if (!escape_item->const_during_execution())
4436
4429
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4437
4430
    return true;
4438
4431
  }
4439
 
 
 
4432
  
4440
4433
  if (escape_item->const_item())
4441
4434
  {
4442
 
    
4443
4435
    /* If we are on execution stage */
4444
4436
    String *escape_str= escape_item->val_str(&tmp_value1);
4445
4437
    if (escape_str)
4446
4438
    {
4447
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4448
 
      strcpy(escape, escape_str->ptr()); 
 
4439
      if (escape_used_in_parsing && (
 
4440
             (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
4441
                escape_str->numchars() != 1) ||
 
4442
               escape_str->numchars() > 1)))
 
4443
      {
 
4444
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4445
        return true;
 
4446
      }
 
4447
 
 
4448
      if (use_mb(cmp.cmp_collation.collation))
 
4449
      {
 
4450
        CHARSET_INFO *cs= escape_str->charset();
 
4451
        my_wc_t wc;
 
4452
        int rc= cs->cset->mb_wc(cs, &wc,
 
4453
                                (const uchar*) escape_str->ptr(),
 
4454
                                (const uchar*) escape_str->ptr() +
 
4455
                                               escape_str->length());
 
4456
        escape= (int) (rc > 0 ? wc : '\\');
 
4457
      }
 
4458
      else
 
4459
      {
 
4460
        /*
 
4461
          In the case of 8bit character set, we pass native
 
4462
          code instead of Unicode code as "escape" argument.
 
4463
          Convert to "cs" if charset of escape differs.
 
4464
        */
 
4465
        CHARSET_INFO *cs= cmp.cmp_collation.collation;
 
4466
        uint32_t unused;
 
4467
        if (escape_str->needs_conversion(escape_str->length(),
 
4468
                                         escape_str->charset(), cs, &unused))
 
4469
        {
 
4470
          char ch;
 
4471
          uint errors;
 
4472
          uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4473
                                          escape_str->length(),
 
4474
                                          escape_str->charset(), &errors);
 
4475
          escape= cnvlen ? ch : '\\';
 
4476
        }
 
4477
        else
 
4478
          escape= *(escape_str->ptr());
 
4479
      }
4449
4480
    }
4450
4481
    else
4451
 
    {
4452
 
      escape= (char *)memory::sql_alloc(1);
4453
 
      strcpy(escape, "\\");
4454
 
    } 
4455
 
   
 
4482
      escape= '\\';
 
4483
 
4456
4484
    /*
4457
4485
      We could also do boyer-more for non-const items, but as we would have to
4458
4486
      recompute the tables for each row it's not worth it.
4459
4487
    */
4460
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
 
4488
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
 
4489
       !(specialflag & SPECIAL_NO_NEW_FUNC))
4461
4490
    {
4462
4491
      String* res2 = args[1]->val_str(&tmp_value2);
4463
4492
      if (!res2)
4464
4493
        return false;                           // Null argument
4465
 
 
 
4494
      
4466
4495
      const size_t len   = res2->length();
4467
4496
      const char*  first = res2->ptr();
4468
4497
      const char*  last  = first + len - 1;
4470
4499
        len must be > 2 ('%pattern%')
4471
4500
        heuristic: only do TurboBM for pattern_len > 2
4472
4501
      */
4473
 
 
 
4502
      
4474
4503
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4475
 
          *first == internal::wild_many &&
4476
 
          *last  == internal::wild_many)
 
4504
          *first == wild_many &&
 
4505
          *last  == wild_many)
4477
4506
      {
4478
4507
        const char* tmp = first + 1;
4479
 
        for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
4480
 
        {
4481
 
          if (escape == tmp)
4482
 
            break;
4483
 
        }
4484
 
  
 
4508
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4485
4509
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4486
4510
      }
4487
4511
      if (canDoTurboBM)
4488
4512
      {
4489
4513
        pattern     = first + 1;
4490
4514
        pattern_len = (int) len - 2;
4491
 
        int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
4492
 
                                                                  ((pattern_len + 1)*2+
4493
 
                                                                   alphabet_size)));
 
4515
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
 
4516
                                      ((pattern_len + 1)*2+
 
4517
                                      alphabet_size)));
4494
4518
        bmGs      = suff + pattern_len + 1;
4495
4519
        bmBc      = bmGs + pattern_len + 1;
4496
4520
        turboBM_compute_good_suffix_shifts(suff);
4507
4531
  Item_bool_func2::cleanup();
4508
4532
}
4509
4533
 
4510
 
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
4511
 
{
4512
4534
#ifdef LIKE_CMP_TOUPPER
4513
 
  return cs->toupper(a);
 
4535
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
4514
4536
#else
4515
 
  return cs->sort_order[a];
 
4537
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
4516
4538
#endif
4517
 
}
 
4539
 
4518
4540
 
4519
4541
/**
4520
4542
  Precomputation dependent only on pattern_len.
4526
4548
  int            f = 0;
4527
4549
  int            g = plm1;
4528
4550
  int *const splm1 = suff + plm1;
4529
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4551
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4530
4552
 
4531
4553
  *splm1 = pattern_len;
4532
4554
 
4533
4555
  if (!cs->sort_order)
4534
4556
  {
4535
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4557
    int i;
 
4558
    for (i = pattern_len - 2; i >= 0; i--)
4536
4559
    {
4537
4560
      int tmp = *(splm1 + i - f);
4538
4561
      if (g < i && tmp < i - g)
4539
 
        suff[i] = tmp;
 
4562
        suff[i] = tmp;
4540
4563
      else
4541
4564
      {
4542
 
        if (i < g)
4543
 
          g = i;
4544
 
        f = i;
4545
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4546
 
          g--;
4547
 
        suff[i] = f - g;
 
4565
        if (i < g)
 
4566
          g = i; // g = min(i, g)
 
4567
        f = i;
 
4568
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4569
          g--;
 
4570
        suff[i] = f - g;
4548
4571
      }
4549
4572
    }
4550
4573
  }
4551
4574
  else
4552
4575
  {
4553
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4576
    int i;
 
4577
    for (i = pattern_len - 2; 0 <= i; --i)
4554
4578
    {
4555
4579
      int tmp = *(splm1 + i - f);
4556
4580
      if (g < i && tmp < i - g)
4557
 
        suff[i] = tmp;
 
4581
        suff[i] = tmp;
4558
4582
      else
4559
4583
      {
4560
 
        if (i < g)
4561
 
          g = i;
4562
 
        f = i;
4563
 
        while (g >= 0 &&
4564
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4565
 
          g--;
4566
 
        suff[i] = f - g;
 
4584
        if (i < g)
 
4585
          g = i; // g = min(i, g)
 
4586
        f = i;
 
4587
        while (g >= 0 &&
 
4588
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4589
          g--;
 
4590
        suff[i] = f - g;
4567
4591
      }
4568
4592
    }
4569
4593
  }
4624
4648
  int *end = bmBc + alphabet_size;
4625
4649
  int j;
4626
4650
  const int plm1 = pattern_len - 1;
4627
 
  const CHARSET_INFO *const cs= cmp.cmp_collation.collation;
 
4651
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4628
4652
 
4629
4653
  for (i = bmBc; i < end; i++)
4630
4654
    *i = pattern_len;
4632
4656
  if (!cs->sort_order)
4633
4657
  {
4634
4658
    for (j = 0; j < plm1; j++)
4635
 
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
 
4659
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
4636
4660
  }
4637
4661
  else
4638
4662
  {
4639
4663
    for (j = 0; j < plm1; j++)
4640
 
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
 
4664
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4641
4665
  }
4642
4666
}
4643
4667
 
4651
4675
 
4652
4676
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
4653
4677
{
4654
 
  int bcShift;
4655
 
  int turboShift;
 
4678
  register int bcShift;
 
4679
  register int turboShift;
4656
4680
  int shift = pattern_len;
4657
4681
  int j     = 0;
4658
4682
  int u     = 0;
4659
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4683
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4660
4684
 
4661
4685
  const int plm1=  pattern_len - 1;
4662
4686
  const int tlmpl= text_len - pattern_len;
4666
4690
  {
4667
4691
    while (j <= tlmpl)
4668
4692
    {
4669
 
      int i= plm1;
 
4693
      register int i= plm1;
4670
4694
      while (i >= 0 && pattern[i] == text[i + j])
4671
4695
      {
4672
4696
        i--;
4676
4700
      if (i < 0)
4677
4701
        return 1;
4678
4702
 
4679
 
      const int v = plm1 - i;
 
4703
      register const int v = plm1 - i;
4680
4704
      turboShift = u - v;
4681
 
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4682
 
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4683
 
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
 
4705
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
 
4706
      shift      = max(turboShift, bcShift);
 
4707
      shift      = max(shift, bmGs[i]);
4684
4708
      if (shift == bmGs[i])
4685
 
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
 
4709
        u = min(pattern_len - shift, v);
4686
4710
      else
4687
4711
      {
4688
 
        if (turboShift < bcShift)
4689
 
          shift= max(shift, u + 1);
4690
 
        u = 0;
 
4712
        if (turboShift < bcShift)
 
4713
          shift = max(shift, u + 1);
 
4714
        u = 0;
4691
4715
      }
4692
4716
      j+= shift;
4693
4717
    }
4697
4721
  {
4698
4722
    while (j <= tlmpl)
4699
4723
    {
4700
 
      int i = plm1;
 
4724
      register int i = plm1;
4701
4725
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4702
4726
      {
4703
 
        i--;
4704
 
        if (i == plm1 - shift)
4705
 
          i-= u;
 
4727
        i--;
 
4728
        if (i == plm1 - shift)
 
4729
          i-= u;
4706
4730
      }
4707
 
 
4708
4731
      if (i < 0)
4709
 
        return 1;
 
4732
        return 1;
4710
4733
 
4711
 
      const int v= plm1 - i;
4712
 
      turboShift= u - v;
4713
 
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4714
 
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4715
 
      shift= max(shift, bmGs[i]);
4716
 
      
 
4734
      register const int v = plm1 - i;
 
4735
      turboShift = u - v;
 
4736
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
 
4737
      shift      = max(turboShift, bcShift);
 
4738
      shift      = max(shift, bmGs[i]);
4717
4739
      if (shift == bmGs[i])
4718
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4740
        u = min(pattern_len - shift, v);
4719
4741
      else
4720
4742
      {
4721
 
        if (turboShift < bcShift)
4722
 
          shift= max(shift, u + 1);
4723
 
        u = 0;
 
4743
        if (turboShift < bcShift)
 
4744
          shift = max(shift, u + 1);
 
4745
        u = 0;
4724
4746
      }
4725
 
 
4726
4747
      j+= shift;
4727
4748
    }
4728
4749
    return 0;
4749
4770
int64_t Item_cond_xor::val_int()
4750
4771
{
4751
4772
  assert(fixed == 1);
4752
 
  List<Item>::iterator li(list.begin());
 
4773
  List_iterator<Item> li(list);
4753
4774
  Item *item;
4754
 
  int result=0;
 
4775
  int result=0; 
4755
4776
  null_value=0;
4756
4777
  while ((item=li++))
4757
4778
  {
4784
4805
       IS NOT NULL(a)     -> IS NULL(a)
4785
4806
    @endverbatim
4786
4807
 
4787
 
  @param session                thread handler
 
4808
  @param thd            thread handler
4788
4809
 
4789
4810
  @return
4790
4811
    New item or
4791
4812
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4792
4813
*/
4793
4814
 
4794
 
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
 
4815
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused)))  /* NOT(x)  ->  x */
4795
4816
{
4796
4817
  return args[0];
4797
4818
}
4798
4819
 
4799
4820
 
4800
 
Item *Item_bool_rowready_func2::neg_transformer(Session *)
 
4821
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
4801
4822
{
4802
4823
  Item *item= negated_item();
4803
4824
  return item;
4807
4828
/**
4808
4829
  a IS NULL  ->  a IS NOT NULL.
4809
4830
*/
4810
 
Item *Item_func_isnull::neg_transformer(Session *)
 
4831
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((unused)))
4811
4832
{
4812
4833
  Item *item= new Item_func_isnotnull(args[0]);
4813
4834
  return item;
4817
4838
/**
4818
4839
  a IS NOT NULL  ->  a IS NULL.
4819
4840
*/
4820
 
Item *Item_func_isnotnull::neg_transformer(Session *)
 
4841
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4821
4842
{
4822
4843
  Item *item= new Item_func_isnull(args[0]);
4823
4844
  return item;
4824
4845
}
4825
4846
 
4826
4847
 
4827
 
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
 
4848
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
4828
4849
                                        /* NOT a OR NOT b OR ... */
4829
4850
{
4830
 
  neg_arguments(session);
 
4851
  neg_arguments(thd);
4831
4852
  Item *item= new Item_cond_or(list);
4832
4853
  return item;
4833
4854
}
4834
4855
 
4835
4856
 
4836
 
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
 
4857
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
4837
4858
                                        /* NOT a AND NOT b AND ... */
4838
4859
{
4839
 
  neg_arguments(session);
 
4860
  neg_arguments(thd);
4840
4861
  Item *item= new Item_cond_and(list);
4841
4862
  return item;
4842
4863
}
4843
4864
 
4844
4865
 
4845
 
Item *Item_func_nop_all::neg_transformer(Session *)
 
4866
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4846
4867
{
4847
4868
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4848
4869
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4853
4874
  return new_item;
4854
4875
}
4855
4876
 
4856
 
Item *Item_func_not_all::neg_transformer(Session *)
 
4877
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
4857
4878
{
4858
4879
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4859
4880
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4909
4930
}
4910
4931
 
4911
4932
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
4912
 
  : item::function::Boolean(), const_item(0), eval_item(0), cond_false(0)
 
4933
  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
4913
4934
{
4914
 
  const_item_cache= false;
 
4935
  const_item_cache= 0;
4915
4936
  fields.push_back(f1);
4916
4937
  fields.push_back(f2);
4917
4938
}
4918
4939
 
4919
4940
Item_equal::Item_equal(Item *c, Item_field *f)
4920
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4941
  : Item_bool_func(), eval_item(0), cond_false(0)
4921
4942
{
4922
 
  const_item_cache= false;
 
4943
  const_item_cache= 0;
4923
4944
  fields.push_back(f);
4924
4945
  const_item= c;
4925
4946
}
4926
4947
 
4927
4948
 
4928
4949
Item_equal::Item_equal(Item_equal *item_equal)
4929
 
  : item::function::Boolean(), eval_item(0), cond_false(0)
 
4950
  : Item_bool_func(), eval_item(0), cond_false(0)
4930
4951
{
4931
 
  const_item_cache= false;
4932
 
  List<Item_field>::iterator li(item_equal->fields.begin());
 
4952
  const_item_cache= 0;
 
4953
  List_iterator_fast<Item_field> li(item_equal->fields);
4933
4954
  Item_field *item;
4934
4955
  while ((item= li++))
4935
4956
  {
4952
4973
  func->set_cmp_func();
4953
4974
  func->quick_fix_field();
4954
4975
  if ((cond_false= !func->val_int()))
4955
 
    const_item_cache= true;
 
4976
    const_item_cache= 1;
4956
4977
}
4957
4978
 
4958
4979
void Item_equal::add(Item_field *f)
4960
4981
  fields.push_back(f);
4961
4982
}
4962
4983
 
4963
 
uint32_t Item_equal::members()
 
4984
uint Item_equal::members()
4964
4985
{
4965
4986
  return fields.elements;
4966
4987
}
4976
4997
  @retval
4977
4998
    1       if nultiple equality contains a reference to field
4978
4999
  @retval
4979
 
    0       otherwise
 
5000
    0       otherwise    
4980
5001
*/
4981
5002
 
4982
5003
bool Item_equal::contains(Field *field)
4983
5004
{
4984
 
  List<Item_field>::iterator it(fields.begin());
 
5005
  List_iterator_fast<Item_field> it(fields);
4985
5006
  Item_field *item;
4986
5007
  while ((item= it++))
4987
5008
  {
4994
5015
 
4995
5016
/**
4996
5017
  Join members of another Item_equal object.
4997
 
 
 
5018
  
4998
5019
    The function actually merges two multiple equalities.
4999
5020
    After this operation the Item_equal object additionally contains
5000
5021
    the field items of another item of the type Item_equal.
5001
5022
    If the optional constant items are not equal the cond_false flag is
5002
 
    set to 1.
 
5023
    set to 1.  
5003
5024
  @param item    multiple equality whose members are to be joined
5004
5025
*/
5005
5026
 
5009
5030
  Item *c= item->const_item;
5010
5031
  if (c)
5011
5032
  {
5012
 
    /*
5013
 
      The flag cond_false will be set to 1 after this, if
5014
 
      the multiple equality already contains a constant and its
 
5033
    /* 
 
5034
      The flag cond_false will be set to 1 after this, if 
 
5035
      the multiple equality already contains a constant and its 
5015
5036
      value is  not equal to the value of c.
5016
5037
    */
5017
5038
    add(c);
5018
5039
  }
5019
5040
  cond_false|= item->cond_false;
5020
 
}
 
5041
5021
5042
 
5022
5043
 
5023
5044
/**
5040
5061
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
5041
5062
{
5042
5063
  bool swap;
5043
 
  List<Item_field>::iterator it(fields.begin());
 
5064
  List_iterator<Item_field> it(fields);
5044
5065
  do
5045
5066
  {
5046
5067
    Item_field *item1= it++;
5064
5085
        ref1= ref2;
5065
5086
      }
5066
5087
    }
5067
 
    it= fields.begin();
 
5088
    it.rewind();
5068
5089
  } while (swap);
5069
5090
}
5070
5091
 
5081
5102
 
5082
5103
void Item_equal::update_const()
5083
5104
{
5084
 
  List<Item_field>::iterator it(fields.begin());
 
5105
  List_iterator<Item_field> it(fields);
5085
5106
  Item *item;
5086
5107
  while ((item= it++))
5087
5108
  {
5093
5114
  }
5094
5115
}
5095
5116
 
5096
 
bool Item_equal::fix_fields(Session *, Item **)
 
5117
bool Item_equal::fix_fields(THD *thd __attribute__((unused)), Item **ref __attribute__((unused)))
5097
5118
{
5098
 
  List<Item_field>::iterator li(fields.begin());
 
5119
  List_iterator_fast<Item_field> li(fields);
5099
5120
  Item *item;
5100
5121
  not_null_tables_cache= used_tables_cache= 0;
5101
 
  const_item_cache= false;
 
5122
  const_item_cache= 0;
5102
5123
  while ((item= li++))
5103
5124
  {
5104
5125
    table_map tmp_table_map;
5115
5136
 
5116
5137
void Item_equal::update_used_tables()
5117
5138
{
5118
 
  List<Item_field>::iterator li(fields.begin());
 
5139
  List_iterator_fast<Item_field> li(fields);
5119
5140
  Item *item;
5120
5141
  not_null_tables_cache= used_tables_cache= 0;
5121
5142
  if ((const_item_cache= cond_false))
5133
5154
  Item_field *item_field;
5134
5155
  if (cond_false)
5135
5156
    return 0;
5136
 
  List<Item_field>::iterator it(fields.begin());
 
5157
  List_iterator_fast<Item_field> it(fields);
5137
5158
  Item *item= const_item ? const_item : it++;
 
5159
  if ((null_value= item->null_value))
 
5160
    return 0;
5138
5161
  eval_item->store_value(item);
5139
 
  if ((null_value= item->null_value))
5140
 
    return 0;
5141
5162
  while ((item_field= it++))
5142
5163
  {
5143
5164
    /* Skip fields of non-const tables. They haven't been read yet */
5144
 
    if (item_field->field->getTable()->const_table)
 
5165
    if (item_field->field->table->const_table)
5145
5166
    {
5146
 
      if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
 
5167
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5147
5168
        return 0;
5148
5169
    }
5149
5170
  }
5157
5178
                                      item->collation.collation);
5158
5179
}
5159
5180
 
5160
 
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
5181
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
5161
5182
{
5162
 
  List<Item_field>::iterator it(fields.begin());
 
5183
  List_iterator_fast<Item_field> it(fields);
5163
5184
  Item *item;
5164
5185
  while ((item= it++))
5165
5186
  {
5169
5190
  return Item_func::walk(processor, walk_subquery, arg);
5170
5191
}
5171
5192
 
5172
 
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
 
5193
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
5173
5194
{
5174
 
  List<Item_field>::iterator it(fields.begin());
 
5195
  List_iterator<Item_field> it(fields);
5175
5196
  Item *item;
5176
5197
  while ((item= it++))
5177
5198
  {
5180
5201
      return 0;
5181
5202
 
5182
5203
    /*
5183
 
      Session::change_item_tree() should be called only if the tree was
 
5204
      THD::change_item_tree() should be called only if the tree was
5184
5205
      really transformed, i.e. when a new item has been created.
5185
5206
      Otherwise we'll be allocating a lot of unnecessary memory for
5186
5207
      change records at each execution.
5187
5208
    */
5188
5209
    if (new_item != item)
5189
 
      getSession().change_item_tree((Item **) it.ref(), new_item);
 
5210
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5190
5211
  }
5191
5212
  return Item_func::transform(transformer, arg);
5192
5213
}
5195
5216
{
5196
5217
  str->append(func_name());
5197
5218
  str->append('(');
5198
 
  List<Item_field>::iterator it(fields.begin());
 
5219
  List_iterator_fast<Item_field> it(fields);
5199
5220
  Item *item;
5200
5221
  if (const_item)
5201
5222
    const_item->print(str, query_type);
5213
5234
  str->append(')');
5214
5235
}
5215
5236
 
5216
 
cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
5217
 
  session(current_session),
5218
 
  warn_item(warn_item_arg),
5219
 
  lval_cache(0)
5220
 
{}
5221
 
 
5222
 
} /* namespace drizzled */