~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_cmpfunc.cc

  • Committer: Brian Aker
  • Date: 2008-07-20 05:41:52 UTC
  • Revision ID: brian@tangent.org-20080720054152-5laf6plsb0o7h6ss
Documentation cleanup

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
 
#include "drizzled/sql_select.h"
26
 
#include "drizzled/error.h"
27
 
#include "drizzled/temporal.h"
28
 
#include "drizzled/item/cmpfunc.h"
29
 
#include "drizzled/cached_item.h"
30
 
#include "drizzled/item/cache_int.h"
31
 
#include "drizzled/item/int_with_ref.h"
32
 
#include "drizzled/check_stack_overrun.h"
33
 
#include "drizzled/time_functions.h"
34
 
#include "drizzled/internal/my_sys.h"
35
 
#include <math.h>
36
 
#include <algorithm>
37
 
 
38
 
using namespace std;
39
 
 
40
 
namespace drizzled
41
 
{
42
 
 
43
 
extern const double log_10[309];
44
 
 
45
 
static Eq_creator eq_creator;
46
 
static Ne_creator ne_creator;
47
 
static Gt_creator gt_creator;
48
 
static Lt_creator lt_creator;
49
 
static Ge_creator ge_creator;
50
 
static Le_creator le_creator;
51
 
 
52
 
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 <m_ctype.h>
 
30
#include "sql_select.h"
 
31
 
 
32
static bool convert_constant_item(THD *, Item_field *, Item **);
53
33
 
54
34
static Item_result item_store_type(Item_result a, Item *item,
55
 
                                   bool unsigned_flag)
 
35
                                   my_bool unsigned_flag)
56
36
{
57
37
  Item_result b= item->result_type();
58
38
 
67
47
    return INT_RESULT;
68
48
}
69
49
 
70
 
static void agg_result_type(Item_result *type, Item **items, uint32_t nitems)
 
50
static void agg_result_type(Item_result *type, Item **items, uint nitems)
71
51
{
72
52
  Item **item, **item_end;
73
 
  bool unsigned_flag= 0;
 
53
  my_bool unsigned_flag= 0;
74
54
 
75
55
  *type= STRING_RESULT;
76
56
  /* Skip beginning NULL items */
104
84
  DESCRIPTION
105
85
    The function checks that two expressions have compatible row signatures
106
86
    i.e. that the number of columns they return are the same and that if they
107
 
    are both row expressions then each component from the first expression has
 
87
    are both row expressions then each component from the first expression has 
108
88
    a row signature compatible with the signature of the corresponding component
109
89
    of the second expression.
110
90
 
115
95
 
116
96
static int cmp_row_type(Item* item1, Item* item2)
117
97
{
118
 
  uint32_t n= item1->cols();
 
98
  uint n= item1->cols();
119
99
  if (item2->check_cols(n))
120
100
    return 1;
121
 
  for (uint32_t i=0; i<n; i++)
 
101
  for (uint i=0; i<n; i++)
122
102
  {
123
103
    if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
124
104
        (item1->element_index(i)->result_type() == ROW_RESULT &&
152
132
    0  otherwise
153
133
*/
154
134
 
155
 
static int agg_cmp_type(Item_result *type, Item **items, uint32_t nitems)
 
135
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
156
136
{
157
 
  uint32_t i;
 
137
  uint i;
158
138
  type[0]= items[0]->result_type();
159
139
  for (i= 1 ; i < nitems ; i++)
160
140
  {
165
145
      of the first row expression has a compatible row signature with
166
146
      the signature of the corresponding component of the second row
167
147
      expression.
168
 
    */
 
148
    */ 
169
149
    if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
170
150
      return 1;     // error found: invalid usage of rows
171
151
  }
191
171
  @return aggregated field type.
192
172
*/
193
173
 
194
 
enum_field_types agg_field_type(Item **items, uint32_t nitems)
 
174
enum_field_types agg_field_type(Item **items, uint nitems)
195
175
{
196
 
  uint32_t i;
 
176
  uint i;
197
177
  if (!nitems || items[0]->result_type() == ROW_RESULT )
198
178
    return (enum_field_types)-1;
199
179
  enum_field_types res= items[0]->field_type();
209
189
    collect_cmp_types()
210
190
      items             Array of items to collect types from
211
191
      nitems            Number of items in the array
212
 
      skip_nulls        Don't collect types of NULL items if TRUE
213
192
 
214
193
  DESCRIPTION
215
194
    This function collects different result types for comparison of the first
220
199
    Bitmap of collected types - otherwise
221
200
*/
222
201
 
223
 
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
 
202
static uint collect_cmp_types(Item **items, uint nitems)
224
203
{
225
 
  uint32_t i;
226
 
  uint32_t found_types;
 
204
  uint i;
 
205
  uint found_types;
227
206
  Item_result left_result= items[0]->result_type();
228
207
  assert(nitems > 1);
229
208
  found_types= 0;
230
209
  for (i= 1; i < nitems ; i++)
231
210
  {
232
 
    if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
233
 
      continue; // Skip NULL constant items
234
 
    if ((left_result == ROW_RESULT ||
 
211
    if ((left_result == ROW_RESULT || 
235
212
         items[i]->result_type() == ROW_RESULT) &&
236
213
        cmp_row_type(items[0], items[i]))
237
214
      return 0;
238
 
    found_types|= 1<< (uint32_t)item_cmp_type(left_result,
 
215
    found_types|= 1<< (uint)item_cmp_type(left_result,
239
216
                                           items[i]->result_type());
240
217
  }
241
 
  /*
242
 
   Even if all right-hand items are NULLs and we are skipping them all, we need
243
 
   at least one type bit in the found_type bitmask.
244
 
  */
245
 
  if (skip_nulls && !found_types)
246
 
    found_types= 1 << (uint)left_result;
247
218
  return found_types;
248
219
}
249
220
 
 
221
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
 
222
                              const char *fname)
 
223
{
 
224
  my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
 
225
           c1.collation->name,c1.derivation_name(),
 
226
           c2.collation->name,c2.derivation_name(),
 
227
           fname);
 
228
}
 
229
 
250
230
 
251
231
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
252
232
{
254
234
}
255
235
 
256
236
 
257
 
const Eq_creator* Eq_creator::instance()
258
 
{
259
 
  return &eq_creator;
260
 
}
261
 
 
262
 
 
263
237
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
264
238
{
265
239
  return new Item_func_ne(a, b);
266
240
}
267
241
 
268
242
 
269
 
const Ne_creator* Ne_creator::instance()
270
 
{
271
 
  return &ne_creator;
272
 
}
273
 
 
274
 
 
275
243
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
276
244
{
277
245
  return new Item_func_gt(a, b);
278
246
}
279
247
 
280
248
 
281
 
const Gt_creator* Gt_creator::instance()
282
 
{
283
 
  return &gt_creator;
284
 
}
285
 
 
286
 
 
287
249
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
288
250
{
289
251
  return new Item_func_lt(a, b);
290
252
}
291
253
 
292
254
 
293
 
const Lt_creator* Lt_creator::instance()
294
 
{
295
 
  return &lt_creator;
296
 
}
297
 
 
298
 
 
299
255
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
300
256
{
301
257
  return new Item_func_ge(a, b);
302
258
}
303
259
 
304
260
 
305
 
const Ge_creator* Ge_creator::instance()
306
 
{
307
 
  return &ge_creator;
308
 
}
309
 
 
310
 
 
311
261
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
312
262
{
313
263
  return new Item_func_le(a, b);
314
264
}
315
265
 
316
 
const Le_creator* Le_creator::instance()
317
 
{
318
 
  return &le_creator;
319
 
}
320
 
 
321
 
 
322
266
/*
323
267
  Test functions
324
268
  Most of these  returns 0LL if false and 1LL if true and
422
366
    also when comparing bigint to strings (in which case strings
423
367
    are converted to bigints).
424
368
 
425
 
  @param  session             thread handle
 
369
  @param  thd             thread handle
426
370
  @param  field_item      item will be converted using the type of this field
427
371
  @param[in,out] item     reference to the item to convert
428
372
 
439
383
    1  Item was replaced with an integer version of the item
440
384
*/
441
385
 
442
 
static bool convert_constant_item(Session *session, Item_field *field_item,
 
386
static bool convert_constant_item(THD *thd, Item_field *field_item,
443
387
                                  Item **item)
444
388
{
445
389
  Field *field= field_item->field;
446
390
  int result= 0;
447
391
 
448
 
  field->setWriteSet();
449
 
 
450
392
  if (!(*item)->with_subselect && (*item)->const_item())
451
393
  {
452
 
    ulong orig_sql_mode= session->variables.sql_mode;
453
 
    enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
 
394
    TABLE *table= field->table;
 
395
    ulong orig_sql_mode= thd->variables.sql_mode;
 
396
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
 
397
    my_bitmap_map *old_write_map;
 
398
    my_bitmap_map *old_read_map;
454
399
    uint64_t orig_field_val= 0; /* original field value if valid */
455
400
 
 
401
    if (table)
 
402
    {
 
403
      old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
 
404
      old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
 
405
    }
456
406
    /* For comparison purposes allow invalid dates like 2000-01-32 */
457
 
    session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
 
407
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
458
408
                             MODE_INVALID_DATES;
459
 
    session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
409
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
460
410
 
461
411
    /*
462
412
      Store the value of the field if it references an outer field because
469
419
      Item *tmp= new Item_int_with_ref(field->val_int(), *item,
470
420
                                       test(field->flags & UNSIGNED_FLAG));
471
421
      if (tmp)
472
 
        session->change_item_tree(item, tmp);
 
422
        thd->change_item_tree(item, tmp);
473
423
      result= 1;                                        // Item was replaced
474
424
    }
475
425
    /* Restore the original field value. */
479
429
      /* orig_field_val must be a valid value that can be restored back. */
480
430
      assert(!result);
481
431
    }
482
 
    session->variables.sql_mode= orig_sql_mode;
483
 
    session->count_cuted_fields= orig_count_cuted_fields;
 
432
    thd->variables.sql_mode= orig_sql_mode;
 
433
    thd->count_cuted_fields= orig_count_cuted_fields;
 
434
    if (table)
 
435
    {
 
436
      dbug_tmp_restore_column_map(table->write_set, old_write_map);
 
437
      dbug_tmp_restore_column_map(table->read_set, old_read_map);
 
438
    }
484
439
  }
485
440
  return result;
486
441
}
489
444
void Item_bool_func2::fix_length_and_dec()
490
445
{
491
446
  max_length= 1;                                     // Function returns 0 or 1
492
 
  Session *session;
 
447
  THD *thd;
493
448
 
494
449
  /*
495
450
    As some compare functions are generated after sql_yacc,
498
453
  if (!args[0] || !args[1])
499
454
    return;
500
455
 
501
 
  /*
 
456
  /* 
502
457
    We allow to convert to Unicode character sets in some cases.
503
458
    The conditions when conversion is possible are:
504
459
    - arguments A and B have different charsets
505
460
    - A wins according to coercibility rules
506
461
    - character set of A is superset for character set of B
507
 
 
 
462
   
508
463
    If all of the above is true, then it's possible to convert
509
464
    B into the character set of A, and then compare according
510
465
    to the collation of A.
511
466
  */
512
467
 
513
 
 
 
468
  
514
469
  DTCollation coll;
515
470
  if (args[0]->result_type() == STRING_RESULT &&
516
471
      args[1]->result_type() == STRING_RESULT &&
517
472
      agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
518
473
    return;
519
 
 
 
474
    
520
475
  args[0]->cmp_context= args[1]->cmp_context=
521
476
    item_cmp_type(args[0]->result_type(), args[1]->result_type());
522
477
  // Make a special case of compare with fields to get nicer DATE comparisons
527
482
    return;
528
483
  }
529
484
 
530
 
  session= current_session;
531
 
  Item_field *field_item= NULL;
 
485
  thd= current_thd;
532
486
 
533
487
  if (args[0]->real_item()->type() == FIELD_ITEM)
534
488
  {
535
 
    field_item= static_cast<Item_field*>(args[0]->real_item());
 
489
    Item_field *field_item= (Item_field*) (args[0]->real_item());
536
490
    if (field_item->field->can_be_compared_as_int64_t() &&
537
491
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
538
492
    {
539
 
      if (convert_constant_item(session, field_item, &args[1]))
 
493
      if (convert_constant_item(thd, field_item, &args[1]))
540
494
      {
541
495
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
542
496
                         INT_RESULT);           // Works for all types.
547
501
 
548
502
    if (args[1]->real_item()->type() == FIELD_ITEM)
549
503
    {
550
 
      field_item= static_cast<Item_field*>(args[1]->real_item());
 
504
      Item_field *field_item= (Item_field*) (args[1]->real_item());
551
505
      if (field_item->field->can_be_compared_as_int64_t() &&
552
506
          !(field_item->is_datetime() &&
553
507
            args[0]->result_type() == STRING_RESULT))
554
508
      {
555
 
        if (convert_constant_item(session, field_item, &args[0]))
 
509
        if (convert_constant_item(thd, field_item, &args[0]))
556
510
        {
557
511
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
558
512
                           INT_RESULT); // Works for all types.
570
524
{
571
525
  owner= item;
572
526
  func= comparator_matrix[type]
573
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
574
 
 
 
527
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
575
528
  switch (type) {
576
529
  case ROW_RESULT:
577
 
    {
578
 
      uint32_t n= (*a)->cols();
579
 
      if (n != (*b)->cols())
580
 
      {
581
 
        my_error(ER_OPERAND_COLUMNS, MYF(0), n);
582
 
        comparators= 0;
583
 
        return 1;
584
 
      }
585
 
      if (!(comparators= new Arg_comparator[n]))
586
 
        return 1;
587
 
      for (uint32_t i=0; i < n; i++)
588
 
      {
589
 
        if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
590
 
        {
591
 
          my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
592
 
          return 1;
593
 
        }
594
 
        comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
595
 
      }
596
 
      break;
597
 
    }
598
 
 
 
530
  {
 
531
    uint n= (*a)->cols();
 
532
    if (n != (*b)->cols())
 
533
    {
 
534
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
535
      comparators= 0;
 
536
      return 1;
 
537
    }
 
538
    if (!(comparators= new Arg_comparator[n]))
 
539
      return 1;
 
540
    for (uint i=0; i < n; i++)
 
541
    {
 
542
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
543
      {
 
544
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
545
        return 1;
 
546
      }
 
547
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
548
    }
 
549
    break;
 
550
  }
599
551
  case STRING_RESULT:
 
552
  {
 
553
    /*
 
554
      We must set cmp_charset here as we may be called from for an automatic
 
555
      generated item, like in natural join
 
556
    */
 
557
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
558
        cmp_collation.derivation == DERIVATION_NONE)
 
559
    {
 
560
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
561
      return 1;
 
562
    }
 
563
    if (cmp_collation.collation == &my_charset_bin)
600
564
    {
601
565
      /*
602
 
        We must set cmp_charset here as we may be called from for an automatic
603
 
        generated item, like in natural join
 
566
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
567
        without removing end space
604
568
      */
605
 
      if (cmp_collation.set((*a)->collation, (*b)->collation) ||
606
 
          cmp_collation.derivation == DERIVATION_NONE)
607
 
      {
608
 
        my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
609
 
        return 1;
610
 
      }
611
 
      if (cmp_collation.collation == &my_charset_bin)
612
 
      {
613
 
        /*
614
 
          We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
615
 
          without removing end space
616
 
        */
617
 
        if (func == &Arg_comparator::compare_string)
618
 
          func= &Arg_comparator::compare_binary_string;
619
 
        else if (func == &Arg_comparator::compare_e_string)
620
 
          func= &Arg_comparator::compare_e_binary_string;
 
569
      if (func == &Arg_comparator::compare_string)
 
570
        func= &Arg_comparator::compare_binary_string;
 
571
      else if (func == &Arg_comparator::compare_e_string)
 
572
        func= &Arg_comparator::compare_e_binary_string;
621
573
 
622
 
        /*
623
 
          As this is binary compassion, mark all fields that they can't be
624
 
          transformed. Otherwise we would get into trouble with comparisons
625
 
like:
626
 
WHERE col= 'j' AND col LIKE BINARY 'j'
627
 
which would be transformed to:
628
 
WHERE col= 'j'
 
574
      /*
 
575
        As this is binary compassion, mark all fields that they can't be
 
576
        transformed. Otherwise we would get into trouble with comparisons
 
577
        like:
 
578
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
579
        which would be transformed to:
 
580
        WHERE col= 'j'
629
581
      */
630
 
        (*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
631
 
        (*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
632
 
      }
633
 
      break;
 
582
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
583
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
634
584
    }
 
585
    break;
 
586
  }
635
587
  case INT_RESULT:
636
 
    {
637
 
      if (func == &Arg_comparator::compare_int_signed)
638
 
      {
639
 
        if ((*a)->unsigned_flag)
640
 
          func= (((*b)->unsigned_flag)?
641
 
                 &Arg_comparator::compare_int_unsigned :
642
 
                 &Arg_comparator::compare_int_unsigned_signed);
643
 
        else if ((*b)->unsigned_flag)
644
 
          func= &Arg_comparator::compare_int_signed_unsigned;
645
 
      }
646
 
      else if (func== &Arg_comparator::compare_e_int)
647
 
      {
648
 
        if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
649
 
          func= &Arg_comparator::compare_e_int_diff_signedness;
650
 
      }
651
 
      break;
652
 
    }
 
588
  {
 
589
    if (func == &Arg_comparator::compare_int_signed)
 
590
    {
 
591
      if ((*a)->unsigned_flag)
 
592
        func= (((*b)->unsigned_flag)?
 
593
               &Arg_comparator::compare_int_unsigned :
 
594
               &Arg_comparator::compare_int_unsigned_signed);
 
595
      else if ((*b)->unsigned_flag)
 
596
        func= &Arg_comparator::compare_int_signed_unsigned;
 
597
    }
 
598
    else if (func== &Arg_comparator::compare_e_int)
 
599
    {
 
600
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
601
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
602
    }
 
603
    break;
 
604
  }
653
605
  case DECIMAL_RESULT:
654
606
    break;
655
607
  case REAL_RESULT:
 
608
  {
 
609
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
656
610
    {
657
 
      if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
658
 
      {
659
 
        precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
660
 
        if (func == &Arg_comparator::compare_real)
661
 
          func= &Arg_comparator::compare_real_fixed;
662
 
        else if (func == &Arg_comparator::compare_e_real)
663
 
          func= &Arg_comparator::compare_e_real_fixed;
664
 
      }
665
 
      break;
 
611
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
 
612
      if (func == &Arg_comparator::compare_real)
 
613
        func= &Arg_comparator::compare_real_fixed;
 
614
      else if (func == &Arg_comparator::compare_e_real)
 
615
        func= &Arg_comparator::compare_e_real_fixed;
666
616
    }
667
 
  }
668
 
 
 
617
    break;
 
618
  }
 
619
  default:
 
620
    assert(0);
 
621
  }
669
622
  return 0;
670
623
}
671
624
 
673
626
/**
674
627
  @brief Convert date provided in a string to the int representation.
675
628
 
676
 
  @param[in]   session        thread handle
 
629
  @param[in]   thd        thread handle
677
630
  @param[in]   str        a string to convert
678
631
  @param[in]   warn_type  type of the timestamp for issuing the warning
679
632
  @param[in]   warn_name  field name for issuing the warning
693
646
*/
694
647
 
695
648
static uint64_t
696
 
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
 
649
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
697
650
                  char *warn_name, bool *error_arg)
698
651
{
699
652
  uint64_t value= 0;
700
653
  int error;
701
 
  DRIZZLE_TIME l_time;
702
 
  enum enum_drizzle_timestamp_type ret;
 
654
  MYSQL_TIME l_time;
 
655
  enum_mysql_timestamp_type ret;
703
656
 
704
657
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
705
658
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
706
 
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
659
                        (thd->variables.sql_mode &
 
660
                         (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
707
661
                       &error);
708
662
 
709
 
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
 
663
  if (ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE)
710
664
  {
711
665
    /*
712
666
      Do not return yet, we may still want to throw a "trailing garbage"
722
676
  }
723
677
 
724
678
  if (error > 0)
725
 
  {
726
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
679
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
727
680
                                 str->ptr(), str->length(),
728
681
                                 warn_type, warn_name);
729
 
  }
730
682
 
731
683
  return value;
732
684
}
749
701
         int result and the other item (b or a) is an item with string result.
750
702
         If the second item is a constant one then it's checked to be
751
703
         convertible to the DATE/DATETIME type. If the constant can't be
752
 
         converted to a DATE/DATETIME then an error is issued back to the Session.
 
704
         converted to a DATE/DATETIME then the compare_datetime() comparator
 
705
         isn't used and the warning about wrong DATE/DATETIME value is issued.
753
706
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
754
707
      the comparison is handled by other comparators.
755
 
 
756
708
    If the datetime comparator can be used and one the operands of the
757
709
    comparison is a string constant that was successfully converted to a
758
710
    DATE/DATETIME type then the result of the conversion is returned in the
765
717
*/
766
718
 
767
719
enum Arg_comparator::enum_date_cmp_type
768
 
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
769
 
                                     uint64_t *const_value)
 
720
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
770
721
{
771
722
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
723
  Item *str_arg= 0, *date_arg= 0;
773
724
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
725
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
726
    return CMP_DATE_DFLT;
776
727
 
777
 
  if (in_a->is_datetime())
 
728
  if (a->is_datetime())
778
729
  {
779
 
    if (in_b->is_datetime())
 
730
    if (b->is_datetime())
780
731
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
732
    else if (b->result_type() == STRING_RESULT)
782
733
    {
783
734
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
735
      date_arg= a;
 
736
      str_arg= b;
786
737
    }
787
738
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
739
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
740
  {
790
741
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
742
    date_arg= b;
 
743
    str_arg= a;
793
744
  }
794
745
 
795
746
  if (cmp_type != CMP_DATE_DFLT)
802
753
        (str_arg->type() != Item::FUNC_ITEM ||
803
754
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
804
755
    {
805
 
      /*
806
 
       * OK, we are here if we've got a date field (or something which can be 
807
 
       * compared as a date field) on one side of the equation, and a constant
808
 
       * string on the other side.  In this case, we must verify that the constant
809
 
       * string expression can indeed be evaluated as a datetime.  If it cannot, 
810
 
       * we throw an error here and stop processsing.  Bad data should ALWAYS 
811
 
       * produce an error, and no implicit conversion or truncation should take place.
812
 
       *
813
 
       * If the conversion to a DateTime temporal is successful, then we convert
814
 
       * the Temporal instance to a uint64_t for the comparison operator, which
815
 
       * compares date(times) using int64_t semantics.
816
 
       *
817
 
       * @TODO
818
 
       *
819
 
       * Does a uint64_t conversion really have to happen here?  Fields return int64_t
820
 
       * from val_int(), not uint64_t...
821
 
       */
 
756
      THD *thd= current_thd;
822
757
      uint64_t value;
823
 
      String *str_val;
824
 
      String tmp;
825
 
      /* DateTime used to pick up as many string conversion possibilities as possible. */
826
 
      DateTime temporal;
 
758
      bool error;
 
759
      String tmp, *str_val= 0;
 
760
      timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_NEWDATE ?
 
761
                              MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
827
762
 
828
763
      str_val= str_arg->val_str(&tmp);
829
 
      if (! str_val)
830
 
      {
831
 
        /* 
832
 
         * If we are here, it is most likely due to the comparison item
833
 
         * being a NULL.  Although this is incorrect (SQL demands that the term IS NULL
834
 
         * be used, not = NULL since no item can be equal to NULL).
835
 
         *
836
 
         * So, return gracefully.
837
 
         */
838
 
        return CMP_DATE_DFLT;
839
 
      }
840
 
      if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
841
 
      {
842
 
        /* Chuck an error. Bad datetime input. */
843
 
        my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
844
 
        return CMP_DATE_DFLT; /* :( What else can I return... */
845
 
      }
846
 
 
847
 
      /* String conversion was good.  Convert to an integer for comparison purposes. */
848
 
      int64_t int_value;
849
 
      temporal.to_int64_t(&int_value);
850
 
      value= (uint64_t) int_value;
851
 
 
 
764
      if (str_arg->null_value)
 
765
        return CMP_DATE_DFLT;
 
766
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
767
      if (error)
 
768
        return CMP_DATE_DFLT;
852
769
      if (const_value)
853
770
        *const_value= value;
854
771
    }
857
774
}
858
775
 
859
776
 
 
777
/*
 
778
  Retrieves correct TIME value from the given item.
 
779
 
 
780
  SYNOPSIS
 
781
    get_time_value()
 
782
    thd                 thread handle
 
783
    item_arg   [in/out] item to retrieve TIME value from
 
784
    cache_arg  [in/out] pointer to place to store the cache item to
 
785
    warn_item  [in]     unused
 
786
    is_null    [out]    true <=> the item_arg is null
 
787
 
 
788
  DESCRIPTION
 
789
    Retrieves the correct TIME value from given item for comparison by the
 
790
    compare_datetime() function.
 
791
    If item's result can be compared as int64_t then its int value is used
 
792
    and a value returned by get_time function is used otherwise.
 
793
    If an item is a constant one then its value is cached and it isn't
 
794
    get parsed again. An Item_cache_int object is used for for cached values.
 
795
    It seamlessly substitutes the original item.  The cache item is marked as
 
796
    non-constant to prevent re-caching it again.
 
797
 
 
798
  RETURN
 
799
    obtained value
 
800
*/
 
801
 
 
802
uint64_t
 
803
get_time_value(THD *thd __attribute__((__unused__)),
 
804
               Item ***item_arg, Item **cache_arg,
 
805
               Item *warn_item __attribute__((__unused__)),
 
806
               bool *is_null)
 
807
{
 
808
  uint64_t value;
 
809
  Item *item= **item_arg;
 
810
  MYSQL_TIME ltime;
 
811
 
 
812
  if (item->result_as_int64_t())
 
813
  {
 
814
    value= item->val_int();
 
815
    *is_null= item->null_value;
 
816
  }
 
817
  else
 
818
  {
 
819
    *is_null= item->get_time(&ltime);
 
820
    value= !*is_null ? TIME_to_uint64_t_datetime(&ltime) : 0;
 
821
  }
 
822
  /*
 
823
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
824
    for the current thread but it still may change during the execution.
 
825
  */
 
826
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
827
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
828
  {
 
829
    Item_cache_int *cache= new Item_cache_int();
 
830
    /* Mark the cache as non-const to prevent re-caching. */
 
831
    cache->set_used_tables(1);
 
832
    cache->store(item, value);
 
833
    *cache_arg= cache;
 
834
    *item_arg= cache_arg;
 
835
  }
 
836
  return value;
 
837
}
 
838
 
 
839
 
860
840
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
861
841
                                        Item **a1, Item **a2,
862
842
                                        Item_result type)
868
848
 
869
849
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
870
850
  {
871
 
    session= current_session;
 
851
    thd= current_thd;
872
852
    owner= owner_arg;
873
853
    a_type= (*a)->field_type();
874
854
    b_type= (*b)->field_type();
898
878
    get_value_func= &get_datetime_value;
899
879
    return 0;
900
880
  }
 
881
  else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
 
882
           (*b)->field_type() == MYSQL_TYPE_TIME)
 
883
  {
 
884
    /* Compare TIME values as integers. */
 
885
    thd= current_thd;
 
886
    owner= owner_arg;
 
887
    a_cache= 0;
 
888
    b_cache= 0;
 
889
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
 
890
    func= &Arg_comparator::compare_datetime;
 
891
    get_value_func= &get_time_value;
 
892
    return 0;
 
893
  }
901
894
 
902
895
  return set_compare_func(owner_arg, type);
903
896
}
905
898
 
906
899
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
907
900
{
908
 
  session= current_session;
 
901
  thd= current_thd;
909
902
  /* A caller will handle null values by itself. */
910
903
  owner= NULL;
911
904
  a= a1;
925
918
 
926
919
  SYNOPSIS
927
920
    get_datetime_value()
928
 
    session                 thread handle
 
921
    thd                 thread handle
929
922
    item_arg   [in/out] item to retrieve DATETIME value from
930
923
    cache_arg  [in/out] pointer to place to store the caching item to
931
924
    warn_item  [in]     item for issuing the conversion warning
950
943
*/
951
944
 
952
945
uint64_t
953
 
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
 
946
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
954
947
                   Item *warn_item, bool *is_null)
955
948
{
956
949
  uint64_t value= 0;
963
956
    *is_null= item->null_value;
964
957
    enum_field_types f_type= item->field_type();
965
958
    /*
966
 
      Item_date_add_interval may return DRIZZLE_TYPE_STRING as the result
 
959
      Item_date_add_interval may return MYSQL_TYPE_STRING as the result
967
960
      field type. To detect that the DATE value has been returned we
968
961
      compare it with 100000000L - any DATE value should be less than it.
969
962
      Don't shift cached DATETIME values up for the second time.
970
963
    */
971
 
    if (f_type == DRIZZLE_TYPE_DATE ||
972
 
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
 
964
    if (f_type == MYSQL_TYPE_NEWDATE ||
 
965
        (f_type != MYSQL_TYPE_DATETIME && value < 100000000L))
973
966
      value*= 1000000L;
974
967
  }
975
968
  else
989
982
  {
990
983
    bool error;
991
984
    enum_field_types f_type= warn_item->field_type();
992
 
    enum enum_drizzle_timestamp_type t_type= f_type ==
993
 
      DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
994
 
    value= get_date_from_str(session, str, t_type, warn_item->name, &error);
 
985
    timestamp_type t_type= f_type ==
 
986
      MYSQL_TYPE_NEWDATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
 
987
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
995
988
    /*
996
989
      If str did not contain a valid date according to the current
997
990
      SQL_MODE, get_date_from_str() has already thrown a warning,
1006
999
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
1007
1000
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
1008
1001
  {
1009
 
    Item_cache_int *cache= new Item_cache_int(DRIZZLE_TYPE_DATETIME);
 
1002
    Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
1010
1003
    /* Mark the cache as non-const to prevent re-caching. */
1011
1004
    cache->set_used_tables(1);
1012
1005
    cache->store(item, value);
1043
1036
  uint64_t a_value, b_value;
1044
1037
 
1045
1038
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1046
 
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
 
1039
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
1047
1040
  if (!is_nulls_eq && is_null)
1048
1041
  {
1049
1042
    if (owner)
1052
1045
  }
1053
1046
 
1054
1047
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1055
 
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
 
1048
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
1056
1049
  if (is_null)
1057
1050
  {
1058
1051
    if (owner)
1066
1059
  /* Compare values. */
1067
1060
  if (is_nulls_eq)
1068
1061
    return (a_value == b_value);
1069
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1062
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1070
1063
}
1071
1064
 
1072
1065
 
1105
1098
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
1106
1099
    {
1107
1100
      owner->null_value= 0;
1108
 
      uint32_t res1_length= res1->length();
1109
 
      uint32_t res2_length= res2->length();
 
1101
      uint res1_length= res1->length();
 
1102
      uint res2_length= res2->length();
1110
1103
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1111
1104
      return cmp ? cmp : (int) (res1_length - res2_length);
1112
1105
    }
1363
1356
  bool was_null= 0;
1364
1357
  (*a)->bring_value();
1365
1358
  (*b)->bring_value();
1366
 
  uint32_t n= (*a)->cols();
1367
 
  for (uint32_t i= 0; i<n; i++)
 
1359
  uint n= (*a)->cols();
 
1360
  for (uint i= 0; i<n; i++)
1368
1361
  {
1369
1362
    res= comparators[i].compare();
1370
1363
    if (owner->null_value)
1406
1399
{
1407
1400
  (*a)->bring_value();
1408
1401
  (*b)->bring_value();
1409
 
  uint32_t n= (*a)->cols();
1410
 
  for (uint32_t i= 0; i<n; i++)
 
1402
  uint n= (*a)->cols();
 
1403
  for (uint i= 0; i<n; i++)
1411
1404
  {
1412
1405
    if (!comparators[i].compare())
1413
1406
      return 0;
1469
1462
}
1470
1463
 
1471
1464
 
1472
 
bool Item_in_optimizer::fix_left(Session *session, Item **)
 
1465
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((__unused__)))
1473
1466
{
1474
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1467
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1475
1468
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1476
1469
    return 1;
1477
1470
 
1485
1478
  }
1486
1479
  else
1487
1480
  {
1488
 
    uint32_t n= cache->cols();
1489
 
    for (uint32_t i= 0; i < n; i++)
 
1481
    uint n= cache->cols();
 
1482
    for (uint i= 0; i < n; i++)
1490
1483
    {
1491
1484
      if (args[0]->element_index(i)->used_tables())
1492
1485
        ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1503
1496
}
1504
1497
 
1505
1498
 
1506
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1499
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1507
1500
{
1508
1501
  assert(fixed == 0);
1509
 
  if (fix_left(session, ref))
 
1502
  if (fix_left(thd, ref))
1510
1503
    return true;
1511
1504
  if (args[0]->maybe_null)
1512
1505
    maybe_null=1;
1513
1506
 
1514
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1507
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1515
1508
    return true;
1516
1509
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1517
1510
  if (args[0]->cols() != sub->engine->cols())
1535
1528
  bool tmp;
1536
1529
  assert(fixed == 1);
1537
1530
  cache->store(args[0]);
1538
 
 
 
1531
  
1539
1532
  if (cache->null_value)
1540
1533
  {
1541
1534
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1563
1556
          We disable the predicates we've pushed down into subselect, run the
1564
1557
          subselect and see if it has produced any rows.
1565
1558
        */
1566
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
 
1559
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1567
1560
        if (cache->cols() == 1)
1568
1561
        {
1569
1562
          item_subs->set_cond_guard_var(0, false);
1573
1566
        }
1574
1567
        else
1575
1568
        {
1576
 
          uint32_t i;
1577
 
          uint32_t ncols= cache->cols();
 
1569
          uint i;
 
1570
          uint ncols= cache->cols();
1578
1571
          /*
1579
1572
            Turn off the predicates that are based on column compares for
1580
1573
            which the left part is currently NULL
1584
1577
            if (cache->element_index(i)->null_value)
1585
1578
              item_subs->set_cond_guard_var(i, false);
1586
1579
          }
1587
 
 
 
1580
          
1588
1581
          (void) args[1]->val_bool_result();
1589
1582
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1590
 
 
 
1583
          
1591
1584
          /* Turn all predicates back on */
1592
1585
          for (i= 0; i < ncols; i++)
1593
1586
            item_subs->set_cond_guard_var(i, true);
1647
1640
    @retval NULL if an error occurred
1648
1641
*/
1649
1642
 
1650
 
Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
 
1643
Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
1651
1644
{
1652
1645
  Item *new_item;
1653
1646
 
1658
1651
  if (!new_item)
1659
1652
    return 0;
1660
1653
  /*
1661
 
    Session::change_item_tree() should be called only if the tree was
 
1654
    THD::change_item_tree() should be called only if the tree was
1662
1655
    really transformed, i.e. when a new item has been created.
1663
1656
    Otherwise we'll be allocating a lot of unnecessary memory for
1664
1657
    change records at each execution.
1665
1658
  */
1666
1659
  if ((*args) != new_item)
1667
 
    current_session->change_item_tree(args, new_item);
 
1660
    current_thd->change_item_tree(args, new_item);
1668
1661
 
1669
1662
  /*
1670
1663
    Transform the right IN operand which should be an Item_in_subselect or a
1779
1772
    return 0;
1780
1773
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
1781
1774
    return 0;
1782
 
  for (uint32_t i=0; i < arg_count ; i++)
 
1775
  for (uint i=0; i < arg_count ; i++)
1783
1776
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
1784
1777
      return 0;
1785
1778
  return 1;
1788
1781
 
1789
1782
void Item_func_interval::fix_length_and_dec()
1790
1783
{
1791
 
  uint32_t rows= row->cols();
1792
 
 
 
1784
  uint rows= row->cols();
 
1785
  
1793
1786
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1794
1787
                            DECIMAL_RESULT) ||
1795
1788
                           (row->element_index(0)->result_type() ==
1798
1791
  {
1799
1792
    bool not_null_consts= true;
1800
1793
 
1801
 
    for (uint32_t i= 1; not_null_consts && i < rows; i++)
 
1794
    for (uint i= 1; not_null_consts && i < rows; i++)
1802
1795
    {
1803
1796
      Item *el= row->element_index(i);
1804
1797
      not_null_consts&= el->const_item() & !el->is_null();
1806
1799
 
1807
1800
    if (not_null_consts &&
1808
1801
        (intervals=
1809
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1802
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1810
1803
    {
1811
1804
      if (use_decimal_comparison)
1812
1805
      {
1813
 
        for (uint32_t i= 1; i < rows; i++)
 
1806
        for (uint i= 1; i < rows; i++)
1814
1807
        {
1815
1808
          Item *el= row->element_index(i);
1816
1809
          interval_range *range= intervals + (i-1);
1835
1828
      }
1836
1829
      else
1837
1830
      {
1838
 
        for (uint32_t i= 1; i < rows; i++)
 
1831
        for (uint i= 1; i < rows; i++)
1839
1832
        {
1840
1833
          intervals[i-1].dbl= row->element_index(i)->val_real();
1841
1834
        }
1870
1863
  assert(fixed == 1);
1871
1864
  double value;
1872
1865
  my_decimal dec_buf, *dec= NULL;
1873
 
  uint32_t i;
 
1866
  uint i;
1874
1867
 
1875
1868
  if (use_decimal_comparison)
1876
1869
  {
1888
1881
 
1889
1882
  if (intervals)
1890
1883
  {                                     // Use binary search to find interval
1891
 
    uint32_t start,end;
 
1884
    uint start,end;
1892
1885
    start= 0;
1893
1886
    end=   row->cols()-2;
1894
1887
    while (start != end)
1895
1888
    {
1896
 
      uint32_t mid= (start + end + 1) / 2;
 
1889
      uint mid= (start + end + 1) / 2;
1897
1890
      interval_range *range= intervals + mid;
1898
 
      bool cmp_result;
 
1891
      my_bool cmp_result;
1899
1892
      /*
1900
1893
        The values in the range intervall may have different types,
1901
1894
        Only do a decimal comparision of the first argument is a decimal
1930
1923
      if (my_decimal_cmp(e_dec, dec) > 0)
1931
1924
        return i - 1;
1932
1925
    }
1933
 
    else
 
1926
    else 
1934
1927
    {
1935
1928
      double val= el->val_real();
1936
1929
      /* Skip NULL ranges. */
1952
1945
    The function saves in ref the pointer to the item or to a newly created
1953
1946
    item that is considered as a replacement for the original one.
1954
1947
 
1955
 
  @param session     reference to the global context of the query thread
 
1948
  @param thd     reference to the global context of the query thread
1956
1949
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1957
1950
                 item is to be assigned
1958
1951
 
1972
1965
    1   got error
1973
1966
*/
1974
1967
 
1975
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1968
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1976
1969
{
1977
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1970
  if (Item_func_opt_neg::fix_fields(thd, ref))
1978
1971
    return 1;
1979
1972
 
1980
 
  session->lex->current_select->between_count++;
 
1973
  thd->lex->current_select->between_count++;
1981
1974
 
1982
1975
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1983
1976
  if (pred_level && !negated)
1997
1990
  max_length= 1;
1998
1991
  int i;
1999
1992
  bool datetime_found= false;
 
1993
  int time_items_found= 0;
2000
1994
  compare_as_dates= true;
2001
 
  Session *session= current_session;
 
1995
  THD *thd= current_thd;
2002
1996
 
2003
1997
  /*
2004
1998
    As some compare functions are generated after sql_yacc,
2026
2020
        datetime_found= true;
2027
2021
        continue;
2028
2022
      }
 
2023
      if (args[i]->field_type() == MYSQL_TYPE_TIME &&
 
2024
          args[i]->result_as_int64_t())
 
2025
        time_items_found++;
2029
2026
    }
2030
2027
  }
2031
2028
  if (!datetime_found)
2036
2033
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2037
2034
    le_cmp.set_datetime_cmp_func(args, args + 2);
2038
2035
  }
2039
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2036
  else if (time_items_found == 3)
 
2037
  {
 
2038
    /* Compare TIME items as integers. */
 
2039
    cmp_type= INT_RESULT;
 
2040
  }
 
2041
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2042
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2040
2043
  {
2041
2044
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2042
2045
    if (field_item->field->can_be_compared_as_int64_t())
2045
2048
        The following can't be recoded with || as convert_constant_item
2046
2049
        changes the argument
2047
2050
      */
2048
 
      if (convert_constant_item(session, field_item, &args[1]))
 
2051
      if (convert_constant_item(thd, field_item, &args[1]))
2049
2052
        cmp_type=INT_RESULT;                    // Works for all types.
2050
 
      if (convert_constant_item(session, field_item, &args[2]))
 
2053
      if (convert_constant_item(thd, field_item, &args[2]))
2051
2054
        cmp_type=INT_RESULT;                    // Works for all types.
2052
2055
    }
2053
2056
  }
2106
2109
  {
2107
2110
    int64_t value=args[0]->val_int(), a, b;
2108
2111
    if ((null_value=args[0]->null_value))
2109
 
      return 0;
 
2112
      return 0;                                 /* purecov: inspected */
2110
2113
    a=args[1]->val_int();
2111
2114
    b=args[2]->val_int();
2112
2115
    if (!args[1]->null_value && !args[2]->null_value)
2127
2130
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2128
2131
               a_buf, *a_dec, b_buf, *b_dec;
2129
2132
    if ((null_value=args[0]->null_value))
2130
 
      return 0;
 
2133
      return 0;                                 /* purecov: inspected */
2131
2134
    a_dec= args[1]->val_decimal(&a_buf);
2132
2135
    b_dec= args[2]->val_decimal(&b_buf);
2133
2136
    if (!args[1]->null_value && !args[2]->null_value)
2144
2147
  {
2145
2148
    double value= args[0]->val_real(),a,b;
2146
2149
    if ((null_value=args[0]->null_value))
2147
 
      return 0;
 
2150
      return 0;                                 /* purecov: inspected */
2148
2151
    a= args[1]->val_real();
2149
2152
    b= args[2]->val_real();
2150
2153
    if (!args[1]->null_value && !args[2]->null_value)
2181
2184
Item_func_ifnull::fix_length_and_dec()
2182
2185
{
2183
2186
  agg_result_type(&hybrid_type, args, 2);
2184
 
  maybe_null= args[1]->maybe_null;
 
2187
  maybe_null=args[1]->maybe_null;
2185
2188
  decimals= max(args[0]->decimals, args[1]->decimals);
2186
2189
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2187
2190
 
2188
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
 
2191
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2189
2192
  {
2190
2193
    int len0= args[0]->max_length - args[0]->decimals
2191
2194
      - (args[0]->unsigned_flag ? 0 : 1);
2196
2199
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2200
  }
2198
2201
  else
2199
 
  {
2200
2202
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
2202
2203
 
2203
 
  switch (hybrid_type)
2204
 
  {
 
2204
  switch (hybrid_type) {
2205
2205
  case STRING_RESULT:
2206
2206
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2207
    break;
2208
 
 
2209
2208
  case DECIMAL_RESULT:
2210
2209
  case REAL_RESULT:
2211
2210
    break;
2212
 
 
2213
2211
  case INT_RESULT:
2214
2212
    decimals= 0;
2215
2213
    break;
2216
 
 
2217
2214
  case ROW_RESULT:
 
2215
  default:
2218
2216
    assert(0);
2219
2217
  }
2220
 
 
2221
2218
  cached_field_type= agg_field_type(args, 2);
2222
2219
}
2223
2220
 
2224
2221
 
2225
 
uint32_t Item_func_ifnull::decimal_precision() const
 
2222
uint Item_func_ifnull::decimal_precision() const
2226
2223
{
2227
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2224
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2228
2225
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2229
2226
}
2230
2227
 
2231
2228
 
2232
 
enum_field_types Item_func_ifnull::field_type() const
 
2229
enum_field_types Item_func_ifnull::field_type() const 
2233
2230
{
2234
2231
  return cached_field_type;
2235
2232
}
2236
2233
 
2237
 
Field *Item_func_ifnull::tmp_table_field(Table *table)
 
2234
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2238
2235
{
2239
2236
  return tmp_table_field_from_field_type(table, 0);
2240
2237
}
2315
2312
    The function saves in ref the pointer to the item or to a newly created
2316
2313
    item that is considered as a replacement for the original one.
2317
2314
 
2318
 
  @param session     reference to the global context of the query thread
 
2315
  @param thd     reference to the global context of the query thread
2319
2316
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2320
2317
                 item is to be assigned
2321
2318
 
2334
2331
*/
2335
2332
 
2336
2333
bool
2337
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2334
Item_func_if::fix_fields(THD *thd, Item **ref)
2338
2335
{
2339
2336
  assert(fixed == 0);
2340
2337
  args[0]->top_level_item();
2341
2338
 
2342
 
  if (Item_func::fix_fields(session, ref))
 
2339
  if (Item_func::fix_fields(thd, ref))
2343
2340
    return 1;
2344
2341
 
2345
2342
  not_null_tables_cache= (args[1]->not_null_tables() &
2352
2349
void
2353
2350
Item_func_if::fix_length_and_dec()
2354
2351
{
2355
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
 
2352
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2356
2353
  decimals= max(args[1]->decimals, args[2]->decimals);
2357
 
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2354
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2358
2355
 
2359
 
  enum Item_result arg1_type= args[1]->result_type();
2360
 
  enum Item_result arg2_type= args[2]->result_type();
2361
 
  bool null1= args[1]->const_item() && args[1]->null_value;
2362
 
  bool null2= args[2]->const_item() && args[2]->null_value;
 
2356
  enum Item_result arg1_type=args[1]->result_type();
 
2357
  enum Item_result arg2_type=args[2]->result_type();
 
2358
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2359
  bool null2=args[2]->const_item() && args[2]->null_value;
2363
2360
 
2364
2361
  if (null1)
2365
2362
  {
2397
2394
    int len2= args[2]->max_length - args[2]->decimals
2398
2395
      - (args[2]->unsigned_flag ? 0 : 1);
2399
2396
 
2400
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2397
    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2401
2398
  }
2402
2399
  else
2403
2400
    max_length= max(args[1]->max_length, args[2]->max_length);
2404
2401
}
2405
2402
 
2406
2403
 
2407
 
uint32_t Item_func_if::decimal_precision() const
 
2404
uint Item_func_if::decimal_precision() const
2408
2405
{
2409
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2410
 
                  decimals);
 
2406
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2407
                 decimals);
2411
2408
  return min(precision, DECIMAL_MAX_PRECISION);
2412
2409
}
2413
2410
 
2549
2546
bool
2550
2547
Item_func_nullif::is_null()
2551
2548
{
2552
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
 
2549
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2553
2550
}
2554
2551
 
2555
2552
 
2574
2571
           failed
2575
2572
*/
2576
2573
 
2577
 
Item *Item_func_case::find_item(String *)
 
2574
Item *Item_func_case::find_item(String *str __attribute__((__unused__)))
2578
2575
{
2579
 
  uint32_t value_added_map= 0;
 
2576
  uint value_added_map= 0;
2580
2577
 
2581
2578
  if (first_expr_num == -1)
2582
2579
  {
2583
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2580
    for (uint i=0 ; i < ncases ; i+=2)
2584
2581
    {
2585
2582
      // No expression between CASE and the first WHEN
2586
2583
      if (args[i]->val_bool())
2591
2588
  else
2592
2589
  {
2593
2590
    /* Compare every WHEN argument with it and return the first match */
2594
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2591
    for (uint i=0 ; i < ncases ; i+=2)
2595
2592
    {
2596
2593
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2597
2594
      assert(cmp_type != ROW_RESULT);
2598
 
      assert(cmp_items[(uint32_t)cmp_type]);
2599
 
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
 
2595
      assert(cmp_items[(uint)cmp_type]);
 
2596
      if (!(value_added_map & (1<<(uint)cmp_type)))
2600
2597
      {
2601
 
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
 
2598
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2602
2599
        if ((null_value=args[first_expr_num]->null_value))
2603
2600
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2604
 
        value_added_map|= 1<<(uint32_t)cmp_type;
 
2601
        value_added_map|= 1<<(uint)cmp_type;
2605
2602
      }
2606
 
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2603
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2607
2604
        return args[i + 1];
2608
2605
    }
2609
2606
  }
2687
2684
}
2688
2685
 
2689
2686
 
2690
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2687
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2691
2688
{
2692
2689
  /*
2693
2690
    buff should match stack usage from
2694
2691
    Item_func_case::val_int() -> Item_func_case::find_item()
2695
2692
  */
2696
 
  unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2697
 
                     +sizeof(double)*2+sizeof(int64_t)*2];
2698
 
  bool res= Item_func::fix_fields(session, ref);
 
2693
  uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
 
2694
  bool res= Item_func::fix_fields(thd, ref);
2699
2695
  /*
2700
2696
    Call check_stack_overrun after fix_fields to be sure that stack variable
2701
2697
    is not optimized away
2702
2698
  */
2703
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2699
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2704
2700
    return true;                                // Fatal error flag is set!
2705
2701
  return res;
2706
2702
}
2716
2712
 
2717
2713
void Item_func_case::agg_num_lengths(Item *arg)
2718
2714
{
2719
 
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2715
  uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2720
2716
                                           arg->unsigned_flag) - arg->decimals;
2721
 
  set_if_bigger(max_length, len);
 
2717
  set_if_bigger(max_length, len); 
2722
2718
  set_if_bigger(decimals, arg->decimals);
2723
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
 
2719
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
2724
2720
}
2725
2721
 
2726
2722
 
2727
2723
void Item_func_case::fix_length_and_dec()
2728
2724
{
2729
2725
  Item **agg;
2730
 
  uint32_t nagg;
2731
 
  uint32_t found_types= 0;
2732
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2726
  uint nagg;
 
2727
  uint found_types= 0;
 
2728
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2733
2729
    return;
2734
 
 
 
2730
  
2735
2731
  /*
2736
2732
    Aggregate all THEN and ELSE expression types
2737
2733
    and collations when string result
2738
2734
  */
2739
 
 
 
2735
  
2740
2736
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2741
2737
    agg[nagg]= args[nagg*2+1];
2742
 
 
 
2738
  
2743
2739
  if (else_expr_num != -1)
2744
2740
    agg[nagg++]= args[else_expr_num];
2745
 
 
 
2741
  
2746
2742
  agg_result_type(&cached_result_type, agg, nagg);
2747
2743
  if ((cached_result_type == STRING_RESULT) &&
2748
2744
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2749
2745
    return;
2750
 
 
 
2746
  
2751
2747
  cached_field_type= agg_field_type(agg, nagg);
2752
2748
  /*
2753
2749
    Aggregate first expression and all THEN expression types
2755
2751
  */
2756
2752
  if (first_expr_num != -1)
2757
2753
  {
 
2754
    uint i;
2758
2755
    agg[0]= args[first_expr_num];
2759
2756
    left_result_type= agg[0]->result_type();
2760
2757
 
2764
2761
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2762
      return;
2766
2763
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2764
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2768
2765
    {
2769
2766
      if (found_types & (1 << i) && !cmp_items[i])
2770
2767
      {
2782
2779
 
2783
2780
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2784
2781
    maybe_null=1;
2785
 
 
 
2782
  
2786
2783
  max_length=0;
2787
2784
  decimals=0;
2788
2785
  unsigned_flag= true;
2789
2786
  if (cached_result_type == STRING_RESULT)
2790
2787
  {
2791
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2788
    for (uint i= 0; i < ncases; i+= 2)
2792
2789
      agg_str_lengths(args[i + 1]);
2793
2790
    if (else_expr_num != -1)
2794
2791
      agg_str_lengths(args[else_expr_num]);
2795
2792
  }
2796
2793
  else
2797
2794
  {
2798
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2795
    for (uint i= 0; i < ncases; i+= 2)
2799
2796
      agg_num_lengths(args[i + 1]);
2800
 
    if (else_expr_num != -1)
 
2797
    if (else_expr_num != -1) 
2801
2798
      agg_num_lengths(args[else_expr_num]);
2802
2799
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2803
2800
                                               unsigned_flag);
2805
2802
}
2806
2803
 
2807
2804
 
2808
 
uint32_t Item_func_case::decimal_precision() const
 
2805
uint Item_func_case::decimal_precision() const
2809
2806
{
2810
2807
  int max_int_part=0;
2811
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2808
  for (uint i=0 ; i < ncases ; i+=2)
2812
2809
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2813
2810
 
2814
 
  if (else_expr_num != -1)
 
2811
  if (else_expr_num != -1) 
2815
2812
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2816
2813
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2817
2814
}
2830
2827
    args[first_expr_num]->print(str, query_type);
2831
2828
    str->append(' ');
2832
2829
  }
2833
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2830
  for (uint i=0 ; i < ncases ; i+=2)
2834
2831
  {
2835
2832
    str->append(STRING_WITH_LEN("when "));
2836
2833
    args[i]->print(str, query_type);
2850
2847
 
2851
2848
void Item_func_case::cleanup()
2852
2849
{
 
2850
  uint i;
2853
2851
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2852
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2855
2853
  {
2856
2854
    delete cmp_items[i];
2857
2855
    cmp_items[i]= 0;
2858
2856
  }
 
2857
  return;
2859
2858
}
2860
2859
 
2861
2860
 
2867
2866
{
2868
2867
  assert(fixed == 1);
2869
2868
  null_value=0;
2870
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2869
  for (uint i=0 ; i < arg_count ; i++)
2871
2870
  {
2872
2871
    String *res;
2873
2872
    if ((res=args[i]->val_str(str)))
2881
2880
{
2882
2881
  assert(fixed == 1);
2883
2882
  null_value=0;
2884
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2883
  for (uint i=0 ; i < arg_count ; i++)
2885
2884
  {
2886
2885
    int64_t res=args[i]->val_int();
2887
2886
    if (!args[i]->null_value)
2895
2894
{
2896
2895
  assert(fixed == 1);
2897
2896
  null_value=0;
2898
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2897
  for (uint i=0 ; i < arg_count ; i++)
2899
2898
  {
2900
2899
    double res= args[i]->val_real();
2901
2900
    if (!args[i]->null_value)
2910
2909
{
2911
2910
  assert(fixed == 1);
2912
2911
  null_value= 0;
2913
 
  for (uint32_t i= 0; i < arg_count; i++)
 
2912
  for (uint i= 0; i < arg_count; i++)
2914
2913
  {
2915
2914
    my_decimal *res= args[i]->val_decimal(decimal_value);
2916
2915
    if (!args[i]->null_value)
2925
2924
{
2926
2925
  cached_field_type= agg_field_type(args, arg_count);
2927
2926
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2927
  switch (hybrid_type) {
2930
2928
  case STRING_RESULT:
2931
2929
    count_only_length();
2932
2930
    decimals= NOT_FIXED_DEC;
2933
2931
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2932
    break;
2935
 
 
2936
2933
  case DECIMAL_RESULT:
2937
2934
    count_decimal_length();
2938
2935
    break;
2939
 
 
2940
2936
  case REAL_RESULT:
2941
2937
    count_real_length();
2942
2938
    break;
2943
 
 
2944
2939
  case INT_RESULT:
2945
2940
    count_only_length();
2946
2941
    decimals= 0;
2947
2942
    break;
2948
 
 
2949
2943
  case ROW_RESULT:
 
2944
  default:
2950
2945
    assert(0);
2951
2946
  }
2952
2947
}
3004
2999
 
3005
3000
 
3006
3001
/*
3007
 
  Compare two integers in IN value list format (packed_int64_t)
 
3002
  Compare two integers in IN value list format (packed_int64_t) 
3008
3003
 
3009
3004
  SYNOPSIS
3010
3005
    cmp_int64_t()
3026
3021
    0           left argument is equal to the right argument.
3027
3022
    1           left argument is greater than the right argument.
3028
3023
*/
3029
 
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3030
 
                in_int64_t::packed_int64_t *b)
 
3024
int cmp_int64_t(void *cmp_arg __attribute__((__unused__)),
 
3025
                 in_int64_t::packed_int64_t *a,
 
3026
                 in_int64_t::packed_int64_t *b)
3031
3027
{
3032
3028
  if (a->unsigned_flag != b->unsigned_flag)
3033
 
  {
3034
 
    /*
3035
 
      One of the args is unsigned and is too big to fit into the
 
3029
  { 
 
3030
    /* 
 
3031
      One of the args is unsigned and is too big to fit into the 
3036
3032
      positive signed range. Report no match.
3037
 
    */
 
3033
    */  
3038
3034
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3039
3035
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3040
3036
      return a->unsigned_flag ? 1 : -1;
3041
3037
    /*
3042
 
      Although the signedness differs both args can fit into the signed
 
3038
      Although the signedness differs both args can fit into the signed 
3043
3039
      positive range. Make them signed and compare as usual.
3044
 
    */
 
3040
    */  
3045
3041
    return cmp_longs (a->val, b->val);
3046
3042
  }
3047
3043
  if (a->unsigned_flag)
3050
3046
    return cmp_longs (a->val, b->val);
3051
3047
}
3052
3048
 
3053
 
static int cmp_double(void *, double *a, double *b)
 
3049
static int cmp_double(void *cmp_arg __attribute__((__unused__)), double *a,double *b)
3054
3050
{
3055
3051
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3056
3052
}
3057
3053
 
3058
 
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
 
3054
static int cmp_row(void *cmp_arg __attribute__((__unused__)), cmp_item_row *a, cmp_item_row *b)
3059
3055
{
3060
3056
  return a->compare(b);
3061
3057
}
3062
3058
 
3063
3059
 
3064
 
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
 
3060
static int cmp_decimal(void *cmp_arg __attribute__((__unused__)), my_decimal *a, my_decimal *b)
3065
3061
{
3066
3062
  /*
3067
3063
    We need call of fixing buffer pointer, because fast sort just copy
3073
3069
}
3074
3070
 
3075
3071
 
3076
 
void in_vector::sort()
3077
 
{
3078
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
3079
 
}
3080
 
 
3081
 
 
3082
3072
int in_vector::find(Item *item)
3083
3073
{
3084
 
  unsigned char *result=get_value(item);
 
3074
  uchar *result=get_value(item);
3085
3075
  if (!result || !used_count)
3086
3076
    return 0;                           // Null value
3087
3077
 
3088
 
  uint32_t start,end;
 
3078
  uint start,end;
3089
3079
  start=0; end=used_count-1;
3090
3080
  while (start != end)
3091
3081
  {
3092
 
    uint32_t mid=(start+end+1)/2;
 
3082
    uint mid=(start+end+1)/2;
3093
3083
    int res;
3094
3084
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3095
3085
      return 1;
3101
3091
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3102
3092
}
3103
3093
 
3104
 
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3094
in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs)
3105
3095
  :in_vector(elements, sizeof(String), cmp_func, cs),
3106
3096
   tmp(buff, sizeof(buff), &my_charset_bin)
3107
3097
{}
3110
3100
{
3111
3101
  if (base)
3112
3102
  {
3113
 
    // base was allocated with help of memory::sql_alloc => following is OK
3114
 
    for (uint32_t i=0 ; i < count ; i++)
 
3103
    // base was allocated with help of sql_alloc => following is OK
 
3104
    for (uint i=0 ; i < count ; i++)
3115
3105
      ((String*) base)[i].free();
3116
3106
  }
3117
3107
}
3118
3108
 
3119
 
void in_string::set(uint32_t pos,Item *item)
 
3109
void in_string::set(uint pos,Item *item)
3120
3110
{
3121
3111
  String *str=((String*) base)+pos;
3122
3112
  String *res=item->val_str(str);
3131
3121
  }
3132
3122
  if (!str->charset())
3133
3123
  {
3134
 
    const CHARSET_INFO *cs;
 
3124
    CHARSET_INFO *cs;
3135
3125
    if (!(cs= item->collation.collation))
3136
3126
      cs= &my_charset_bin;              // Should never happen for STR items
3137
3127
    str->set_charset(cs);
3139
3129
}
3140
3130
 
3141
3131
 
3142
 
unsigned char *in_string::get_value(Item *item)
 
3132
uchar *in_string::get_value(Item *item)
3143
3133
{
3144
 
  return (unsigned char*) item->val_str(&tmp);
 
3134
  return (uchar*) item->val_str(&tmp);
3145
3135
}
3146
3136
 
3147
 
in_row::in_row(uint32_t elements, Item *)
 
3137
in_row::in_row(uint elements, Item * item __attribute__((__unused__)))
3148
3138
{
3149
3139
  base= (char*) new cmp_item_row[count= elements];
3150
3140
  size= sizeof(cmp_item_row);
3163
3153
    delete [] (cmp_item_row*) base;
3164
3154
}
3165
3155
 
3166
 
unsigned char *in_row::get_value(Item *item)
 
3156
uchar *in_row::get_value(Item *item)
3167
3157
{
3168
3158
  tmp.store_value(item);
3169
3159
  if (item->is_null())
3170
3160
    return 0;
3171
 
  return (unsigned char *)&tmp;
 
3161
  return (uchar *)&tmp;
3172
3162
}
3173
3163
 
3174
 
void in_row::set(uint32_t pos, Item *item)
 
3164
void in_row::set(uint pos, Item *item)
3175
3165
{
3176
3166
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3177
3167
  return;
3178
3168
}
3179
3169
 
3180
 
in_int64_t::in_int64_t(uint32_t elements)
 
3170
in_int64_t::in_int64_t(uint elements)
3181
3171
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3182
3172
{}
3183
3173
 
3184
 
void in_int64_t::set(uint32_t pos,Item *item)
 
3174
void in_int64_t::set(uint pos,Item *item)
3185
3175
{
3186
3176
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3187
 
 
 
3177
  
3188
3178
  buff->val= item->val_int();
3189
3179
  buff->unsigned_flag= item->unsigned_flag;
3190
3180
}
3191
3181
 
3192
 
unsigned char *in_int64_t::get_value(Item *item)
 
3182
uchar *in_int64_t::get_value(Item *item)
3193
3183
{
3194
3184
  tmp.val= item->val_int();
3195
3185
  if (item->null_value)
3196
3186
    return 0;
3197
3187
  tmp.unsigned_flag= item->unsigned_flag;
3198
 
  return (unsigned char*) &tmp;
 
3188
  return (uchar*) &tmp;
3199
3189
}
3200
3190
 
3201
 
void in_datetime::set(uint32_t pos,Item *item)
 
3191
void in_datetime::set(uint pos,Item *item)
3202
3192
{
3203
3193
  Item **tmp_item= &item;
3204
3194
  bool is_null;
3205
3195
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3206
3196
 
3207
 
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3197
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3208
3198
  buff->unsigned_flag= 1L;
3209
3199
}
3210
3200
 
3211
 
unsigned char *in_datetime::get_value(Item *item)
 
3201
uchar *in_datetime::get_value(Item *item)
3212
3202
{
3213
3203
  bool is_null;
3214
3204
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3215
 
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3205
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3216
3206
  if (item->null_value)
3217
3207
    return 0;
3218
3208
  tmp.unsigned_flag= 1L;
3219
 
  return (unsigned char*) &tmp;
 
3209
  return (uchar*) &tmp;
3220
3210
}
3221
3211
 
3222
 
in_double::in_double(uint32_t elements)
 
3212
in_double::in_double(uint elements)
3223
3213
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3224
3214
{}
3225
3215
 
3226
 
void in_double::set(uint32_t pos,Item *item)
 
3216
void in_double::set(uint pos,Item *item)
3227
3217
{
3228
3218
  ((double*) base)[pos]= item->val_real();
3229
3219
}
3230
3220
 
3231
 
unsigned char *in_double::get_value(Item *item)
 
3221
uchar *in_double::get_value(Item *item)
3232
3222
{
3233
3223
  tmp= item->val_real();
3234
3224
  if (item->null_value)
3235
 
    return 0;
3236
 
  return (unsigned char*) &tmp;
 
3225
    return 0;                                   /* purecov: inspected */
 
3226
  return (uchar*) &tmp;
3237
3227
}
3238
3228
 
3239
3229
 
3240
 
in_decimal::in_decimal(uint32_t elements)
 
3230
in_decimal::in_decimal(uint elements)
3241
3231
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3242
3232
{}
3243
3233
 
3244
3234
 
3245
 
void in_decimal::set(uint32_t pos, Item *item)
 
3235
void in_decimal::set(uint pos, Item *item)
3246
3236
{
3247
3237
  /* as far as 'item' is constant, we can store reference on my_decimal */
3248
3238
  my_decimal *dec= ((my_decimal *)base) + pos;
3249
3239
  dec->len= DECIMAL_BUFF_LENGTH;
3250
3240
  dec->fix_buffer_pointer();
3251
3241
  my_decimal *res= item->val_decimal(dec);
3252
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
 
3242
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
3253
3243
  if (!item->null_value && res != dec)
3254
3244
    my_decimal2decimal(res, dec);
3255
3245
}
3256
3246
 
3257
3247
 
3258
 
unsigned char *in_decimal::get_value(Item *item)
 
3248
uchar *in_decimal::get_value(Item *item)
3259
3249
{
3260
3250
  my_decimal *result= item->val_decimal(&val);
3261
3251
  if (item->null_value)
3262
3252
    return 0;
3263
 
  return (unsigned char *)result;
 
3253
  return (uchar *)result;
3264
3254
}
3265
3255
 
3266
3256
 
3267
3257
cmp_item* cmp_item::get_comparator(Item_result type,
3268
 
                                   const CHARSET_INFO * const cs)
 
3258
                                   CHARSET_INFO *cs)
3269
3259
{
3270
3260
  switch (type) {
3271
3261
  case STRING_RESULT:
3272
3262
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3263
  case INT_RESULT:
3275
3264
    return new cmp_item_int;
3276
 
 
3277
3265
  case REAL_RESULT:
3278
3266
    return new cmp_item_real;
3279
 
 
3280
3267
  case ROW_RESULT:
3281
3268
    return new cmp_item_row;
3282
 
 
3283
3269
  case DECIMAL_RESULT:
3284
3270
    return new cmp_item_decimal;
 
3271
  default:
 
3272
    assert(0);
 
3273
    break;
3285
3274
  }
3286
 
 
3287
3275
  return 0; // to satisfy compiler :)
3288
3276
}
3289
3277
 
3313
3301
{
3314
3302
  if (comparators)
3315
3303
  {
3316
 
    for (uint32_t i= 0; i < n; i++)
 
3304
    for (uint i= 0; i < n; i++)
3317
3305
    {
3318
3306
      if (comparators[i])
3319
3307
        delete comparators[i];
3326
3314
void cmp_item_row::alloc_comparators()
3327
3315
{
3328
3316
  if (!comparators)
3329
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3317
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3330
3318
}
3331
3319
 
3332
3320
 
3338
3326
  {
3339
3327
    item->bring_value();
3340
3328
    item->null_value= 0;
3341
 
    for (uint32_t i=0; i < n; i++)
 
3329
    for (uint i=0; i < n; i++)
3342
3330
    {
3343
3331
      if (!comparators[i])
3344
3332
        if (!(comparators[i]=
3362
3350
    return;
3363
3351
  }
3364
3352
  n= tmpl->n;
3365
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3353
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3366
3354
  {
3367
3355
    item->bring_value();
3368
3356
    item->null_value= 0;
3369
 
    for (uint32_t i=0; i < n; i++)
 
3357
    for (uint i=0; i < n; i++)
3370
3358
    {
3371
3359
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3372
3360
        break;                                  // new failed
3388
3376
  }
3389
3377
  bool was_null= 0;
3390
3378
  arg->bring_value();
3391
 
  for (uint32_t i=0; i < n; i++)
 
3379
  for (uint i=0; i < n; i++)
3392
3380
  {
3393
3381
    if (comparators[i]->cmp(arg->element_index(i)))
3394
3382
    {
3404
3392
int cmp_item_row::compare(cmp_item *c)
3405
3393
{
3406
3394
  cmp_item_row *l_cmp= (cmp_item_row *) c;
3407
 
  for (uint32_t i=0; i < n; i++)
 
3395
  for (uint i=0; i < n; i++)
3408
3396
  {
3409
3397
    int res;
3410
3398
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3449
3437
{
3450
3438
  bool is_null;
3451
3439
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3452
 
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3440
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3453
3441
}
3454
3442
 
3455
3443
 
3458
3446
  bool is_null;
3459
3447
  Item **tmp_item= &arg;
3460
3448
  return value !=
3461
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3449
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3462
3450
}
3463
3451
 
3464
3452
 
3495
3483
    The function saves in ref the pointer to the item or to a newly created
3496
3484
    item that is considered as a replacement for the original one.
3497
3485
 
3498
 
  @param session     reference to the global context of the query thread
 
3486
  @param thd     reference to the global context of the query thread
3499
3487
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3500
3488
                 item is to be assigned
3501
3489
 
3516
3504
*/
3517
3505
 
3518
3506
bool
3519
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3507
Item_func_in::fix_fields(THD *thd, Item **ref)
3520
3508
{
3521
3509
  Item **arg, **arg_end;
3522
3510
 
3523
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3511
  if (Item_func_opt_neg::fix_fields(thd, ref))
3524
3512
    return 1;
3525
3513
 
3526
3514
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3536
3524
}
3537
3525
 
3538
3526
 
3539
 
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
 
3527
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
3540
3528
{
3541
3529
  return cs->coll->strnncollsp(cs,
3542
 
                               (unsigned char *) x->ptr(),x->length(),
3543
 
                               (unsigned char *) y->ptr(),y->length(), 0);
 
3530
                               (uchar *) x->ptr(),x->length(),
 
3531
                               (uchar *) y->ptr(),y->length(), 0);
3544
3532
}
3545
3533
 
3546
3534
 
3548
3536
{
3549
3537
  Item **arg, **arg_end;
3550
3538
  bool const_itm= 1;
3551
 
  Session *session= current_session;
 
3539
  THD *thd= current_thd;
3552
3540
  bool datetime_found= false;
3553
3541
  /* true <=> arguments values will be compared as DATETIMEs. */
3554
3542
  bool compare_as_datetime= false;
3555
3543
  Item *date_arg= 0;
3556
 
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3544
  uint found_types= 0;
 
3545
  uint type_cnt= 0, i;
3558
3546
  Item_result cmp_type= STRING_RESULT;
3559
3547
  left_result_type= args[0]->result_type();
3560
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3548
  if (!(found_types= collect_cmp_types(args, arg_count)))
3561
3549
    return;
3562
 
 
 
3550
  
3563
3551
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3564
3552
  {
3565
3553
    if (!arg[0]->const_item())
3568
3556
      break;
3569
3557
    }
3570
3558
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3559
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
3572
3560
  {
3573
3561
    if (found_types & 1 << i)
3574
3562
    {
3579
3567
 
3580
3568
  if (type_cnt == 1)
3581
3569
  {
3582
 
    if (cmp_type == STRING_RESULT &&
 
3570
    if (cmp_type == STRING_RESULT && 
3583
3571
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3584
3572
      return;
3585
3573
    arg_types_compatible= true;
3610
3598
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3611
3599
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3612
3600
    {
3613
 
      uint32_t col, num_cols= args[0]->cols();
 
3601
      uint col, cols= args[0]->cols();
3614
3602
 
3615
 
      for (col= 0; col < num_cols; col++)
 
3603
      for (col= 0; col < cols; col++)
3616
3604
      {
3617
3605
        bool skip_column= false;
3618
3606
        /*
3637
3625
            */
3638
3626
            if (!date_arg)
3639
3627
              date_arg= itm;
3640
 
            else if (itm->field_type() == DRIZZLE_TYPE_DATETIME)
 
3628
            else if (itm->field_type() == MYSQL_TYPE_DATETIME)
3641
3629
            {
3642
3630
              date_arg= itm;
3643
3631
              /* All arguments are already checked to have the STRING result. */
3675
3663
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3664
  {
3677
3665
    if (compare_as_datetime)
3678
 
    {
3679
3666
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3667
    else
3682
3668
    {
3683
3669
      /*
3684
3670
        IN must compare INT columns and constants as int values (the same
3685
3671
        way as equality does).
3686
 
        So we must check here if the column on the left and all the constant
3687
 
        values on the right can be compared as integers and adjust the
 
3672
        So we must check here if the column on the left and all the constant 
 
3673
        values on the right can be compared as integers and adjust the 
3688
3674
        comparison type accordingly.
3689
 
      */
 
3675
      */  
3690
3676
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3677
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3678
          cmp_type != INT_RESULT)
3692
3679
      {
3693
3680
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3696
3683
          bool all_converted= true;
3697
3684
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3698
3685
          {
3699
 
            if (!convert_constant_item (session, field_item, &arg[0]))
 
3686
            if (!convert_constant_item (thd, field_item, &arg[0]))
3700
3687
              all_converted= false;
3701
3688
          }
3702
3689
          if (all_converted)
3703
3690
            cmp_type= INT_RESULT;
3704
3691
        }
3705
3692
      }
3706
 
 
3707
3693
      switch (cmp_type) {
3708
3694
      case STRING_RESULT:
3709
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
 
3695
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
3710
3696
                            cmp_collation.collation);
3711
3697
        break;
3712
 
 
3713
3698
      case INT_RESULT:
3714
3699
        array= new in_int64_t(arg_count-1);
3715
3700
        break;
3716
 
 
3717
3701
      case REAL_RESULT:
3718
3702
        array= new in_double(arg_count-1);
3719
3703
        break;
3720
 
 
3721
3704
      case ROW_RESULT:
3722
3705
        /*
3723
3706
          The row comparator was created at the beginning but only DATETIME
3726
3709
        */
3727
3710
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3711
        break;
3729
 
 
3730
3712
      case DECIMAL_RESULT:
3731
3713
        array= new in_decimal(arg_count - 1);
3732
3714
        break;
 
3715
      default:
 
3716
        assert(0);
 
3717
        return;
3733
3718
      }
3734
3719
    }
3735
 
 
3736
 
    if (array && !(session->is_fatal_error))            // If not EOM
 
3720
    if (array && !(thd->is_fatal_error))                // If not EOM
3737
3721
    {
3738
 
      uint32_t j=0;
3739
 
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
 
3722
      uint j=0;
 
3723
      for (uint i=1 ; i < arg_count ; i++)
3740
3724
      {
3741
 
        if (!args[arg_num]->null_value)                 // Skip NULL values
3742
 
        {
3743
 
          array->set(j,args[arg_num]);
3744
 
          j++;
3745
 
        }
3746
 
        else
3747
 
          have_null= 1;
 
3725
        array->set(j,args[i]);
 
3726
        if (!args[i]->null_value)                       // Skip NULL values
 
3727
          j++;
 
3728
        else
 
3729
          have_null= 1;
3748
3730
      }
3749
3731
      if ((array->used_count= j))
3750
 
        array->sort();
 
3732
        array->sort();
3751
3733
    }
3752
3734
  }
3753
3735
  else
3756
3738
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3739
    else
3758
3740
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3741
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
3760
3742
      {
3761
3743
        if (found_types & (1 << i) && !cmp_items[i])
3762
3744
        {
3817
3799
{
3818
3800
  cmp_item *in_item;
3819
3801
  assert(fixed == 1);
3820
 
  uint32_t value_added_map= 0;
 
3802
  uint value_added_map= 0;
3821
3803
  if (array)
3822
3804
  {
3823
3805
    int tmp=array->find(args[0]);
3825
3807
    return (int64_t) (!null_value && tmp != negated);
3826
3808
  }
3827
3809
 
3828
 
  for (uint32_t i= 1 ; i < arg_count ; i++)
 
3810
  for (uint i= 1 ; i < arg_count ; i++)
3829
3811
  {
3830
3812
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3831
 
    in_item= cmp_items[(uint32_t)cmp_type];
 
3813
    in_item= cmp_items[(uint)cmp_type];
3832
3814
    assert(in_item);
3833
 
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
 
3815
    if (!(value_added_map & (1 << (uint)cmp_type)))
3834
3816
    {
3835
3817
      in_item->store_value(args[0]);
3836
3818
      if ((null_value=args[0]->null_value))
3837
3819
        return 0;
3838
3820
      have_null= 0;
3839
 
      value_added_map|= 1 << (uint32_t)cmp_type;
 
3821
      value_added_map|= 1 << (uint)cmp_type;
3840
3822
    }
3841
3823
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3842
3824
      return (int64_t) (!negated);
3848
3830
}
3849
3831
 
3850
3832
 
3851
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
 
  :Item_bool_func(session, item),
 
3833
int64_t Item_func_bit_or::val_int()
 
3834
{
 
3835
  assert(fixed == 1);
 
3836
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3837
  if (args[0]->null_value)
 
3838
  {
 
3839
    null_value=1; /* purecov: inspected */
 
3840
    return 0; /* purecov: inspected */
 
3841
  }
 
3842
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3843
  if (args[1]->null_value)
 
3844
  {
 
3845
    null_value=1;
 
3846
    return 0;
 
3847
  }
 
3848
  null_value=0;
 
3849
  return (int64_t) (arg1 | arg2);
 
3850
}
 
3851
 
 
3852
 
 
3853
int64_t Item_func_bit_and::val_int()
 
3854
{
 
3855
  assert(fixed == 1);
 
3856
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
3857
  if (args[0]->null_value)
 
3858
  {
 
3859
    null_value=1; /* purecov: inspected */
 
3860
    return 0; /* purecov: inspected */
 
3861
  }
 
3862
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
3863
  if (args[1]->null_value)
 
3864
  {
 
3865
    null_value=1; /* purecov: inspected */
 
3866
    return 0; /* purecov: inspected */
 
3867
  }
 
3868
  null_value=0;
 
3869
  return (int64_t) (arg1 & arg2);
 
3870
}
 
3871
 
 
3872
Item_cond::Item_cond(THD *thd, Item_cond *item)
 
3873
  :Item_bool_func(thd, item),
3853
3874
   abort_on_null(item->abort_on_null),
3854
3875
   and_tables_cache(item->and_tables_cache)
3855
3876
{
3859
3880
}
3860
3881
 
3861
3882
 
3862
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3883
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3863
3884
{
3864
3885
  List_iterator_fast<Item> li(item->list);
3865
3886
  while (Item *it= li++)
3866
 
    list.push_back(it->copy_andor_structure(session));
 
3887
    list.push_back(it->copy_andor_structure(thd));
3867
3888
}
3868
3889
 
3869
3890
 
3870
3891
bool
3871
 
Item_cond::fix_fields(Session *session, Item **)
 
3892
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
3872
3893
{
3873
3894
  assert(fixed == 0);
3874
3895
  List_iterator<Item> li(list);
3875
3896
  Item *item;
3876
 
  void *orig_session_marker= session->session_marker;
3877
 
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
 
3897
  void *orig_thd_marker= thd->thd_marker;
 
3898
  uchar buff[sizeof(char*)];                    // Max local vars in function
3878
3899
  not_null_tables_cache= used_tables_cache= 0;
3879
3900
  const_item_cache= 1;
3880
3901
 
3881
3902
  if (functype() == COND_OR_FUNC)
3882
 
    session->session_marker= 0;
 
3903
    thd->thd_marker= 0;
3883
3904
  /*
3884
3905
    and_table_cache is the value that Item_cond_or() returns for
3885
3906
    not_null_tables()
3886
3907
  */
3887
3908
  and_tables_cache= ~(table_map) 0;
3888
3909
 
3889
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3910
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3890
3911
    return true;                                // Fatal error flag is set!
3891
3912
  /*
3892
3913
    The following optimization reduces the depth of an AND-OR tree.
3919
3940
 
3920
3941
    // item can be substituted in fix_fields
3921
3942
    if ((!item->fixed &&
3922
 
         item->fix_fields(session, li.ref())) ||
 
3943
         item->fix_fields(thd, li.ref())) ||
3923
3944
        (item= *li.ref())->check_cols(1))
3924
 
      return true;
 
3945
      return true; /* purecov: inspected */
3925
3946
    used_tables_cache|=     item->used_tables();
3926
3947
    if (item->const_item())
3927
3948
      and_tables_cache= (table_map) 0;
3931
3952
      not_null_tables_cache|= tmp_table_map;
3932
3953
      and_tables_cache&= tmp_table_map;
3933
3954
      const_item_cache= false;
3934
 
    }
 
3955
    }  
3935
3956
    with_sum_func=          with_sum_func || item->with_sum_func;
3936
3957
    with_subselect|=        item->with_subselect;
3937
3958
    if (item->maybe_null)
3938
3959
      maybe_null=1;
3939
3960
  }
3940
 
  session->lex->current_select->cond_count+= list.elements;
3941
 
  session->session_marker= orig_session_marker;
 
3961
  thd->lex->current_select->cond_count+= list.elements;
 
3962
  thd->thd_marker= orig_thd_marker;
3942
3963
  fix_length_and_dec();
3943
3964
  fixed= 1;
3944
3965
  return false;
3945
3966
}
3946
3967
 
3947
3968
 
3948
 
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
 
3969
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((__unused__)))
3949
3970
{
3950
3971
  List_iterator<Item> li(list);
3951
3972
  Item *item;
3972
3993
      not_null_tables_cache|= tmp_table_map;
3973
3994
      and_tables_cache&= tmp_table_map;
3974
3995
      const_item_cache= false;
3975
 
    }
 
3996
    }  
3976
3997
  }
3977
3998
}
3978
3999
 
3979
4000
 
3980
 
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
4001
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
3981
4002
{
3982
4003
  List_iterator_fast<Item> li(list);
3983
4004
  Item *item;
3990
4011
 
3991
4012
/**
3992
4013
  Transform an Item_cond object with a transformer callback function.
3993
 
 
 
4014
  
3994
4015
    The function recursively applies the transform method to each
3995
4016
     member item of the condition list.
3996
4017
    If the call of the method for a member item returns a new item
3997
4018
    the old item is substituted for a new one.
3998
4019
    After this the transformer is applied to the root node
3999
 
    of the Item_cond object.
4000
 
 
 
4020
    of the Item_cond object. 
 
4021
     
4001
4022
  @param transformer   the transformer callback function to be applied to
4002
4023
                       the nodes of the tree of the object
4003
4024
  @param arg           parameter to be passed to the transformer
4004
4025
 
4005
4026
  @return
4006
 
    Item returned as the result of transformation of the root node
 
4027
    Item returned as the result of transformation of the root node 
4007
4028
*/
4008
4029
 
4009
 
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
 
4030
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
4010
4031
{
4011
4032
  List_iterator<Item> li(list);
4012
4033
  Item *item;
4017
4038
      return 0;
4018
4039
 
4019
4040
    /*
4020
 
      Session::change_item_tree() should be called only if the tree was
 
4041
      THD::change_item_tree() should be called only if the tree was
4021
4042
      really transformed, i.e. when a new item has been created.
4022
4043
      Otherwise we'll be allocating a lot of unnecessary memory for
4023
4044
      change records at each execution.
4024
4045
    */
4025
4046
    if (new_item != item)
4026
 
      current_session->change_item_tree(li.ref(), new_item);
 
4047
      current_thd->change_item_tree(li.ref(), new_item);
4027
4048
  }
4028
4049
  return Item_func::transform(transformer, arg);
4029
4050
}
4032
4053
/**
4033
4054
  Compile Item_cond object with a processor and a transformer
4034
4055
  callback functions.
4035
 
 
 
4056
  
4036
4057
    First the function applies the analyzer to the root node of
4037
4058
    the Item_func object. Then if the analyzer succeeeds (returns true)
4038
4059
    the function recursively applies the compile method to member
4040
4061
    If the call of the method for a member item returns a new item
4041
4062
    the old item is substituted for a new one.
4042
4063
    After this the transformer is applied to the root node
4043
 
    of the Item_cond object.
4044
 
 
 
4064
    of the Item_cond object. 
 
4065
     
4045
4066
  @param analyzer      the analyzer callback function to be applied to the
4046
4067
                       nodes of the tree of the object
4047
4068
  @param[in,out] arg_p parameter to be passed to the analyzer
4050
4071
  @param arg_t         parameter to be passed to the transformer
4051
4072
 
4052
4073
  @return
4053
 
    Item returned as the result of transformation of the root node
 
4074
    Item returned as the result of transformation of the root node 
4054
4075
*/
4055
4076
 
4056
 
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4057
 
                         Item_transformer transformer, unsigned char *arg_t)
 
4077
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
 
4078
                         Item_transformer transformer, uchar *arg_t)
4058
4079
{
4059
4080
  if (!(this->*analyzer)(arg_p))
4060
4081
    return 0;
4061
 
 
 
4082
  
4062
4083
  List_iterator<Item> li(list);
4063
4084
  Item *item;
4064
4085
  while ((item= li++))
4065
4086
  {
4066
 
    /*
 
4087
    /* 
4067
4088
      The same parameter value of arg_p must be passed
4068
4089
      to analyze any argument of the condition formula.
4069
 
    */
4070
 
    unsigned char *arg_v= *arg_p;
 
4090
    */   
 
4091
    uchar *arg_v= *arg_p;
4071
4092
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4072
4093
    if (new_item && new_item != item)
4073
4094
      li.replace(new_item);
4081
4102
  List_iterator<Item> li(list);
4082
4103
  Item *item;
4083
4104
 
4084
 
  switch (order) {
4085
 
  case (T_PREFIX):
 
4105
  switch(order) {
 
4106
  case(PREFIX):
4086
4107
    (*traverser)(this, arg);
4087
4108
    while ((item= li++))
4088
4109
    {
4090
4111
    }
4091
4112
    (*traverser)(NULL, arg);
4092
4113
    break;
4093
 
  case (T_POSTFIX):
 
4114
  case(POSTFIX):
4094
4115
    while ((item= li++))
4095
4116
    {
4096
4117
      item->traverse_cond(traverser, arg, order);
4107
4128
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4108
4129
  sql_select.cc)
4109
4130
 
4110
 
  @param session                        Thread handler
 
4131
  @param thd                    Thread handler
4111
4132
  @param ref_pointer_array      Pointer to array of reference fields
4112
4133
  @param fields         All fields in select
4113
4134
 
4116
4137
    that have or refer (HAVING) to a SUM expression.
4117
4138
*/
4118
4139
 
4119
 
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
 
4140
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
4120
4141
                               List<Item> &fields)
4121
4142
{
4122
4143
  List_iterator<Item> li(list);
4123
4144
  Item *item;
4124
4145
  while ((item= li++))
4125
 
    item->split_sum_func(session, ref_pointer_array,
4126
 
                         fields, li.ref(), true);
 
4146
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4127
4147
}
4128
4148
 
4129
4149
 
4168
4188
}
4169
4189
 
4170
4190
 
4171
 
void Item_cond::neg_arguments(Session *session)
 
4191
void Item_cond::neg_arguments(THD *thd)
4172
4192
{
4173
4193
  List_iterator<Item> li(list);
4174
4194
  Item *item;
4175
4195
  while ((item= li++))          /* Apply not transformation to the arguments */
4176
4196
  {
4177
 
    Item *new_item= item->neg_transformer(session);
 
4197
    Item *new_item= item->neg_transformer(thd);
4178
4198
    if (!new_item)
4179
4199
    {
4180
4200
      if (!(new_item= new Item_func_not(item)))
4181
4201
        return;                                 // Fatal OEM error
4182
4202
    }
4183
 
    li.replace(new_item);
 
4203
    VOID(li.replace(new_item));
4184
4204
  }
4185
4205
}
4186
4206
 
4369
4389
  if (canDoTurboBM)
4370
4390
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4371
4391
  return my_wildcmp(cmp.cmp_collation.collation,
4372
 
                    res->ptr(),res->ptr()+res->length(),
 
4392
                    res->ptr(),res->ptr()+res->length(),
4373
4393
                    res2->ptr(),res2->ptr()+res2->length(),
4374
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4375
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4394
                    escape,wild_one,wild_many) ? 0 : 1;
4376
4395
}
4377
4396
 
4378
4397
 
4389
4408
    if (!res2)
4390
4409
      return OPTIMIZE_NONE;
4391
4410
 
4392
 
    if (*res2->ptr() != internal::wild_many)
 
4411
    if (*res2->ptr() != wild_many)
4393
4412
    {
4394
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4413
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4395
4414
        return OPTIMIZE_OP;
4396
4415
    }
4397
4416
  }
4399
4418
}
4400
4419
 
4401
4420
 
4402
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4421
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4403
4422
{
4404
4423
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4406
 
      escape_item->fix_fields(session, &escape_item))
 
4424
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4425
      escape_item->fix_fields(thd, &escape_item))
4407
4426
    return true;
4408
4427
 
4409
4428
  if (!escape_item->const_during_execution())
4411
4430
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4431
    return true;
4413
4432
  }
4414
 
 
 
4433
  
4415
4434
  if (escape_item->const_item())
4416
4435
  {
4417
 
    
4418
4436
    /* If we are on execution stage */
4419
4437
    String *escape_str= escape_item->val_str(&tmp_value1);
4420
4438
    if (escape_str)
4421
4439
    {
4422
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4423
 
      strcpy(escape, escape_str->ptr()); 
 
4440
      if (escape_used_in_parsing && (
 
4441
             (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
4442
                escape_str->numchars() != 1) ||
 
4443
               escape_str->numchars() > 1)))
 
4444
      {
 
4445
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4446
        return true;
 
4447
      }
 
4448
 
 
4449
      if (use_mb(cmp.cmp_collation.collation))
 
4450
      {
 
4451
        CHARSET_INFO *cs= escape_str->charset();
 
4452
        my_wc_t wc;
 
4453
        int rc= cs->cset->mb_wc(cs, &wc,
 
4454
                                (const uchar*) escape_str->ptr(),
 
4455
                                (const uchar*) escape_str->ptr() +
 
4456
                                               escape_str->length());
 
4457
        escape= (int) (rc > 0 ? wc : '\\');
 
4458
      }
 
4459
      else
 
4460
      {
 
4461
        /*
 
4462
          In the case of 8bit character set, we pass native
 
4463
          code instead of Unicode code as "escape" argument.
 
4464
          Convert to "cs" if charset of escape differs.
 
4465
        */
 
4466
        CHARSET_INFO *cs= cmp.cmp_collation.collation;
 
4467
        uint32 unused;
 
4468
        if (escape_str->needs_conversion(escape_str->length(),
 
4469
                                         escape_str->charset(), cs, &unused))
 
4470
        {
 
4471
          char ch;
 
4472
          uint errors;
 
4473
          uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4474
                                          escape_str->length(),
 
4475
                                          escape_str->charset(), &errors);
 
4476
          escape= cnvlen ? ch : '\\';
 
4477
        }
 
4478
        else
 
4479
          escape= *(escape_str->ptr());
 
4480
      }
4424
4481
    }
4425
4482
    else
4426
 
    {
4427
 
      escape= (char *)memory::sql_alloc(1);
4428
 
      strcpy(escape, "\\");
4429
 
    } 
4430
 
   
 
4483
      escape= '\\';
 
4484
 
4431
4485
    /*
4432
4486
      We could also do boyer-more for non-const items, but as we would have to
4433
4487
      recompute the tables for each row it's not worth it.
4434
4488
    */
4435
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
 
4489
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
 
4490
       !(specialflag & SPECIAL_NO_NEW_FUNC))
4436
4491
    {
4437
4492
      String* res2 = args[1]->val_str(&tmp_value2);
4438
4493
      if (!res2)
4439
4494
        return false;                           // Null argument
4440
 
 
 
4495
      
4441
4496
      const size_t len   = res2->length();
4442
4497
      const char*  first = res2->ptr();
4443
4498
      const char*  last  = first + len - 1;
4445
4500
        len must be > 2 ('%pattern%')
4446
4501
        heuristic: only do TurboBM for pattern_len > 2
4447
4502
      */
4448
 
 
 
4503
      
4449
4504
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4450
 
          *first == internal::wild_many &&
4451
 
          *last  == internal::wild_many)
 
4505
          *first == wild_many &&
 
4506
          *last  == wild_many)
4452
4507
      {
4453
4508
        const char* tmp = first + 1;
4454
 
        for (; *tmp != internal::wild_many && *tmp != internal::wild_one; tmp++)
4455
 
        {
4456
 
          if (escape == tmp)
4457
 
            break;
4458
 
        }
4459
 
  
 
4509
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4460
4510
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4461
4511
      }
4462
4512
      if (canDoTurboBM)
4463
4513
      {
4464
4514
        pattern     = first + 1;
4465
4515
        pattern_len = (int) len - 2;
4466
 
        int *suff = (int*) session->alloc((int) (sizeof(int)*
 
4516
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
4467
4517
                                      ((pattern_len + 1)*2+
4468
4518
                                      alphabet_size)));
4469
4519
        bmGs      = suff + pattern_len + 1;
4483
4533
}
4484
4534
 
4485
4535
#ifdef LIKE_CMP_TOUPPER
4486
 
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
 
4536
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
4487
4537
#else
4488
 
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
 
4538
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
4489
4539
#endif
4490
4540
 
4491
4541
 
4499
4549
  int            f = 0;
4500
4550
  int            g = plm1;
4501
4551
  int *const splm1 = suff + plm1;
4502
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4552
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4503
4553
 
4504
4554
  *splm1 = pattern_len;
4505
4555
 
4506
4556
  if (!cs->sort_order)
4507
4557
  {
4508
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4558
    int i;
 
4559
    for (i = pattern_len - 2; i >= 0; i--)
4509
4560
    {
4510
4561
      int tmp = *(splm1 + i - f);
4511
4562
      if (g < i && tmp < i - g)
4512
 
        suff[i] = tmp;
 
4563
        suff[i] = tmp;
4513
4564
      else
4514
4565
      {
4515
 
        if (i < g)
4516
 
          g = i;
4517
 
        f = i;
4518
 
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4519
 
          g--;
4520
 
        suff[i] = f - g;
 
4566
        if (i < g)
 
4567
          g = i; // g = min(i, g)
 
4568
        f = i;
 
4569
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4570
          g--;
 
4571
        suff[i] = f - g;
4521
4572
      }
4522
4573
    }
4523
4574
  }
4524
4575
  else
4525
4576
  {
4526
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4577
    int i;
 
4578
    for (i = pattern_len - 2; 0 <= i; --i)
4527
4579
    {
4528
4580
      int tmp = *(splm1 + i - f);
4529
4581
      if (g < i && tmp < i - g)
4530
 
        suff[i] = tmp;
 
4582
        suff[i] = tmp;
4531
4583
      else
4532
4584
      {
4533
 
        if (i < g)
4534
 
          g = i;
4535
 
        f = i;
4536
 
        while (g >= 0 &&
4537
 
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4538
 
          g--;
4539
 
        suff[i] = f - g;
 
4585
        if (i < g)
 
4586
          g = i; // g = min(i, g)
 
4587
        f = i;
 
4588
        while (g >= 0 &&
 
4589
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4590
          g--;
 
4591
        suff[i] = f - g;
4540
4592
      }
4541
4593
    }
4542
4594
  }
4597
4649
  int *end = bmBc + alphabet_size;
4598
4650
  int j;
4599
4651
  const int plm1 = pattern_len - 1;
4600
 
  const CHARSET_INFO *const cs= cmp.cmp_collation.collation;
 
4652
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4601
4653
 
4602
4654
  for (i = bmBc; i < end; i++)
4603
4655
    *i = pattern_len;
4605
4657
  if (!cs->sort_order)
4606
4658
  {
4607
4659
    for (j = 0; j < plm1; j++)
4608
 
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
 
4660
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
4609
4661
  }
4610
4662
  else
4611
4663
  {
4612
4664
    for (j = 0; j < plm1; j++)
4613
 
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
 
4665
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4614
4666
  }
4615
4667
}
4616
4668
 
4629
4681
  int shift = pattern_len;
4630
4682
  int j     = 0;
4631
4683
  int u     = 0;
4632
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4684
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4633
4685
 
4634
4686
  const int plm1=  pattern_len - 1;
4635
4687
  const int tlmpl= text_len - pattern_len;
4651
4703
 
4652
4704
      register const int v = plm1 - i;
4653
4705
      turboShift = u - v;
4654
 
      bcShift    = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4655
 
      shift      = (turboShift > bcShift) ? turboShift : bcShift;
4656
 
      shift      = (shift > bmGs[i]) ? shift : bmGs[i];
 
4706
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
 
4707
      shift      = max(turboShift, bcShift);
 
4708
      shift      = max(shift, bmGs[i]);
4657
4709
      if (shift == bmGs[i])
4658
 
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
 
4710
        u = min(pattern_len - shift, v);
4659
4711
      else
4660
4712
      {
4661
 
        if (turboShift < bcShift)
4662
 
          shift= max(shift, u + 1);
4663
 
        u = 0;
 
4713
        if (turboShift < bcShift)
 
4714
          shift = max(shift, u + 1);
 
4715
        u = 0;
4664
4716
      }
4665
4717
      j+= shift;
4666
4718
    }
4673
4725
      register int i = plm1;
4674
4726
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4675
4727
      {
4676
 
        i--;
4677
 
        if (i == plm1 - shift)
4678
 
          i-= u;
 
4728
        i--;
 
4729
        if (i == plm1 - shift)
 
4730
          i-= u;
4679
4731
      }
4680
 
 
4681
4732
      if (i < 0)
4682
 
        return 1;
 
4733
        return 1;
4683
4734
 
4684
 
      register const int v= plm1 - i;
4685
 
      turboShift= u - v;
4686
 
      bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4687
 
      shift= (turboShift > bcShift) ? turboShift : bcShift;
4688
 
      shift= max(shift, bmGs[i]);
4689
 
      
 
4735
      register const int v = plm1 - i;
 
4736
      turboShift = u - v;
 
4737
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
 
4738
      shift      = max(turboShift, bcShift);
 
4739
      shift      = max(shift, bmGs[i]);
4690
4740
      if (shift == bmGs[i])
4691
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4741
        u = min(pattern_len - shift, v);
4692
4742
      else
4693
4743
      {
4694
 
        if (turboShift < bcShift)
4695
 
          shift= max(shift, u + 1);
4696
 
        u = 0;
 
4744
        if (turboShift < bcShift)
 
4745
          shift = max(shift, u + 1);
 
4746
        u = 0;
4697
4747
      }
4698
 
 
4699
4748
      j+= shift;
4700
4749
    }
4701
4750
    return 0;
4724
4773
  assert(fixed == 1);
4725
4774
  List_iterator<Item> li(list);
4726
4775
  Item *item;
4727
 
  int result=0;
 
4776
  int result=0; 
4728
4777
  null_value=0;
4729
4778
  while ((item=li++))
4730
4779
  {
4757
4806
       IS NOT NULL(a)     -> IS NULL(a)
4758
4807
    @endverbatim
4759
4808
 
4760
 
  @param session                thread handler
 
4809
  @param thd            thread handler
4761
4810
 
4762
4811
  @return
4763
4812
    New item or
4764
4813
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4765
4814
*/
4766
4815
 
4767
 
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
 
4816
Item *Item_func_not::neg_transformer(THD *thd __attribute__((__unused__)))      /* NOT(x)  ->  x */
4768
4817
{
4769
4818
  return args[0];
4770
4819
}
4771
4820
 
4772
4821
 
4773
 
Item *Item_bool_rowready_func2::neg_transformer(Session *)
 
4822
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((__unused__)))
4774
4823
{
4775
4824
  Item *item= negated_item();
4776
4825
  return item;
4780
4829
/**
4781
4830
  a IS NULL  ->  a IS NOT NULL.
4782
4831
*/
4783
 
Item *Item_func_isnull::neg_transformer(Session *)
 
4832
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((__unused__)))
4784
4833
{
4785
4834
  Item *item= new Item_func_isnotnull(args[0]);
4786
4835
  return item;
4790
4839
/**
4791
4840
  a IS NOT NULL  ->  a IS NULL.
4792
4841
*/
4793
 
Item *Item_func_isnotnull::neg_transformer(Session *)
 
4842
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((__unused__)))
4794
4843
{
4795
4844
  Item *item= new Item_func_isnull(args[0]);
4796
4845
  return item;
4797
4846
}
4798
4847
 
4799
4848
 
4800
 
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
 
4849
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
4801
4850
                                        /* NOT a OR NOT b OR ... */
4802
4851
{
4803
 
  neg_arguments(session);
 
4852
  neg_arguments(thd);
4804
4853
  Item *item= new Item_cond_or(list);
4805
4854
  return item;
4806
4855
}
4807
4856
 
4808
4857
 
4809
 
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
 
4858
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
4810
4859
                                        /* NOT a AND NOT b AND ... */
4811
4860
{
4812
 
  neg_arguments(session);
 
4861
  neg_arguments(thd);
4813
4862
  Item *item= new Item_cond_and(list);
4814
4863
  return item;
4815
4864
}
4816
4865
 
4817
4866
 
4818
 
Item *Item_func_nop_all::neg_transformer(Session *)
 
4867
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((__unused__)))
4819
4868
{
4820
4869
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4821
4870
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4826
4875
  return new_item;
4827
4876
}
4828
4877
 
4829
 
Item *Item_func_not_all::neg_transformer(Session *)
 
4878
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((__unused__)))
4830
4879
{
4831
4880
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4832
4881
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4933
4982
  fields.push_back(f);
4934
4983
}
4935
4984
 
4936
 
uint32_t Item_equal::members()
 
4985
uint Item_equal::members()
4937
4986
{
4938
4987
  return fields.elements;
4939
4988
}
4949
4998
  @retval
4950
4999
    1       if nultiple equality contains a reference to field
4951
5000
  @retval
4952
 
    0       otherwise
 
5001
    0       otherwise    
4953
5002
*/
4954
5003
 
4955
5004
bool Item_equal::contains(Field *field)
4967
5016
 
4968
5017
/**
4969
5018
  Join members of another Item_equal object.
4970
 
 
 
5019
  
4971
5020
    The function actually merges two multiple equalities.
4972
5021
    After this operation the Item_equal object additionally contains
4973
5022
    the field items of another item of the type Item_equal.
4974
5023
    If the optional constant items are not equal the cond_false flag is
4975
 
    set to 1.
 
5024
    set to 1.  
4976
5025
  @param item    multiple equality whose members are to be joined
4977
5026
*/
4978
5027
 
4982
5031
  Item *c= item->const_item;
4983
5032
  if (c)
4984
5033
  {
4985
 
    /*
4986
 
      The flag cond_false will be set to 1 after this, if
4987
 
      the multiple equality already contains a constant and its
 
5034
    /* 
 
5035
      The flag cond_false will be set to 1 after this, if 
 
5036
      the multiple equality already contains a constant and its 
4988
5037
      value is  not equal to the value of c.
4989
5038
    */
4990
5039
    add(c);
4991
5040
  }
4992
5041
  cond_false|= item->cond_false;
4993
 
}
 
5042
4994
5043
 
4995
5044
 
4996
5045
/**
5066
5115
  }
5067
5116
}
5068
5117
 
5069
 
bool Item_equal::fix_fields(Session *, Item **)
 
5118
bool Item_equal::fix_fields(THD *thd __attribute__((__unused__)), Item **ref __attribute__((__unused__)))
5070
5119
{
5071
5120
  List_iterator_fast<Item_field> li(fields);
5072
5121
  Item *item;
5114
5163
  while ((item_field= it++))
5115
5164
  {
5116
5165
    /* Skip fields of non-const tables. They haven't been read yet */
5117
 
    if (item_field->field->getTable()->const_table)
 
5166
    if (item_field->field->table->const_table)
5118
5167
    {
5119
5168
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5120
5169
        return 0;
5130
5179
                                      item->collation.collation);
5131
5180
}
5132
5181
 
5133
 
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
5182
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
5134
5183
{
5135
5184
  List_iterator_fast<Item_field> it(fields);
5136
5185
  Item *item;
5142
5191
  return Item_func::walk(processor, walk_subquery, arg);
5143
5192
}
5144
5193
 
5145
 
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
 
5194
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
5146
5195
{
5147
5196
  List_iterator<Item_field> it(fields);
5148
5197
  Item *item;
5153
5202
      return 0;
5154
5203
 
5155
5204
    /*
5156
 
      Session::change_item_tree() should be called only if the tree was
 
5205
      THD::change_item_tree() should be called only if the tree was
5157
5206
      really transformed, i.e. when a new item has been created.
5158
5207
      Otherwise we'll be allocating a lot of unnecessary memory for
5159
5208
      change records at each execution.
5160
5209
    */
5161
5210
    if (new_item != item)
5162
 
      current_session->change_item_tree((Item **) it.ref(), new_item);
 
5211
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5163
5212
  }
5164
5213
  return Item_func::transform(transformer, arg);
5165
5214
}
5186
5235
  str->append(')');
5187
5236
}
5188
5237
 
5189
 
} /* namespace drizzled */