~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_cmpfunc.cc

  • Committer: Mark Atwood
  • Date: 2008-07-12 11:37:59 UTC
  • mto: This revision was merged to the branch mainline in revision 139.
  • Revision ID: me@mark.atwood.name-20080712113759-nrjn1bq1e0shuory
Add hello_world() UDF

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
325
269
  NULL if some arg is NULL.
326
270
*/
327
271
 
328
 
int64_t Item_func_not::val_int()
 
272
longlong Item_func_not::val_int()
329
273
{
330
274
  assert(fixed == 1);
331
275
  bool value= args[0]->val_bool();
354
298
*/
355
299
 
356
300
 
357
 
int64_t Item_func_not_all::val_int()
 
301
longlong Item_func_not_all::val_int()
358
302
{
359
303
  assert(fixed == 1);
360
304
  bool value= args[0]->val_bool();
395
339
    returns some rows it return same value as argument (true/false).
396
340
*/
397
341
 
398
 
int64_t Item_func_nop_all::val_int()
 
342
longlong Item_func_nop_all::val_int()
399
343
{
400
344
  assert(fixed == 1);
401
 
  int64_t value= args[0]->val_int();
 
345
  longlong value= args[0]->val_int();
402
346
 
403
347
  /*
404
348
    return false if there was records in underlying select in max/min
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;
454
 
    uint64_t orig_field_val= 0; /* original field value if valid */
 
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;
 
399
    ulonglong 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;
532
 
 
533
 
  if (args[0]->real_item()->type() == FIELD_ITEM)
 
485
  thd= current_thd;
 
486
  if (!thd->is_context_analysis_only())
534
487
  {
535
 
    field_item= static_cast<Item_field*>(args[0]->real_item());
536
 
    if (field_item->field->can_be_compared_as_int64_t() &&
537
 
        !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
 
488
    if (args[0]->real_item()->type() == FIELD_ITEM)
538
489
    {
539
 
      if (convert_constant_item(session, field_item, &args[1]))
 
490
      Item_field *field_item= (Item_field*) (args[0]->real_item());
 
491
      if (field_item->field->can_be_compared_as_longlong() &&
 
492
          !(field_item->is_datetime() &&
 
493
            args[1]->result_type() == STRING_RESULT))
540
494
      {
541
 
        cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
542
 
                         INT_RESULT);           // Works for all types.
543
 
        args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
544
 
        return;
 
495
        if (convert_constant_item(thd, field_item, &args[1]))
 
496
        {
 
497
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
 
498
                           INT_RESULT);         // Works for all types.
 
499
          args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
 
500
          return;
 
501
        }
545
502
      }
546
503
    }
547
 
 
548
504
    if (args[1]->real_item()->type() == FIELD_ITEM)
549
505
    {
550
 
      field_item= static_cast<Item_field*>(args[1]->real_item());
551
 
      if (field_item->field->can_be_compared_as_int64_t() &&
 
506
      Item_field *field_item= (Item_field*) (args[1]->real_item());
 
507
      if (field_item->field->can_be_compared_as_longlong() &&
552
508
          !(field_item->is_datetime() &&
553
509
            args[0]->result_type() == STRING_RESULT))
554
510
      {
555
 
        if (convert_constant_item(session, field_item, &args[0]))
 
511
        if (convert_constant_item(thd, field_item, &args[0]))
556
512
        {
557
513
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
558
514
                           INT_RESULT); // Works for all types.
570
526
{
571
527
  owner= item;
572
528
  func= comparator_matrix[type]
573
 
    [test(owner->functype() == Item_func::EQUAL_FUNC)];
574
 
 
 
529
                         [test(owner->functype() == Item_func::EQUAL_FUNC)];
575
530
  switch (type) {
576
531
  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
 
 
 
532
  {
 
533
    uint n= (*a)->cols();
 
534
    if (n != (*b)->cols())
 
535
    {
 
536
      my_error(ER_OPERAND_COLUMNS, MYF(0), n);
 
537
      comparators= 0;
 
538
      return 1;
 
539
    }
 
540
    if (!(comparators= new Arg_comparator[n]))
 
541
      return 1;
 
542
    for (uint i=0; i < n; i++)
 
543
    {
 
544
      if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
 
545
      {
 
546
        my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
 
547
        return 1;
 
548
      }
 
549
      comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
 
550
    }
 
551
    break;
 
552
  }
599
553
  case STRING_RESULT:
 
554
  {
 
555
    /*
 
556
      We must set cmp_charset here as we may be called from for an automatic
 
557
      generated item, like in natural join
 
558
    */
 
559
    if (cmp_collation.set((*a)->collation, (*b)->collation) || 
 
560
        cmp_collation.derivation == DERIVATION_NONE)
 
561
    {
 
562
      my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
 
563
      return 1;
 
564
    }
 
565
    if (cmp_collation.collation == &my_charset_bin)
600
566
    {
601
567
      /*
602
 
        We must set cmp_charset here as we may be called from for an automatic
603
 
        generated item, like in natural join
 
568
        We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
 
569
        without removing end space
604
570
      */
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;
 
571
      if (func == &Arg_comparator::compare_string)
 
572
        func= &Arg_comparator::compare_binary_string;
 
573
      else if (func == &Arg_comparator::compare_e_string)
 
574
        func= &Arg_comparator::compare_e_binary_string;
621
575
 
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'
 
576
      /*
 
577
        As this is binary compassion, mark all fields that they can't be
 
578
        transformed. Otherwise we would get into trouble with comparisons
 
579
        like:
 
580
        WHERE col= 'j' AND col LIKE BINARY 'j'
 
581
        which would be transformed to:
 
582
        WHERE col= 'j'
629
583
      */
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;
 
584
      (*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
 
585
      (*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
634
586
    }
 
587
    break;
 
588
  }
635
589
  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
 
    }
 
590
  {
 
591
    if (func == &Arg_comparator::compare_int_signed)
 
592
    {
 
593
      if ((*a)->unsigned_flag)
 
594
        func= (((*b)->unsigned_flag)?
 
595
               &Arg_comparator::compare_int_unsigned :
 
596
               &Arg_comparator::compare_int_unsigned_signed);
 
597
      else if ((*b)->unsigned_flag)
 
598
        func= &Arg_comparator::compare_int_signed_unsigned;
 
599
    }
 
600
    else if (func== &Arg_comparator::compare_e_int)
 
601
    {
 
602
      if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
 
603
        func= &Arg_comparator::compare_e_int_diff_signedness;
 
604
    }
 
605
    break;
 
606
  }
653
607
  case DECIMAL_RESULT:
654
608
    break;
655
609
  case REAL_RESULT:
 
610
  {
 
611
    if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
656
612
    {
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;
 
613
      precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
 
614
      if (func == &Arg_comparator::compare_real)
 
615
        func= &Arg_comparator::compare_real_fixed;
 
616
      else if (func == &Arg_comparator::compare_e_real)
 
617
        func= &Arg_comparator::compare_e_real_fixed;
666
618
    }
667
 
  }
668
 
 
 
619
    break;
 
620
  }
 
621
  default:
 
622
    assert(0);
 
623
  }
669
624
  return 0;
670
625
}
671
626
 
673
628
/**
674
629
  @brief Convert date provided in a string to the int representation.
675
630
 
676
 
  @param[in]   session        thread handle
 
631
  @param[in]   thd        thread handle
677
632
  @param[in]   str        a string to convert
678
633
  @param[in]   warn_type  type of the timestamp for issuing the warning
679
634
  @param[in]   warn_name  field name for issuing the warning
692
647
    converted value. 0 on error and on zero-dates -- check 'failure'
693
648
*/
694
649
 
695
 
static uint64_t
696
 
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
 
650
static ulonglong
 
651
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
697
652
                  char *warn_name, bool *error_arg)
698
653
{
699
 
  uint64_t value= 0;
 
654
  ulonglong value= 0;
700
655
  int error;
701
 
  DRIZZLE_TIME l_time;
702
 
  enum enum_drizzle_timestamp_type ret;
 
656
  MYSQL_TIME l_time;
 
657
  enum_mysql_timestamp_type ret;
703
658
 
704
659
  ret= str_to_datetime(str->ptr(), str->length(), &l_time,
705
660
                       (TIME_FUZZY_DATE | MODE_INVALID_DATES |
706
 
                        (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
 
661
                        (thd->variables.sql_mode &
 
662
                         (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
707
663
                       &error);
708
664
 
709
 
  if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
 
665
  if (ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE)
710
666
  {
711
667
    /*
712
668
      Do not return yet, we may still want to throw a "trailing garbage"
713
669
      warning.
714
670
    */
715
671
    *error_arg= false;
716
 
    value= TIME_to_uint64_t_datetime(&l_time);
 
672
    value= TIME_to_ulonglong_datetime(&l_time);
717
673
  }
718
674
  else
719
675
  {
722
678
  }
723
679
 
724
680
  if (error > 0)
725
 
  {
726
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
681
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
727
682
                                 str->ptr(), str->length(),
728
683
                                 warn_type, warn_name);
729
 
  }
730
684
 
731
685
  return value;
732
686
}
749
703
         int result and the other item (b or a) is an item with string result.
750
704
         If the second item is a constant one then it's checked to be
751
705
         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.
 
706
         converted to a DATE/DATETIME then the compare_datetime() comparator
 
707
         isn't used and the warning about wrong DATE/DATETIME value is issued.
753
708
      In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
754
709
      the comparison is handled by other comparators.
755
 
 
756
710
    If the datetime comparator can be used and one the operands of the
757
711
    comparison is a string constant that was successfully converted to a
758
712
    DATE/DATETIME type then the result of the conversion is returned in the
765
719
*/
766
720
 
767
721
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)
 
722
Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
770
723
{
771
724
  enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
725
  Item *str_arg= 0, *date_arg= 0;
773
726
 
774
 
  if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
 
727
  if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
728
    return CMP_DATE_DFLT;
776
729
 
777
 
  if (in_a->is_datetime())
 
730
  if (a->is_datetime())
778
731
  {
779
 
    if (in_b->is_datetime())
 
732
    if (b->is_datetime())
780
733
      cmp_type= CMP_DATE_WITH_DATE;
781
 
    else if (in_b->result_type() == STRING_RESULT)
 
734
    else if (b->result_type() == STRING_RESULT)
782
735
    {
783
736
      cmp_type= CMP_DATE_WITH_STR;
784
 
      date_arg= in_a;
785
 
      str_arg= in_b;
 
737
      date_arg= a;
 
738
      str_arg= b;
786
739
    }
787
740
  }
788
 
  else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
 
741
  else if (b->is_datetime() && a->result_type() == STRING_RESULT)
789
742
  {
790
743
    cmp_type= CMP_STR_WITH_DATE;
791
 
    date_arg= in_b;
792
 
    str_arg= in_a;
 
744
    date_arg= b;
 
745
    str_arg= a;
793
746
  }
794
747
 
795
748
  if (cmp_type != CMP_DATE_DFLT)
802
755
        (str_arg->type() != Item::FUNC_ITEM ||
803
756
        ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
804
757
    {
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
 
       */
822
 
      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
      THD *thd= current_thd;
 
759
      ulonglong value;
 
760
      bool error;
 
761
      String tmp, *str_val= 0;
 
762
      timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_NEWDATE ?
 
763
                              MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
827
764
 
828
765
      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
 
 
 
766
      if (str_arg->null_value)
 
767
        return CMP_DATE_DFLT;
 
768
      value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
 
769
      if (error)
 
770
        return CMP_DATE_DFLT;
852
771
      if (const_value)
853
772
        *const_value= value;
854
773
    }
857
776
}
858
777
 
859
778
 
 
779
/*
 
780
  Retrieves correct TIME value from the given item.
 
781
 
 
782
  SYNOPSIS
 
783
    get_time_value()
 
784
    thd                 thread handle
 
785
    item_arg   [in/out] item to retrieve TIME value from
 
786
    cache_arg  [in/out] pointer to place to store the cache item to
 
787
    warn_item  [in]     unused
 
788
    is_null    [out]    true <=> the item_arg is null
 
789
 
 
790
  DESCRIPTION
 
791
    Retrieves the correct TIME value from given item for comparison by the
 
792
    compare_datetime() function.
 
793
    If item's result can be compared as longlong then its int value is used
 
794
    and a value returned by get_time function is used otherwise.
 
795
    If an item is a constant one then its value is cached and it isn't
 
796
    get parsed again. An Item_cache_int object is used for for cached values.
 
797
    It seamlessly substitutes the original item.  The cache item is marked as
 
798
    non-constant to prevent re-caching it again.
 
799
 
 
800
  RETURN
 
801
    obtained value
 
802
*/
 
803
 
 
804
ulonglong
 
805
get_time_value(THD *thd __attribute__((__unused__)),
 
806
               Item ***item_arg, Item **cache_arg,
 
807
               Item *warn_item __attribute__((__unused__)),
 
808
               bool *is_null)
 
809
{
 
810
  ulonglong value;
 
811
  Item *item= **item_arg;
 
812
  MYSQL_TIME ltime;
 
813
 
 
814
  if (item->result_as_longlong())
 
815
  {
 
816
    value= item->val_int();
 
817
    *is_null= item->null_value;
 
818
  }
 
819
  else
 
820
  {
 
821
    *is_null= item->get_time(&ltime);
 
822
    value= !*is_null ? TIME_to_ulonglong_datetime(&ltime) : 0;
 
823
  }
 
824
  /*
 
825
    Do not cache GET_USER_VAR() function as its const_item() may return true
 
826
    for the current thread but it still may change during the execution.
 
827
  */
 
828
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
 
829
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
 
830
  {
 
831
    Item_cache_int *cache= new Item_cache_int();
 
832
    /* Mark the cache as non-const to prevent re-caching. */
 
833
    cache->set_used_tables(1);
 
834
    cache->store(item, value);
 
835
    *cache_arg= cache;
 
836
    *item_arg= cache_arg;
 
837
  }
 
838
  return value;
 
839
}
 
840
 
 
841
 
860
842
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
861
843
                                        Item **a1, Item **a2,
862
844
                                        Item_result type)
863
845
{
864
846
  enum enum_date_cmp_type cmp_type;
865
 
  uint64_t const_value= (uint64_t)-1;
 
847
  ulonglong const_value= (ulonglong)-1;
866
848
  a= a1;
867
849
  b= a2;
868
850
 
869
851
  if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
870
852
  {
871
 
    session= current_session;
 
853
    thd= current_thd;
872
854
    owner= owner_arg;
873
855
    a_type= (*a)->field_type();
874
856
    b_type= (*b)->field_type();
875
857
    a_cache= 0;
876
858
    b_cache= 0;
877
859
 
878
 
    if (const_value != (uint64_t)-1)
 
860
    if (const_value != (ulonglong)-1)
879
861
    {
880
862
      Item_cache_int *cache= new Item_cache_int();
881
863
      /* Mark the cache as non-const to prevent re-caching. */
898
880
    get_value_func= &get_datetime_value;
899
881
    return 0;
900
882
  }
 
883
  else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
 
884
           (*b)->field_type() == MYSQL_TYPE_TIME)
 
885
  {
 
886
    /* Compare TIME values as integers. */
 
887
    thd= current_thd;
 
888
    owner= owner_arg;
 
889
    a_cache= 0;
 
890
    b_cache= 0;
 
891
    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
 
892
    func= &Arg_comparator::compare_datetime;
 
893
    get_value_func= &get_time_value;
 
894
    return 0;
 
895
  }
901
896
 
902
897
  return set_compare_func(owner_arg, type);
903
898
}
905
900
 
906
901
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
907
902
{
908
 
  session= current_session;
 
903
  thd= current_thd;
909
904
  /* A caller will handle null values by itself. */
910
905
  owner= NULL;
911
906
  a= a1;
925
920
 
926
921
  SYNOPSIS
927
922
    get_datetime_value()
928
 
    session                 thread handle
 
923
    thd                 thread handle
929
924
    item_arg   [in/out] item to retrieve DATETIME value from
930
925
    cache_arg  [in/out] pointer to place to store the caching item to
931
926
    warn_item  [in]     item for issuing the conversion warning
934
929
  DESCRIPTION
935
930
    Retrieves the correct DATETIME value from given item for comparison by the
936
931
    compare_datetime() function.
937
 
    If item's result can be compared as int64_t then its int value is used
 
932
    If item's result can be compared as longlong then its int value is used
938
933
    and its string value is used otherwise. Strings are always parsed and
939
934
    converted to int values by the get_date_from_str() function.
940
935
    This allows us to compare correctly string dates with missed insignificant
949
944
    obtained value
950
945
*/
951
946
 
952
 
uint64_t
953
 
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
 
947
ulonglong
 
948
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
954
949
                   Item *warn_item, bool *is_null)
955
950
{
956
 
  uint64_t value= 0;
 
951
  ulonglong value= 0;
957
952
  String buf, *str= 0;
958
953
  Item *item= **item_arg;
959
954
 
960
 
  if (item->result_as_int64_t())
 
955
  if (item->result_as_longlong())
961
956
  {
962
957
    value= item->val_int();
963
958
    *is_null= item->null_value;
964
959
    enum_field_types f_type= item->field_type();
965
960
    /*
966
 
      Item_date_add_interval may return DRIZZLE_TYPE_STRING as the result
 
961
      Item_date_add_interval may return MYSQL_TYPE_STRING as the result
967
962
      field type. To detect that the DATE value has been returned we
968
963
      compare it with 100000000L - any DATE value should be less than it.
969
964
      Don't shift cached DATETIME values up for the second time.
970
965
    */
971
 
    if (f_type == DRIZZLE_TYPE_DATE ||
972
 
        (f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
 
966
    if (f_type == MYSQL_TYPE_NEWDATE ||
 
967
        (f_type != MYSQL_TYPE_DATETIME && value < 100000000L))
973
968
      value*= 1000000L;
974
969
  }
975
970
  else
978
973
    *is_null= item->null_value;
979
974
  }
980
975
  if (*is_null)
981
 
    return ~(uint64_t) 0;
 
976
    return ~(ulonglong) 0;
982
977
  /*
983
978
    Convert strings to the integer DATE/DATETIME representation.
984
979
    Even if both dates provided in strings we can't compare them directly as
989
984
  {
990
985
    bool error;
991
986
    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);
 
987
    timestamp_type t_type= f_type ==
 
988
      MYSQL_TYPE_NEWDATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
 
989
    value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
995
990
    /*
996
991
      If str did not contain a valid date according to the current
997
992
      SQL_MODE, get_date_from_str() has already thrown a warning,
1006
1001
  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
1007
1002
      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
1008
1003
  {
1009
 
    Item_cache_int *cache= new Item_cache_int(DRIZZLE_TYPE_DATETIME);
 
1004
    Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
1010
1005
    /* Mark the cache as non-const to prevent re-caching. */
1011
1006
    cache->set_used_tables(1);
1012
1007
    cache->store(item, value);
1040
1035
int Arg_comparator::compare_datetime()
1041
1036
{
1042
1037
  bool is_null= false;
1043
 
  uint64_t a_value, b_value;
 
1038
  ulonglong a_value, b_value;
1044
1039
 
1045
1040
  /* Get DATE/DATETIME/TIME value of the 'a' item. */
1046
 
  a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
 
1041
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
1047
1042
  if (!is_nulls_eq && is_null)
1048
1043
  {
1049
1044
    if (owner)
1052
1047
  }
1053
1048
 
1054
1049
  /* Get DATE/DATETIME/TIME value of the 'b' item. */
1055
 
  b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
 
1050
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
1056
1051
  if (is_null)
1057
1052
  {
1058
1053
    if (owner)
1066
1061
  /* Compare values. */
1067
1062
  if (is_nulls_eq)
1068
1063
    return (a_value == b_value);
1069
 
  return (a_value < b_value) ? -1 : ((a_value > b_value) ? 1 : 0);
 
1064
  return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1070
1065
}
1071
1066
 
1072
1067
 
1105
1100
    if ((res2= (*b)->val_str(&owner->tmp_value2)))
1106
1101
    {
1107
1102
      owner->null_value= 0;
1108
 
      uint32_t res1_length= res1->length();
1109
 
      uint32_t res2_length= res2->length();
 
1103
      uint res1_length= res1->length();
 
1104
      uint res2_length= res2->length();
1110
1105
      int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1111
1106
      return cmp ? cmp : (int) (res1_length - res2_length);
1112
1107
    }
1244
1239
 
1245
1240
int Arg_comparator::compare_int_signed()
1246
1241
{
1247
 
  int64_t val1= (*a)->val_int();
 
1242
  longlong val1= (*a)->val_int();
1248
1243
  if (!(*a)->null_value)
1249
1244
  {
1250
 
    int64_t val2= (*b)->val_int();
 
1245
    longlong val2= (*b)->val_int();
1251
1246
    if (!(*b)->null_value)
1252
1247
    {
1253
1248
      owner->null_value= 0;
1267
1262
 
1268
1263
int Arg_comparator::compare_int_unsigned()
1269
1264
{
1270
 
  uint64_t val1= (*a)->val_int();
 
1265
  ulonglong val1= (*a)->val_int();
1271
1266
  if (!(*a)->null_value)
1272
1267
  {
1273
 
    uint64_t val2= (*b)->val_int();
 
1268
    ulonglong val2= (*b)->val_int();
1274
1269
    if (!(*b)->null_value)
1275
1270
    {
1276
1271
      owner->null_value= 0;
1290
1285
 
1291
1286
int Arg_comparator::compare_int_signed_unsigned()
1292
1287
{
1293
 
  int64_t sval1= (*a)->val_int();
 
1288
  longlong sval1= (*a)->val_int();
1294
1289
  if (!(*a)->null_value)
1295
1290
  {
1296
 
    uint64_t uval2= (uint64_t)(*b)->val_int();
 
1291
    ulonglong uval2= (ulonglong)(*b)->val_int();
1297
1292
    if (!(*b)->null_value)
1298
1293
    {
1299
1294
      owner->null_value= 0;
1300
 
      if (sval1 < 0 || (uint64_t)sval1 < uval2)
 
1295
      if (sval1 < 0 || (ulonglong)sval1 < uval2)
1301
1296
        return -1;
1302
 
      if ((uint64_t)sval1 == uval2)
 
1297
      if ((ulonglong)sval1 == uval2)
1303
1298
        return 0;
1304
1299
      return 1;
1305
1300
    }
1315
1310
 
1316
1311
int Arg_comparator::compare_int_unsigned_signed()
1317
1312
{
1318
 
  uint64_t uval1= (uint64_t)(*a)->val_int();
 
1313
  ulonglong uval1= (ulonglong)(*a)->val_int();
1319
1314
  if (!(*a)->null_value)
1320
1315
  {
1321
 
    int64_t sval2= (*b)->val_int();
 
1316
    longlong sval2= (*b)->val_int();
1322
1317
    if (!(*b)->null_value)
1323
1318
    {
1324
1319
      owner->null_value= 0;
1325
1320
      if (sval2 < 0)
1326
1321
        return 1;
1327
 
      if (uval1 < (uint64_t)sval2)
 
1322
      if (uval1 < (ulonglong)sval2)
1328
1323
        return -1;
1329
 
      if (uval1 == (uint64_t)sval2)
 
1324
      if (uval1 == (ulonglong)sval2)
1330
1325
        return 0;
1331
1326
      return 1;
1332
1327
    }
1338
1333
 
1339
1334
int Arg_comparator::compare_e_int()
1340
1335
{
1341
 
  int64_t val1= (*a)->val_int();
1342
 
  int64_t val2= (*b)->val_int();
 
1336
  longlong val1= (*a)->val_int();
 
1337
  longlong val2= (*b)->val_int();
1343
1338
  if ((*a)->null_value || (*b)->null_value)
1344
1339
    return test((*a)->null_value && (*b)->null_value);
1345
1340
  return test(val1 == val2);
1350
1345
*/
1351
1346
int Arg_comparator::compare_e_int_diff_signedness()
1352
1347
{
1353
 
  int64_t val1= (*a)->val_int();
1354
 
  int64_t val2= (*b)->val_int();
 
1348
  longlong val1= (*a)->val_int();
 
1349
  longlong val2= (*b)->val_int();
1355
1350
  if ((*a)->null_value || (*b)->null_value)
1356
1351
    return test((*a)->null_value && (*b)->null_value);
1357
1352
  return (val1 >= 0) && test(val1 == val2);
1363
1358
  bool was_null= 0;
1364
1359
  (*a)->bring_value();
1365
1360
  (*b)->bring_value();
1366
 
  uint32_t n= (*a)->cols();
1367
 
  for (uint32_t i= 0; i<n; i++)
 
1361
  uint n= (*a)->cols();
 
1362
  for (uint i= 0; i<n; i++)
1368
1363
  {
1369
1364
    res= comparators[i].compare();
1370
1365
    if (owner->null_value)
1406
1401
{
1407
1402
  (*a)->bring_value();
1408
1403
  (*b)->bring_value();
1409
 
  uint32_t n= (*a)->cols();
1410
 
  for (uint32_t i= 0; i<n; i++)
 
1404
  uint n= (*a)->cols();
 
1405
  for (uint i= 0; i<n; i++)
1411
1406
  {
1412
1407
    if (!comparators[i].compare())
1413
1408
      return 0;
1463
1458
}
1464
1459
 
1465
1460
 
1466
 
int64_t Item_func_truth::val_int()
 
1461
longlong Item_func_truth::val_int()
1467
1462
{
1468
1463
  return (val_bool() ? 1 : 0);
1469
1464
}
1470
1465
 
1471
1466
 
1472
 
bool Item_in_optimizer::fix_left(Session *session, Item **)
 
1467
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((__unused__)))
1473
1468
{
1474
 
  if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
 
1469
  if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1475
1470
      (!cache && !(cache= Item_cache::get_cache(args[0]))))
1476
1471
    return 1;
1477
1472
 
1485
1480
  }
1486
1481
  else
1487
1482
  {
1488
 
    uint32_t n= cache->cols();
1489
 
    for (uint32_t i= 0; i < n; i++)
 
1483
    uint n= cache->cols();
 
1484
    for (uint i= 0; i < n; i++)
1490
1485
    {
1491
1486
      if (args[0]->element_index(i)->used_tables())
1492
1487
        ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
1503
1498
}
1504
1499
 
1505
1500
 
1506
 
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
 
1501
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1507
1502
{
1508
1503
  assert(fixed == 0);
1509
 
  if (fix_left(session, ref))
 
1504
  if (fix_left(thd, ref))
1510
1505
    return true;
1511
1506
  if (args[0]->maybe_null)
1512
1507
    maybe_null=1;
1513
1508
 
1514
 
  if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
 
1509
  if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1515
1510
    return true;
1516
1511
  Item_in_subselect * sub= (Item_in_subselect *)args[1];
1517
1512
  if (args[0]->cols() != sub->engine->cols())
1530
1525
}
1531
1526
 
1532
1527
 
1533
 
int64_t Item_in_optimizer::val_int()
 
1528
longlong Item_in_optimizer::val_int()
1534
1529
{
1535
1530
  bool tmp;
1536
1531
  assert(fixed == 1);
1537
1532
  cache->store(args[0]);
1538
 
 
 
1533
  
1539
1534
  if (cache->null_value)
1540
1535
  {
1541
1536
    if (((Item_in_subselect*)args[1])->is_top_level_item())
1563
1558
          We disable the predicates we've pushed down into subselect, run the
1564
1559
          subselect and see if it has produced any rows.
1565
1560
        */
1566
 
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
 
1561
        Item_in_subselect *item_subs=(Item_in_subselect*)args[1]; 
1567
1562
        if (cache->cols() == 1)
1568
1563
        {
1569
1564
          item_subs->set_cond_guard_var(0, false);
1573
1568
        }
1574
1569
        else
1575
1570
        {
1576
 
          uint32_t i;
1577
 
          uint32_t ncols= cache->cols();
 
1571
          uint i;
 
1572
          uint ncols= cache->cols();
1578
1573
          /*
1579
1574
            Turn off the predicates that are based on column compares for
1580
1575
            which the left part is currently NULL
1584
1579
            if (cache->element_index(i)->null_value)
1585
1580
              item_subs->set_cond_guard_var(i, false);
1586
1581
          }
1587
 
 
 
1582
          
1588
1583
          (void) args[1]->val_bool_result();
1589
1584
          result_for_null_param= null_value= !item_subs->engine->no_rows();
1590
 
 
 
1585
          
1591
1586
          /* Turn all predicates back on */
1592
1587
          for (i= 0; i < ncols; i++)
1593
1588
            item_subs->set_cond_guard_var(i, true);
1647
1642
    @retval NULL if an error occurred
1648
1643
*/
1649
1644
 
1650
 
Item *Item_in_optimizer::transform(Item_transformer transformer, unsigned char *argument)
 
1645
Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
1651
1646
{
1652
1647
  Item *new_item;
1653
1648
 
1658
1653
  if (!new_item)
1659
1654
    return 0;
1660
1655
  /*
1661
 
    Session::change_item_tree() should be called only if the tree was
 
1656
    THD::change_item_tree() should be called only if the tree was
1662
1657
    really transformed, i.e. when a new item has been created.
1663
1658
    Otherwise we'll be allocating a lot of unnecessary memory for
1664
1659
    change records at each execution.
1665
1660
  */
1666
1661
  if ((*args) != new_item)
1667
 
    current_session->change_item_tree(args, new_item);
 
1662
    current_thd->change_item_tree(args, new_item);
1668
1663
 
1669
1664
  /*
1670
1665
    Transform the right IN operand which should be an Item_in_subselect or a
1689
1684
 
1690
1685
 
1691
1686
 
1692
 
int64_t Item_func_eq::val_int()
 
1687
longlong Item_func_eq::val_int()
1693
1688
{
1694
1689
  assert(fixed == 1);
1695
1690
  int value= cmp.compare();
1705
1700
  maybe_null=null_value=0;
1706
1701
}
1707
1702
 
1708
 
int64_t Item_func_equal::val_int()
 
1703
longlong Item_func_equal::val_int()
1709
1704
{
1710
1705
  assert(fixed == 1);
1711
1706
  return cmp.compare();
1712
1707
}
1713
1708
 
1714
 
int64_t Item_func_ne::val_int()
 
1709
longlong Item_func_ne::val_int()
1715
1710
{
1716
1711
  assert(fixed == 1);
1717
1712
  int value= cmp.compare();
1719
1714
}
1720
1715
 
1721
1716
 
1722
 
int64_t Item_func_ge::val_int()
 
1717
longlong Item_func_ge::val_int()
1723
1718
{
1724
1719
  assert(fixed == 1);
1725
1720
  int value= cmp.compare();
1727
1722
}
1728
1723
 
1729
1724
 
1730
 
int64_t Item_func_gt::val_int()
 
1725
longlong Item_func_gt::val_int()
1731
1726
{
1732
1727
  assert(fixed == 1);
1733
1728
  int value= cmp.compare();
1734
1729
  return value > 0 ? 1 : 0;
1735
1730
}
1736
1731
 
1737
 
int64_t Item_func_le::val_int()
 
1732
longlong Item_func_le::val_int()
1738
1733
{
1739
1734
  assert(fixed == 1);
1740
1735
  int value= cmp.compare();
1742
1737
}
1743
1738
 
1744
1739
 
1745
 
int64_t Item_func_lt::val_int()
 
1740
longlong Item_func_lt::val_int()
1746
1741
{
1747
1742
  assert(fixed == 1);
1748
1743
  int value= cmp.compare();
1750
1745
}
1751
1746
 
1752
1747
 
1753
 
int64_t Item_func_strcmp::val_int()
 
1748
longlong Item_func_strcmp::val_int()
1754
1749
{
1755
1750
  assert(fixed == 1);
1756
1751
  String *a=args[0]->val_str(&tmp_value1);
1762
1757
  }
1763
1758
  int value= sortcmp(a,b,cmp.cmp_collation.collation);
1764
1759
  null_value=0;
1765
 
  return !value ? 0 : (value < 0 ? (int64_t) -1 : (int64_t) 1);
 
1760
  return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
1766
1761
}
1767
1762
 
1768
1763
 
1779
1774
    return 0;
1780
1775
  if (negated != ((Item_func_opt_neg *) item_func)->negated)
1781
1776
    return 0;
1782
 
  for (uint32_t i=0; i < arg_count ; i++)
 
1777
  for (uint i=0; i < arg_count ; i++)
1783
1778
    if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
1784
1779
      return 0;
1785
1780
  return 1;
1788
1783
 
1789
1784
void Item_func_interval::fix_length_and_dec()
1790
1785
{
1791
 
  uint32_t rows= row->cols();
1792
 
 
 
1786
  uint rows= row->cols();
 
1787
  
1793
1788
  use_decimal_comparison= ((row->element_index(0)->result_type() ==
1794
1789
                            DECIMAL_RESULT) ||
1795
1790
                           (row->element_index(0)->result_type() ==
1798
1793
  {
1799
1794
    bool not_null_consts= true;
1800
1795
 
1801
 
    for (uint32_t i= 1; not_null_consts && i < rows; i++)
 
1796
    for (uint i= 1; not_null_consts && i < rows; i++)
1802
1797
    {
1803
1798
      Item *el= row->element_index(i);
1804
1799
      not_null_consts&= el->const_item() & !el->is_null();
1806
1801
 
1807
1802
    if (not_null_consts &&
1808
1803
        (intervals=
1809
 
          (interval_range*) memory::sql_alloc(sizeof(interval_range) * (rows - 1))))
 
1804
          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
1810
1805
    {
1811
1806
      if (use_decimal_comparison)
1812
1807
      {
1813
 
        for (uint32_t i= 1; i < rows; i++)
 
1808
        for (uint i= 1; i < rows; i++)
1814
1809
        {
1815
1810
          Item *el= row->element_index(i);
1816
1811
          interval_range *range= intervals + (i-1);
1835
1830
      }
1836
1831
      else
1837
1832
      {
1838
 
        for (uint32_t i= 1; i < rows; i++)
 
1833
        for (uint i= 1; i < rows; i++)
1839
1834
        {
1840
1835
          intervals[i-1].dbl= row->element_index(i)->val_real();
1841
1836
        }
1865
1860
    - arg_count if higher than biggest argument
1866
1861
*/
1867
1862
 
1868
 
int64_t Item_func_interval::val_int()
 
1863
longlong Item_func_interval::val_int()
1869
1864
{
1870
1865
  assert(fixed == 1);
1871
1866
  double value;
1872
1867
  my_decimal dec_buf, *dec= NULL;
1873
 
  uint32_t i;
 
1868
  uint i;
1874
1869
 
1875
1870
  if (use_decimal_comparison)
1876
1871
  {
1888
1883
 
1889
1884
  if (intervals)
1890
1885
  {                                     // Use binary search to find interval
1891
 
    uint32_t start,end;
 
1886
    uint start,end;
1892
1887
    start= 0;
1893
1888
    end=   row->cols()-2;
1894
1889
    while (start != end)
1895
1890
    {
1896
 
      uint32_t mid= (start + end + 1) / 2;
 
1891
      uint mid= (start + end + 1) / 2;
1897
1892
      interval_range *range= intervals + mid;
1898
 
      bool cmp_result;
 
1893
      my_bool cmp_result;
1899
1894
      /*
1900
1895
        The values in the range intervall may have different types,
1901
1896
        Only do a decimal comparision of the first argument is a decimal
1930
1925
      if (my_decimal_cmp(e_dec, dec) > 0)
1931
1926
        return i - 1;
1932
1927
    }
1933
 
    else
 
1928
    else 
1934
1929
    {
1935
1930
      double val= el->val_real();
1936
1931
      /* Skip NULL ranges. */
1952
1947
    The function saves in ref the pointer to the item or to a newly created
1953
1948
    item that is considered as a replacement for the original one.
1954
1949
 
1955
 
  @param session     reference to the global context of the query thread
 
1950
  @param thd     reference to the global context of the query thread
1956
1951
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
1957
1952
                 item is to be assigned
1958
1953
 
1972
1967
    1   got error
1973
1968
*/
1974
1969
 
1975
 
bool Item_func_between::fix_fields(Session *session, Item **ref)
 
1970
bool Item_func_between::fix_fields(THD *thd, Item **ref)
1976
1971
{
1977
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
1972
  if (Item_func_opt_neg::fix_fields(thd, ref))
1978
1973
    return 1;
1979
1974
 
1980
 
  session->lex->current_select->between_count++;
 
1975
  thd->lex->current_select->between_count++;
1981
1976
 
1982
1977
  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1983
1978
  if (pred_level && !negated)
1997
1992
  max_length= 1;
1998
1993
  int i;
1999
1994
  bool datetime_found= false;
 
1995
  int time_items_found= 0;
2000
1996
  compare_as_dates= true;
2001
 
  Session *session= current_session;
 
1997
  THD *thd= current_thd;
2002
1998
 
2003
1999
  /*
2004
2000
    As some compare functions are generated after sql_yacc,
2026
2022
        datetime_found= true;
2027
2023
        continue;
2028
2024
      }
 
2025
      if (args[i]->field_type() == MYSQL_TYPE_TIME &&
 
2026
          args[i]->result_as_longlong())
 
2027
        time_items_found++;
2029
2028
    }
2030
2029
  }
2031
2030
  if (!datetime_found)
2036
2035
    ge_cmp.set_datetime_cmp_func(args, args + 1);
2037
2036
    le_cmp.set_datetime_cmp_func(args, args + 2);
2038
2037
  }
2039
 
  else if (args[0]->real_item()->type() == FIELD_ITEM)
 
2038
  else if (time_items_found == 3)
 
2039
  {
 
2040
    /* Compare TIME items as integers. */
 
2041
    cmp_type= INT_RESULT;
 
2042
  }
 
2043
  else if (args[0]->real_item()->type() == FIELD_ITEM &&
 
2044
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2040
2045
  {
2041
2046
    Item_field *field_item= (Item_field*) (args[0]->real_item());
2042
 
    if (field_item->field->can_be_compared_as_int64_t())
 
2047
    if (field_item->field->can_be_compared_as_longlong())
2043
2048
    {
2044
2049
      /*
2045
2050
        The following can't be recoded with || as convert_constant_item
2046
2051
        changes the argument
2047
2052
      */
2048
 
      if (convert_constant_item(session, field_item, &args[1]))
 
2053
      if (convert_constant_item(thd, field_item, &args[1]))
2049
2054
        cmp_type=INT_RESULT;                    // Works for all types.
2050
 
      if (convert_constant_item(session, field_item, &args[2]))
 
2055
      if (convert_constant_item(thd, field_item, &args[2]))
2051
2056
        cmp_type=INT_RESULT;                    // Works for all types.
2052
2057
    }
2053
2058
  }
2054
2059
}
2055
2060
 
2056
2061
 
2057
 
int64_t Item_func_between::val_int()
 
2062
longlong Item_func_between::val_int()
2058
2063
{                                               // ANSI BETWEEN
2059
2064
  assert(fixed == 1);
2060
2065
  if (compare_as_dates)
2067
2072
    le_res= le_cmp.compare();
2068
2073
 
2069
2074
    if (!args[1]->null_value && !args[2]->null_value)
2070
 
      return (int64_t) ((ge_res >= 0 && le_res <=0) != negated);
 
2075
      return (longlong) ((ge_res >= 0 && le_res <=0) != negated);
2071
2076
    else if (args[1]->null_value)
2072
2077
    {
2073
2078
      null_value= le_res > 0;                   // not null if false range.
2086
2091
    a=args[1]->val_str(&value1);
2087
2092
    b=args[2]->val_str(&value2);
2088
2093
    if (!args[1]->null_value && !args[2]->null_value)
2089
 
      return (int64_t) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
 
2094
      return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
2090
2095
                          sortcmp(value,b,cmp_collation.collation) <= 0) !=
2091
2096
                         negated);
2092
2097
    if (args[1]->null_value && args[2]->null_value)
2104
2109
  }
2105
2110
  else if (cmp_type == INT_RESULT)
2106
2111
  {
2107
 
    int64_t value=args[0]->val_int(), a, b;
 
2112
    longlong value=args[0]->val_int(), a, b;
2108
2113
    if ((null_value=args[0]->null_value))
2109
 
      return 0;
 
2114
      return 0;                                 /* purecov: inspected */
2110
2115
    a=args[1]->val_int();
2111
2116
    b=args[2]->val_int();
2112
2117
    if (!args[1]->null_value && !args[2]->null_value)
2113
 
      return (int64_t) ((value >= a && value <= b) != negated);
 
2118
      return (longlong) ((value >= a && value <= b) != negated);
2114
2119
    if (args[1]->null_value && args[2]->null_value)
2115
2120
      null_value=1;
2116
2121
    else if (args[1]->null_value)
2127
2132
    my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2128
2133
               a_buf, *a_dec, b_buf, *b_dec;
2129
2134
    if ((null_value=args[0]->null_value))
2130
 
      return 0;
 
2135
      return 0;                                 /* purecov: inspected */
2131
2136
    a_dec= args[1]->val_decimal(&a_buf);
2132
2137
    b_dec= args[2]->val_decimal(&b_buf);
2133
2138
    if (!args[1]->null_value && !args[2]->null_value)
2134
 
      return (int64_t) ((my_decimal_cmp(dec, a_dec) >= 0 &&
 
2139
      return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
2135
2140
                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
2136
2141
    if (args[1]->null_value && args[2]->null_value)
2137
2142
      null_value=1;
2144
2149
  {
2145
2150
    double value= args[0]->val_real(),a,b;
2146
2151
    if ((null_value=args[0]->null_value))
2147
 
      return 0;
 
2152
      return 0;                                 /* purecov: inspected */
2148
2153
    a= args[1]->val_real();
2149
2154
    b= args[2]->val_real();
2150
2155
    if (!args[1]->null_value && !args[2]->null_value)
2151
 
      return (int64_t) ((value >= a && value <= b) != negated);
 
2156
      return (longlong) ((value >= a && value <= b) != negated);
2152
2157
    if (args[1]->null_value && args[2]->null_value)
2153
2158
      null_value=1;
2154
2159
    else if (args[1]->null_value)
2160
2165
      null_value= value >= a;
2161
2166
    }
2162
2167
  }
2163
 
  return (int64_t) (!null_value && negated);
 
2168
  return (longlong) (!null_value && negated);
2164
2169
}
2165
2170
 
2166
2171
 
2181
2186
Item_func_ifnull::fix_length_and_dec()
2182
2187
{
2183
2188
  agg_result_type(&hybrid_type, args, 2);
2184
 
  maybe_null= args[1]->maybe_null;
 
2189
  maybe_null=args[1]->maybe_null;
2185
2190
  decimals= max(args[0]->decimals, args[1]->decimals);
2186
2191
  unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2187
2192
 
2188
 
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
 
2193
  if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) 
2189
2194
  {
2190
2195
    int len0= args[0]->max_length - args[0]->decimals
2191
2196
      - (args[0]->unsigned_flag ? 0 : 1);
2196
2201
    max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2197
2202
  }
2198
2203
  else
2199
 
  {
2200
2204
    max_length= max(args[0]->max_length, args[1]->max_length);
2201
 
  }
2202
2205
 
2203
 
  switch (hybrid_type)
2204
 
  {
 
2206
  switch (hybrid_type) {
2205
2207
  case STRING_RESULT:
2206
2208
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2207
2209
    break;
2208
 
 
2209
2210
  case DECIMAL_RESULT:
2210
2211
  case REAL_RESULT:
2211
2212
    break;
2212
 
 
2213
2213
  case INT_RESULT:
2214
2214
    decimals= 0;
2215
2215
    break;
2216
 
 
2217
2216
  case ROW_RESULT:
 
2217
  default:
2218
2218
    assert(0);
2219
2219
  }
2220
 
 
2221
2220
  cached_field_type= agg_field_type(args, 2);
2222
2221
}
2223
2222
 
2224
2223
 
2225
 
uint32_t Item_func_ifnull::decimal_precision() const
 
2224
uint Item_func_ifnull::decimal_precision() const
2226
2225
{
2227
 
  int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
 
2226
  int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2228
2227
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2229
2228
}
2230
2229
 
2231
2230
 
2232
 
enum_field_types Item_func_ifnull::field_type() const
 
2231
enum_field_types Item_func_ifnull::field_type() const 
2233
2232
{
2234
2233
  return cached_field_type;
2235
2234
}
2236
2235
 
2237
 
Field *Item_func_ifnull::tmp_table_field(Table *table)
 
2236
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2238
2237
{
2239
2238
  return tmp_table_field_from_field_type(table, 0);
2240
2239
}
2255
2254
  return value;
2256
2255
}
2257
2256
 
2258
 
int64_t
 
2257
longlong
2259
2258
Item_func_ifnull::int_op()
2260
2259
{
2261
2260
  assert(fixed == 1);
2262
 
  int64_t value=args[0]->val_int();
 
2261
  longlong value=args[0]->val_int();
2263
2262
  if (!args[0]->null_value)
2264
2263
  {
2265
2264
    null_value=0;
2315
2314
    The function saves in ref the pointer to the item or to a newly created
2316
2315
    item that is considered as a replacement for the original one.
2317
2316
 
2318
 
  @param session     reference to the global context of the query thread
 
2317
  @param thd     reference to the global context of the query thread
2319
2318
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
2320
2319
                 item is to be assigned
2321
2320
 
2334
2333
*/
2335
2334
 
2336
2335
bool
2337
 
Item_func_if::fix_fields(Session *session, Item **ref)
 
2336
Item_func_if::fix_fields(THD *thd, Item **ref)
2338
2337
{
2339
2338
  assert(fixed == 0);
2340
2339
  args[0]->top_level_item();
2341
2340
 
2342
 
  if (Item_func::fix_fields(session, ref))
 
2341
  if (Item_func::fix_fields(thd, ref))
2343
2342
    return 1;
2344
2343
 
2345
2344
  not_null_tables_cache= (args[1]->not_null_tables() &
2352
2351
void
2353
2352
Item_func_if::fix_length_and_dec()
2354
2353
{
2355
 
  maybe_null= args[1]->maybe_null || args[2]->maybe_null;
 
2354
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2356
2355
  decimals= max(args[1]->decimals, args[2]->decimals);
2357
 
  unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
 
2356
  unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2358
2357
 
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;
 
2358
  enum Item_result arg1_type=args[1]->result_type();
 
2359
  enum Item_result arg2_type=args[2]->result_type();
 
2360
  bool null1=args[1]->const_item() && args[1]->null_value;
 
2361
  bool null2=args[2]->const_item() && args[2]->null_value;
2363
2362
 
2364
2363
  if (null1)
2365
2364
  {
2397
2396
    int len2= args[2]->max_length - args[2]->decimals
2398
2397
      - (args[2]->unsigned_flag ? 0 : 1);
2399
2398
 
2400
 
    max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
 
2399
    max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2401
2400
  }
2402
2401
  else
2403
2402
    max_length= max(args[1]->max_length, args[2]->max_length);
2404
2403
}
2405
2404
 
2406
2405
 
2407
 
uint32_t Item_func_if::decimal_precision() const
 
2406
uint Item_func_if::decimal_precision() const
2408
2407
{
2409
 
  int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2410
 
                  decimals);
 
2408
  int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
 
2409
                 decimals);
2411
2410
  return min(precision, DECIMAL_MAX_PRECISION);
2412
2411
}
2413
2412
 
2422
2421
  return value;
2423
2422
}
2424
2423
 
2425
 
int64_t
 
2424
longlong
2426
2425
Item_func_if::val_int()
2427
2426
{
2428
2427
  assert(fixed == 1);
2429
2428
  Item *arg= args[0]->val_bool() ? args[1] : args[2];
2430
 
  int64_t value=arg->val_int();
 
2429
  longlong value=arg->val_int();
2431
2430
  null_value=arg->null_value;
2432
2431
  return value;
2433
2432
}
2499
2498
  return value;
2500
2499
}
2501
2500
 
2502
 
int64_t
 
2501
longlong
2503
2502
Item_func_nullif::val_int()
2504
2503
{
2505
2504
  assert(fixed == 1);
2506
 
  int64_t value;
 
2505
  longlong value;
2507
2506
  if (!cmp.compare())
2508
2507
  {
2509
2508
    null_value=1;
2549
2548
bool
2550
2549
Item_func_nullif::is_null()
2551
2550
{
2552
 
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
 
2551
  return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); 
2553
2552
}
2554
2553
 
2555
2554
 
2574
2573
           failed
2575
2574
*/
2576
2575
 
2577
 
Item *Item_func_case::find_item(String *)
 
2576
Item *Item_func_case::find_item(String *str __attribute__((__unused__)))
2578
2577
{
2579
 
  uint32_t value_added_map= 0;
 
2578
  uint value_added_map= 0;
2580
2579
 
2581
2580
  if (first_expr_num == -1)
2582
2581
  {
2583
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2582
    for (uint i=0 ; i < ncases ; i+=2)
2584
2583
    {
2585
2584
      // No expression between CASE and the first WHEN
2586
2585
      if (args[i]->val_bool())
2591
2590
  else
2592
2591
  {
2593
2592
    /* Compare every WHEN argument with it and return the first match */
2594
 
    for (uint32_t i=0 ; i < ncases ; i+=2)
 
2593
    for (uint i=0 ; i < ncases ; i+=2)
2595
2594
    {
2596
2595
      cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2597
2596
      assert(cmp_type != ROW_RESULT);
2598
 
      assert(cmp_items[(uint32_t)cmp_type]);
2599
 
      if (!(value_added_map & (1<<(uint32_t)cmp_type)))
 
2597
      assert(cmp_items[(uint)cmp_type]);
 
2598
      if (!(value_added_map & (1<<(uint)cmp_type)))
2600
2599
      {
2601
 
        cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
 
2600
        cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2602
2601
        if ((null_value=args[first_expr_num]->null_value))
2603
2602
          return else_expr_num != -1 ? args[else_expr_num] : 0;
2604
 
        value_added_map|= 1<<(uint32_t)cmp_type;
 
2603
        value_added_map|= 1<<(uint)cmp_type;
2605
2604
      }
2606
 
      if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
 
2605
      if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2607
2606
        return args[i + 1];
2608
2607
    }
2609
2608
  }
2630
2629
}
2631
2630
 
2632
2631
 
2633
 
int64_t Item_func_case::val_int()
 
2632
longlong Item_func_case::val_int()
2634
2633
{
2635
2634
  assert(fixed == 1);
2636
2635
  char buff[MAX_FIELD_WIDTH];
2637
2636
  String dummy_str(buff,sizeof(buff),default_charset());
2638
2637
  Item *item=find_item(&dummy_str);
2639
 
  int64_t res;
 
2638
  longlong res;
2640
2639
 
2641
2640
  if (!item)
2642
2641
  {
2687
2686
}
2688
2687
 
2689
2688
 
2690
 
bool Item_func_case::fix_fields(Session *session, Item **ref)
 
2689
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2691
2690
{
2692
2691
  /*
2693
2692
    buff should match stack usage from
2694
2693
    Item_func_case::val_int() -> Item_func_case::find_item()
2695
2694
  */
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);
 
2695
  uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2];
 
2696
  bool res= Item_func::fix_fields(thd, ref);
2699
2697
  /*
2700
2698
    Call check_stack_overrun after fix_fields to be sure that stack variable
2701
2699
    is not optimized away
2702
2700
  */
2703
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
2701
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2704
2702
    return true;                                // Fatal error flag is set!
2705
2703
  return res;
2706
2704
}
2716
2714
 
2717
2715
void Item_func_case::agg_num_lengths(Item *arg)
2718
2716
{
2719
 
  uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
 
2717
  uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2720
2718
                                           arg->unsigned_flag) - arg->decimals;
2721
 
  set_if_bigger(max_length, len);
 
2719
  set_if_bigger(max_length, len); 
2722
2720
  set_if_bigger(decimals, arg->decimals);
2723
 
  unsigned_flag= unsigned_flag && arg->unsigned_flag;
 
2721
  unsigned_flag= unsigned_flag && arg->unsigned_flag; 
2724
2722
}
2725
2723
 
2726
2724
 
2727
2725
void Item_func_case::fix_length_and_dec()
2728
2726
{
2729
2727
  Item **agg;
2730
 
  uint32_t nagg;
2731
 
  uint32_t found_types= 0;
2732
 
  if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
 
2728
  uint nagg;
 
2729
  uint found_types= 0;
 
2730
  if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2733
2731
    return;
2734
 
 
 
2732
  
2735
2733
  /*
2736
2734
    Aggregate all THEN and ELSE expression types
2737
2735
    and collations when string result
2738
2736
  */
2739
 
 
 
2737
  
2740
2738
  for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2741
2739
    agg[nagg]= args[nagg*2+1];
2742
 
 
 
2740
  
2743
2741
  if (else_expr_num != -1)
2744
2742
    agg[nagg++]= args[else_expr_num];
2745
 
 
 
2743
  
2746
2744
  agg_result_type(&cached_result_type, agg, nagg);
2747
2745
  if ((cached_result_type == STRING_RESULT) &&
2748
2746
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2749
2747
    return;
2750
 
 
 
2748
  
2751
2749
  cached_field_type= agg_field_type(agg, nagg);
2752
2750
  /*
2753
2751
    Aggregate first expression and all THEN expression types
2755
2753
  */
2756
2754
  if (first_expr_num != -1)
2757
2755
  {
 
2756
    uint i;
2758
2757
    agg[0]= args[first_expr_num];
2759
2758
    left_result_type= agg[0]->result_type();
2760
2759
 
2764
2763
    if (!(found_types= collect_cmp_types(agg, nagg)))
2765
2764
      return;
2766
2765
 
2767
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2766
    for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2768
2767
    {
2769
2768
      if (found_types & (1 << i) && !cmp_items[i])
2770
2769
      {
2782
2781
 
2783
2782
  if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
2784
2783
    maybe_null=1;
2785
 
 
 
2784
  
2786
2785
  max_length=0;
2787
2786
  decimals=0;
2788
2787
  unsigned_flag= true;
2789
2788
  if (cached_result_type == STRING_RESULT)
2790
2789
  {
2791
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2790
    for (uint i= 0; i < ncases; i+= 2)
2792
2791
      agg_str_lengths(args[i + 1]);
2793
2792
    if (else_expr_num != -1)
2794
2793
      agg_str_lengths(args[else_expr_num]);
2795
2794
  }
2796
2795
  else
2797
2796
  {
2798
 
    for (uint32_t i= 0; i < ncases; i+= 2)
 
2797
    for (uint i= 0; i < ncases; i+= 2)
2799
2798
      agg_num_lengths(args[i + 1]);
2800
 
    if (else_expr_num != -1)
 
2799
    if (else_expr_num != -1) 
2801
2800
      agg_num_lengths(args[else_expr_num]);
2802
2801
    max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2803
2802
                                               unsigned_flag);
2805
2804
}
2806
2805
 
2807
2806
 
2808
 
uint32_t Item_func_case::decimal_precision() const
 
2807
uint Item_func_case::decimal_precision() const
2809
2808
{
2810
2809
  int max_int_part=0;
2811
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2810
  for (uint i=0 ; i < ncases ; i+=2)
2812
2811
    set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2813
2812
 
2814
 
  if (else_expr_num != -1)
 
2813
  if (else_expr_num != -1) 
2815
2814
    set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2816
2815
  return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2817
2816
}
2830
2829
    args[first_expr_num]->print(str, query_type);
2831
2830
    str->append(' ');
2832
2831
  }
2833
 
  for (uint32_t i=0 ; i < ncases ; i+=2)
 
2832
  for (uint i=0 ; i < ncases ; i+=2)
2834
2833
  {
2835
2834
    str->append(STRING_WITH_LEN("when "));
2836
2835
    args[i]->print(str, query_type);
2850
2849
 
2851
2850
void Item_func_case::cleanup()
2852
2851
{
 
2852
  uint i;
2853
2853
  Item_func::cleanup();
2854
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
2854
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2855
2855
  {
2856
2856
    delete cmp_items[i];
2857
2857
    cmp_items[i]= 0;
2858
2858
  }
 
2859
  return;
2859
2860
}
2860
2861
 
2861
2862
 
2867
2868
{
2868
2869
  assert(fixed == 1);
2869
2870
  null_value=0;
2870
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2871
  for (uint i=0 ; i < arg_count ; i++)
2871
2872
  {
2872
2873
    String *res;
2873
2874
    if ((res=args[i]->val_str(str)))
2877
2878
  return 0;
2878
2879
}
2879
2880
 
2880
 
int64_t Item_func_coalesce::int_op()
 
2881
longlong Item_func_coalesce::int_op()
2881
2882
{
2882
2883
  assert(fixed == 1);
2883
2884
  null_value=0;
2884
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2885
  for (uint i=0 ; i < arg_count ; i++)
2885
2886
  {
2886
 
    int64_t res=args[i]->val_int();
 
2887
    longlong res=args[i]->val_int();
2887
2888
    if (!args[i]->null_value)
2888
2889
      return res;
2889
2890
  }
2895
2896
{
2896
2897
  assert(fixed == 1);
2897
2898
  null_value=0;
2898
 
  for (uint32_t i=0 ; i < arg_count ; i++)
 
2899
  for (uint i=0 ; i < arg_count ; i++)
2899
2900
  {
2900
2901
    double res= args[i]->val_real();
2901
2902
    if (!args[i]->null_value)
2910
2911
{
2911
2912
  assert(fixed == 1);
2912
2913
  null_value= 0;
2913
 
  for (uint32_t i= 0; i < arg_count; i++)
 
2914
  for (uint i= 0; i < arg_count; i++)
2914
2915
  {
2915
2916
    my_decimal *res= args[i]->val_decimal(decimal_value);
2916
2917
    if (!args[i]->null_value)
2925
2926
{
2926
2927
  cached_field_type= agg_field_type(args, arg_count);
2927
2928
  agg_result_type(&hybrid_type, args, arg_count);
2928
 
 
2929
2929
  switch (hybrid_type) {
2930
2930
  case STRING_RESULT:
2931
2931
    count_only_length();
2932
2932
    decimals= NOT_FIXED_DEC;
2933
2933
    agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1);
2934
2934
    break;
2935
 
 
2936
2935
  case DECIMAL_RESULT:
2937
2936
    count_decimal_length();
2938
2937
    break;
2939
 
 
2940
2938
  case REAL_RESULT:
2941
2939
    count_real_length();
2942
2940
    break;
2943
 
 
2944
2941
  case INT_RESULT:
2945
2942
    count_only_length();
2946
2943
    decimals= 0;
2947
2944
    break;
2948
 
 
2949
2945
  case ROW_RESULT:
 
2946
  default:
2950
2947
    assert(0);
2951
2948
  }
2952
2949
}
2956
2953
****************************************************************************/
2957
2954
 
2958
2955
/*
2959
 
  Determine which of the signed int64_t arguments is bigger
 
2956
  Determine which of the signed longlong arguments is bigger
2960
2957
 
2961
2958
  SYNOPSIS
2962
2959
    cmp_longs()
2964
2961
      b_val     right argument
2965
2962
 
2966
2963
  DESCRIPTION
2967
 
    This function will compare two signed int64_t arguments
 
2964
    This function will compare two signed longlong arguments
2968
2965
    and will return -1, 0, or 1 if left argument is smaller than,
2969
2966
    equal to or greater than the right argument.
2970
2967
 
2973
2970
    0           left argument is equal to the right argument.
2974
2971
    1           left argument is greater than the right argument.
2975
2972
*/
2976
 
static inline int cmp_longs (int64_t a_val, int64_t b_val)
 
2973
static inline int cmp_longs (longlong a_val, longlong b_val)
2977
2974
{
2978
2975
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
2979
2976
}
2980
2977
 
2981
2978
 
2982
2979
/*
2983
 
  Determine which of the unsigned int64_t arguments is bigger
 
2980
  Determine which of the unsigned longlong arguments is bigger
2984
2981
 
2985
2982
  SYNOPSIS
2986
2983
    cmp_ulongs()
2988
2985
      b_val     right argument
2989
2986
 
2990
2987
  DESCRIPTION
2991
 
    This function will compare two unsigned int64_t arguments
 
2988
    This function will compare two unsigned longlong arguments
2992
2989
    and will return -1, 0, or 1 if left argument is smaller than,
2993
2990
    equal to or greater than the right argument.
2994
2991
 
2997
2994
    0           left argument is equal to the right argument.
2998
2995
    1           left argument is greater than the right argument.
2999
2996
*/
3000
 
static inline int cmp_ulongs (uint64_t a_val, uint64_t b_val)
 
2997
static inline int cmp_ulongs (ulonglong a_val, ulonglong b_val)
3001
2998
{
3002
2999
  return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
3003
3000
}
3004
3001
 
3005
3002
 
3006
3003
/*
3007
 
  Compare two integers in IN value list format (packed_int64_t)
 
3004
  Compare two integers in IN value list format (packed_longlong) 
3008
3005
 
3009
3006
  SYNOPSIS
3010
 
    cmp_int64_t()
 
3007
    cmp_longlong()
3011
3008
      cmp_arg   an argument passed to the calling function (my_qsort2)
3012
3009
      a         left argument
3013
3010
      b         right argument
3017
3014
    format and will return -1, 0, or 1 if left argument is smaller than,
3018
3015
    equal to or greater than the right argument.
3019
3016
    It's used in sorting the IN values list and finding an element in it.
3020
 
    Depending on the signedness of the arguments cmp_int64_t() will
 
3017
    Depending on the signedness of the arguments cmp_longlong() will
3021
3018
    compare them as either signed (using cmp_longs()) or unsigned (using
3022
3019
    cmp_ulongs()).
3023
3020
 
3026
3023
    0           left argument is equal to the right argument.
3027
3024
    1           left argument is greater than the right argument.
3028
3025
*/
3029
 
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3030
 
                in_int64_t::packed_int64_t *b)
 
3026
int cmp_longlong(void *cmp_arg __attribute__((__unused__)),
 
3027
                 in_longlong::packed_longlong *a,
 
3028
                 in_longlong::packed_longlong *b)
3031
3029
{
3032
3030
  if (a->unsigned_flag != b->unsigned_flag)
3033
 
  {
3034
 
    /*
3035
 
      One of the args is unsigned and is too big to fit into the
 
3031
  { 
 
3032
    /* 
 
3033
      One of the args is unsigned and is too big to fit into the 
3036
3034
      positive signed range. Report no match.
3037
 
    */
3038
 
    if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3039
 
        (b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
 
3035
    */  
 
3036
    if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) ||
 
3037
        (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX))
3040
3038
      return a->unsigned_flag ? 1 : -1;
3041
3039
    /*
3042
 
      Although the signedness differs both args can fit into the signed
 
3040
      Although the signedness differs both args can fit into the signed 
3043
3041
      positive range. Make them signed and compare as usual.
3044
 
    */
 
3042
    */  
3045
3043
    return cmp_longs (a->val, b->val);
3046
3044
  }
3047
3045
  if (a->unsigned_flag)
3048
 
    return cmp_ulongs ((uint64_t) a->val, (uint64_t) b->val);
 
3046
    return cmp_ulongs ((ulonglong) a->val, (ulonglong) b->val);
3049
3047
  else
3050
3048
    return cmp_longs (a->val, b->val);
3051
3049
}
3052
3050
 
3053
 
static int cmp_double(void *, double *a, double *b)
 
3051
static int cmp_double(void *cmp_arg __attribute__((__unused__)), double *a,double *b)
3054
3052
{
3055
3053
  return *a < *b ? -1 : *a == *b ? 0 : 1;
3056
3054
}
3057
3055
 
3058
 
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
 
3056
static int cmp_row(void *cmp_arg __attribute__((__unused__)), cmp_item_row *a, cmp_item_row *b)
3059
3057
{
3060
3058
  return a->compare(b);
3061
3059
}
3062
3060
 
3063
3061
 
3064
 
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
 
3062
static int cmp_decimal(void *cmp_arg __attribute__((__unused__)), my_decimal *a, my_decimal *b)
3065
3063
{
3066
3064
  /*
3067
3065
    We need call of fixing buffer pointer, because fast sort just copy
3073
3071
}
3074
3072
 
3075
3073
 
3076
 
void in_vector::sort()
3077
 
{
3078
 
  internal::my_qsort2(base,used_count,size,compare, (void *) collation);
3079
 
}
3080
 
 
3081
 
 
3082
3074
int in_vector::find(Item *item)
3083
3075
{
3084
 
  unsigned char *result=get_value(item);
 
3076
  uchar *result=get_value(item);
3085
3077
  if (!result || !used_count)
3086
3078
    return 0;                           // Null value
3087
3079
 
3088
 
  uint32_t start,end;
 
3080
  uint start,end;
3089
3081
  start=0; end=used_count-1;
3090
3082
  while (start != end)
3091
3083
  {
3092
 
    uint32_t mid=(start+end+1)/2;
 
3084
    uint mid=(start+end+1)/2;
3093
3085
    int res;
3094
3086
    if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3095
3087
      return 1;
3101
3093
  return (int) ((*compare)(collation, base+start*size, result) == 0);
3102
3094
}
3103
3095
 
3104
 
in_string::in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs)
 
3096
in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs)
3105
3097
  :in_vector(elements, sizeof(String), cmp_func, cs),
3106
3098
   tmp(buff, sizeof(buff), &my_charset_bin)
3107
3099
{}
3110
3102
{
3111
3103
  if (base)
3112
3104
  {
3113
 
    // base was allocated with help of memory::sql_alloc => following is OK
3114
 
    for (uint32_t i=0 ; i < count ; i++)
 
3105
    // base was allocated with help of sql_alloc => following is OK
 
3106
    for (uint i=0 ; i < count ; i++)
3115
3107
      ((String*) base)[i].free();
3116
3108
  }
3117
3109
}
3118
3110
 
3119
 
void in_string::set(uint32_t pos,Item *item)
 
3111
void in_string::set(uint pos,Item *item)
3120
3112
{
3121
3113
  String *str=((String*) base)+pos;
3122
3114
  String *res=item->val_str(str);
3131
3123
  }
3132
3124
  if (!str->charset())
3133
3125
  {
3134
 
    const CHARSET_INFO *cs;
 
3126
    CHARSET_INFO *cs;
3135
3127
    if (!(cs= item->collation.collation))
3136
3128
      cs= &my_charset_bin;              // Should never happen for STR items
3137
3129
    str->set_charset(cs);
3139
3131
}
3140
3132
 
3141
3133
 
3142
 
unsigned char *in_string::get_value(Item *item)
 
3134
uchar *in_string::get_value(Item *item)
3143
3135
{
3144
 
  return (unsigned char*) item->val_str(&tmp);
 
3136
  return (uchar*) item->val_str(&tmp);
3145
3137
}
3146
3138
 
3147
 
in_row::in_row(uint32_t elements, Item *)
 
3139
in_row::in_row(uint elements, Item * item __attribute__((__unused__)))
3148
3140
{
3149
3141
  base= (char*) new cmp_item_row[count= elements];
3150
3142
  size= sizeof(cmp_item_row);
3163
3155
    delete [] (cmp_item_row*) base;
3164
3156
}
3165
3157
 
3166
 
unsigned char *in_row::get_value(Item *item)
 
3158
uchar *in_row::get_value(Item *item)
3167
3159
{
3168
3160
  tmp.store_value(item);
3169
3161
  if (item->is_null())
3170
3162
    return 0;
3171
 
  return (unsigned char *)&tmp;
 
3163
  return (uchar *)&tmp;
3172
3164
}
3173
3165
 
3174
 
void in_row::set(uint32_t pos, Item *item)
 
3166
void in_row::set(uint pos, Item *item)
3175
3167
{
3176
3168
  ((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3177
3169
  return;
3178
3170
}
3179
3171
 
3180
 
in_int64_t::in_int64_t(uint32_t elements)
3181
 
  :in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
 
3172
in_longlong::in_longlong(uint elements)
 
3173
  :in_vector(elements,sizeof(packed_longlong),(qsort2_cmp) cmp_longlong, 0)
3182
3174
{}
3183
3175
 
3184
 
void in_int64_t::set(uint32_t pos,Item *item)
 
3176
void in_longlong::set(uint pos,Item *item)
3185
3177
{
3186
 
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3187
 
 
 
3178
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];
 
3179
  
3188
3180
  buff->val= item->val_int();
3189
3181
  buff->unsigned_flag= item->unsigned_flag;
3190
3182
}
3191
3183
 
3192
 
unsigned char *in_int64_t::get_value(Item *item)
 
3184
uchar *in_longlong::get_value(Item *item)
3193
3185
{
3194
3186
  tmp.val= item->val_int();
3195
3187
  if (item->null_value)
3196
3188
    return 0;
3197
3189
  tmp.unsigned_flag= item->unsigned_flag;
3198
 
  return (unsigned char*) &tmp;
 
3190
  return (uchar*) &tmp;
3199
3191
}
3200
3192
 
3201
 
void in_datetime::set(uint32_t pos,Item *item)
 
3193
void in_datetime::set(uint pos,Item *item)
3202
3194
{
3203
3195
  Item **tmp_item= &item;
3204
3196
  bool is_null;
3205
 
  struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
 
3197
  struct packed_longlong *buff= &((packed_longlong*) base)[pos];
3206
3198
 
3207
 
  buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3199
  buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3208
3200
  buff->unsigned_flag= 1L;
3209
3201
}
3210
3202
 
3211
 
unsigned char *in_datetime::get_value(Item *item)
 
3203
uchar *in_datetime::get_value(Item *item)
3212
3204
{
3213
3205
  bool is_null;
3214
3206
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3215
 
  tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3207
  tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3216
3208
  if (item->null_value)
3217
3209
    return 0;
3218
3210
  tmp.unsigned_flag= 1L;
3219
 
  return (unsigned char*) &tmp;
 
3211
  return (uchar*) &tmp;
3220
3212
}
3221
3213
 
3222
 
in_double::in_double(uint32_t elements)
 
3214
in_double::in_double(uint elements)
3223
3215
  :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3224
3216
{}
3225
3217
 
3226
 
void in_double::set(uint32_t pos,Item *item)
 
3218
void in_double::set(uint pos,Item *item)
3227
3219
{
3228
3220
  ((double*) base)[pos]= item->val_real();
3229
3221
}
3230
3222
 
3231
 
unsigned char *in_double::get_value(Item *item)
 
3223
uchar *in_double::get_value(Item *item)
3232
3224
{
3233
3225
  tmp= item->val_real();
3234
3226
  if (item->null_value)
3235
 
    return 0;
3236
 
  return (unsigned char*) &tmp;
 
3227
    return 0;                                   /* purecov: inspected */
 
3228
  return (uchar*) &tmp;
3237
3229
}
3238
3230
 
3239
3231
 
3240
 
in_decimal::in_decimal(uint32_t elements)
 
3232
in_decimal::in_decimal(uint elements)
3241
3233
  :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3242
3234
{}
3243
3235
 
3244
3236
 
3245
 
void in_decimal::set(uint32_t pos, Item *item)
 
3237
void in_decimal::set(uint pos, Item *item)
3246
3238
{
3247
3239
  /* as far as 'item' is constant, we can store reference on my_decimal */
3248
3240
  my_decimal *dec= ((my_decimal *)base) + pos;
3249
3241
  dec->len= DECIMAL_BUFF_LENGTH;
3250
3242
  dec->fix_buffer_pointer();
3251
3243
  my_decimal *res= item->val_decimal(dec);
3252
 
  /* if item->val_decimal() is evaluated to NULL then res == 0 */
 
3244
  /* if item->val_decimal() is evaluated to NULL then res == 0 */ 
3253
3245
  if (!item->null_value && res != dec)
3254
3246
    my_decimal2decimal(res, dec);
3255
3247
}
3256
3248
 
3257
3249
 
3258
 
unsigned char *in_decimal::get_value(Item *item)
 
3250
uchar *in_decimal::get_value(Item *item)
3259
3251
{
3260
3252
  my_decimal *result= item->val_decimal(&val);
3261
3253
  if (item->null_value)
3262
3254
    return 0;
3263
 
  return (unsigned char *)result;
 
3255
  return (uchar *)result;
3264
3256
}
3265
3257
 
3266
3258
 
3267
3259
cmp_item* cmp_item::get_comparator(Item_result type,
3268
 
                                   const CHARSET_INFO * const cs)
 
3260
                                   CHARSET_INFO *cs)
3269
3261
{
3270
3262
  switch (type) {
3271
3263
  case STRING_RESULT:
3272
3264
    return new cmp_item_sort_string(cs);
3273
 
 
3274
3265
  case INT_RESULT:
3275
3266
    return new cmp_item_int;
3276
 
 
3277
3267
  case REAL_RESULT:
3278
3268
    return new cmp_item_real;
3279
 
 
3280
3269
  case ROW_RESULT:
3281
3270
    return new cmp_item_row;
3282
 
 
3283
3271
  case DECIMAL_RESULT:
3284
3272
    return new cmp_item_decimal;
 
3273
  default:
 
3274
    assert(0);
 
3275
    break;
3285
3276
  }
3286
 
 
3287
3277
  return 0; // to satisfy compiler :)
3288
3278
}
3289
3279
 
3313
3303
{
3314
3304
  if (comparators)
3315
3305
  {
3316
 
    for (uint32_t i= 0; i < n; i++)
 
3306
    for (uint i= 0; i < n; i++)
3317
3307
    {
3318
3308
      if (comparators[i])
3319
3309
        delete comparators[i];
3326
3316
void cmp_item_row::alloc_comparators()
3327
3317
{
3328
3318
  if (!comparators)
3329
 
    comparators= (cmp_item **) current_session->calloc(sizeof(cmp_item *)*n);
 
3319
    comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
3330
3320
}
3331
3321
 
3332
3322
 
3338
3328
  {
3339
3329
    item->bring_value();
3340
3330
    item->null_value= 0;
3341
 
    for (uint32_t i=0; i < n; i++)
 
3331
    for (uint i=0; i < n; i++)
3342
3332
    {
3343
3333
      if (!comparators[i])
3344
3334
        if (!(comparators[i]=
3362
3352
    return;
3363
3353
  }
3364
3354
  n= tmpl->n;
3365
 
  if ((comparators= (cmp_item **) memory::sql_alloc(sizeof(cmp_item *)*n)))
 
3355
  if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
3366
3356
  {
3367
3357
    item->bring_value();
3368
3358
    item->null_value= 0;
3369
 
    for (uint32_t i=0; i < n; i++)
 
3359
    for (uint i=0; i < n; i++)
3370
3360
    {
3371
3361
      if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3372
3362
        break;                                  // new failed
3388
3378
  }
3389
3379
  bool was_null= 0;
3390
3380
  arg->bring_value();
3391
 
  for (uint32_t i=0; i < n; i++)
 
3381
  for (uint i=0; i < n; i++)
3392
3382
  {
3393
3383
    if (comparators[i]->cmp(arg->element_index(i)))
3394
3384
    {
3404
3394
int cmp_item_row::compare(cmp_item *c)
3405
3395
{
3406
3396
  cmp_item_row *l_cmp= (cmp_item_row *) c;
3407
 
  for (uint32_t i=0; i < n; i++)
 
3397
  for (uint i=0; i < n; i++)
3408
3398
  {
3409
3399
    int res;
3410
3400
    if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3449
3439
{
3450
3440
  bool is_null;
3451
3441
  Item **tmp_item= lval_cache ? &lval_cache : &item;
3452
 
  value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
 
3442
  value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3453
3443
}
3454
3444
 
3455
3445
 
3458
3448
  bool is_null;
3459
3449
  Item **tmp_item= &arg;
3460
3450
  return value !=
3461
 
    get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
 
3451
    get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3462
3452
}
3463
3453
 
3464
3454
 
3495
3485
    The function saves in ref the pointer to the item or to a newly created
3496
3486
    item that is considered as a replacement for the original one.
3497
3487
 
3498
 
  @param session     reference to the global context of the query thread
 
3488
  @param thd     reference to the global context of the query thread
3499
3489
  @param ref     pointer to Item* variable where pointer to resulting "fixed"
3500
3490
                 item is to be assigned
3501
3491
 
3516
3506
*/
3517
3507
 
3518
3508
bool
3519
 
Item_func_in::fix_fields(Session *session, Item **ref)
 
3509
Item_func_in::fix_fields(THD *thd, Item **ref)
3520
3510
{
3521
3511
  Item **arg, **arg_end;
3522
3512
 
3523
 
  if (Item_func_opt_neg::fix_fields(session, ref))
 
3513
  if (Item_func_opt_neg::fix_fields(thd, ref))
3524
3514
    return 1;
3525
3515
 
3526
3516
  /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3536
3526
}
3537
3527
 
3538
3528
 
3539
 
static int srtcmp_in(const CHARSET_INFO * const cs, const String *x,const String *y)
 
3529
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
3540
3530
{
3541
3531
  return cs->coll->strnncollsp(cs,
3542
 
                               (unsigned char *) x->ptr(),x->length(),
3543
 
                               (unsigned char *) y->ptr(),y->length(), 0);
 
3532
                               (uchar *) x->ptr(),x->length(),
 
3533
                               (uchar *) y->ptr(),y->length(), 0);
3544
3534
}
3545
3535
 
3546
3536
 
3548
3538
{
3549
3539
  Item **arg, **arg_end;
3550
3540
  bool const_itm= 1;
3551
 
  Session *session= current_session;
 
3541
  THD *thd= current_thd;
3552
3542
  bool datetime_found= false;
3553
3543
  /* true <=> arguments values will be compared as DATETIMEs. */
3554
3544
  bool compare_as_datetime= false;
3555
3545
  Item *date_arg= 0;
3556
 
  uint32_t found_types= 0;
3557
 
  uint32_t type_cnt= 0;
 
3546
  uint found_types= 0;
 
3547
  uint type_cnt= 0, i;
3558
3548
  Item_result cmp_type= STRING_RESULT;
3559
3549
  left_result_type= args[0]->result_type();
3560
 
  if (!(found_types= collect_cmp_types(args, arg_count, true)))
 
3550
  if (!(found_types= collect_cmp_types(args, arg_count)))
3561
3551
    return;
3562
 
 
 
3552
  
3563
3553
  for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3564
3554
  {
3565
3555
    if (!arg[0]->const_item())
3568
3558
      break;
3569
3559
    }
3570
3560
  }
3571
 
  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3561
  for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
3572
3562
  {
3573
3563
    if (found_types & 1 << i)
3574
3564
    {
3579
3569
 
3580
3570
  if (type_cnt == 1)
3581
3571
  {
3582
 
    if (cmp_type == STRING_RESULT &&
 
3572
    if (cmp_type == STRING_RESULT && 
3583
3573
        agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3584
3574
      return;
3585
3575
    arg_types_compatible= true;
3610
3600
    /* All DATE/DATETIME fields/functions has the STRING result type. */
3611
3601
    if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3612
3602
    {
3613
 
      uint32_t col, num_cols= args[0]->cols();
 
3603
      uint col, cols= args[0]->cols();
3614
3604
 
3615
 
      for (col= 0; col < num_cols; col++)
 
3605
      for (col= 0; col < cols; col++)
3616
3606
      {
3617
3607
        bool skip_column= false;
3618
3608
        /*
3637
3627
            */
3638
3628
            if (!date_arg)
3639
3629
              date_arg= itm;
3640
 
            else if (itm->field_type() == DRIZZLE_TYPE_DATETIME)
 
3630
            else if (itm->field_type() == MYSQL_TYPE_DATETIME)
3641
3631
            {
3642
3632
              date_arg= itm;
3643
3633
              /* All arguments are already checked to have the STRING result. */
3675
3665
  if (type_cnt == 1 && const_itm && !nulls_in_row())
3676
3666
  {
3677
3667
    if (compare_as_datetime)
3678
 
    {
3679
3668
      array= new in_datetime(date_arg, arg_count - 1);
3680
 
    }
3681
3669
    else
3682
3670
    {
3683
3671
      /*
3684
3672
        IN must compare INT columns and constants as int values (the same
3685
3673
        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
 
3674
        So we must check here if the column on the left and all the constant 
 
3675
        values on the right can be compared as integers and adjust the 
3688
3676
        comparison type accordingly.
3689
 
      */
 
3677
      */  
3690
3678
      if (args[0]->real_item()->type() == FIELD_ITEM &&
 
3679
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3691
3680
          cmp_type != INT_RESULT)
3692
3681
      {
3693
3682
        Item_field *field_item= (Item_field*) (args[0]->real_item());
3694
 
        if (field_item->field->can_be_compared_as_int64_t())
 
3683
        if (field_item->field->can_be_compared_as_longlong())
3695
3684
        {
3696
3685
          bool all_converted= true;
3697
3686
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3698
3687
          {
3699
 
            if (!convert_constant_item (session, field_item, &arg[0]))
 
3688
            if (!convert_constant_item (thd, field_item, &arg[0]))
3700
3689
              all_converted= false;
3701
3690
          }
3702
3691
          if (all_converted)
3703
3692
            cmp_type= INT_RESULT;
3704
3693
        }
3705
3694
      }
3706
 
 
3707
3695
      switch (cmp_type) {
3708
3696
      case STRING_RESULT:
3709
 
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
 
3697
        array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, 
3710
3698
                            cmp_collation.collation);
3711
3699
        break;
3712
 
 
3713
3700
      case INT_RESULT:
3714
 
        array= new in_int64_t(arg_count-1);
 
3701
        array= new in_longlong(arg_count-1);
3715
3702
        break;
3716
 
 
3717
3703
      case REAL_RESULT:
3718
3704
        array= new in_double(arg_count-1);
3719
3705
        break;
3720
 
 
3721
3706
      case ROW_RESULT:
3722
3707
        /*
3723
3708
          The row comparator was created at the beginning but only DATETIME
3726
3711
        */
3727
3712
        ((in_row*)array)->tmp.store_value(args[0]);
3728
3713
        break;
3729
 
 
3730
3714
      case DECIMAL_RESULT:
3731
3715
        array= new in_decimal(arg_count - 1);
3732
3716
        break;
 
3717
      default:
 
3718
        assert(0);
 
3719
        return;
3733
3720
      }
3734
3721
    }
3735
 
 
3736
 
    if (array && !(session->is_fatal_error))            // If not EOM
 
3722
    if (array && !(thd->is_fatal_error))                // If not EOM
3737
3723
    {
3738
 
      uint32_t j=0;
3739
 
      for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
 
3724
      uint j=0;
 
3725
      for (uint i=1 ; i < arg_count ; i++)
3740
3726
      {
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;
 
3727
        array->set(j,args[i]);
 
3728
        if (!args[i]->null_value)                       // Skip NULL values
 
3729
          j++;
 
3730
        else
 
3731
          have_null= 1;
3748
3732
      }
3749
3733
      if ((array->used_count= j))
3750
 
        array->sort();
 
3734
        array->sort();
3751
3735
    }
3752
3736
  }
3753
3737
  else
3756
3740
      cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
3757
3741
    else
3758
3742
    {
3759
 
      for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
3743
      for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
3760
3744
      {
3761
3745
        if (found_types & (1 << i) && !cmp_items[i])
3762
3746
        {
3813
3797
    Value of the function
3814
3798
*/
3815
3799
 
3816
 
int64_t Item_func_in::val_int()
 
3800
longlong Item_func_in::val_int()
3817
3801
{
3818
3802
  cmp_item *in_item;
3819
3803
  assert(fixed == 1);
3820
 
  uint32_t value_added_map= 0;
 
3804
  uint value_added_map= 0;
3821
3805
  if (array)
3822
3806
  {
3823
3807
    int tmp=array->find(args[0]);
3824
3808
    null_value=args[0]->null_value || (!tmp && have_null);
3825
 
    return (int64_t) (!null_value && tmp != negated);
 
3809
    return (longlong) (!null_value && tmp != negated);
3826
3810
  }
3827
3811
 
3828
 
  for (uint32_t i= 1 ; i < arg_count ; i++)
 
3812
  for (uint i= 1 ; i < arg_count ; i++)
3829
3813
  {
3830
3814
    Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3831
 
    in_item= cmp_items[(uint32_t)cmp_type];
 
3815
    in_item= cmp_items[(uint)cmp_type];
3832
3816
    assert(in_item);
3833
 
    if (!(value_added_map & (1 << (uint32_t)cmp_type)))
 
3817
    if (!(value_added_map & (1 << (uint)cmp_type)))
3834
3818
    {
3835
3819
      in_item->store_value(args[0]);
3836
3820
      if ((null_value=args[0]->null_value))
3837
3821
        return 0;
3838
3822
      have_null= 0;
3839
 
      value_added_map|= 1 << (uint32_t)cmp_type;
 
3823
      value_added_map|= 1 << (uint)cmp_type;
3840
3824
    }
3841
3825
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
3842
 
      return (int64_t) (!negated);
 
3826
      return (longlong) (!negated);
3843
3827
    have_null|= args[i]->null_value;
3844
3828
  }
3845
3829
 
3846
3830
  null_value= have_null;
3847
 
  return (int64_t) (!null_value && negated);
3848
 
}
3849
 
 
3850
 
 
3851
 
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
 
  :Item_bool_func(session, item),
 
3831
  return (longlong) (!null_value && negated);
 
3832
}
 
3833
 
 
3834
 
 
3835
longlong Item_func_bit_or::val_int()
 
3836
{
 
3837
  assert(fixed == 1);
 
3838
  ulonglong arg1= (ulonglong) args[0]->val_int();
 
3839
  if (args[0]->null_value)
 
3840
  {
 
3841
    null_value=1; /* purecov: inspected */
 
3842
    return 0; /* purecov: inspected */
 
3843
  }
 
3844
  ulonglong arg2= (ulonglong) args[1]->val_int();
 
3845
  if (args[1]->null_value)
 
3846
  {
 
3847
    null_value=1;
 
3848
    return 0;
 
3849
  }
 
3850
  null_value=0;
 
3851
  return (longlong) (arg1 | arg2);
 
3852
}
 
3853
 
 
3854
 
 
3855
longlong Item_func_bit_and::val_int()
 
3856
{
 
3857
  assert(fixed == 1);
 
3858
  ulonglong arg1= (ulonglong) args[0]->val_int();
 
3859
  if (args[0]->null_value)
 
3860
  {
 
3861
    null_value=1; /* purecov: inspected */
 
3862
    return 0; /* purecov: inspected */
 
3863
  }
 
3864
  ulonglong arg2= (ulonglong) args[1]->val_int();
 
3865
  if (args[1]->null_value)
 
3866
  {
 
3867
    null_value=1; /* purecov: inspected */
 
3868
    return 0; /* purecov: inspected */
 
3869
  }
 
3870
  null_value=0;
 
3871
  return (longlong) (arg1 & arg2);
 
3872
}
 
3873
 
 
3874
Item_cond::Item_cond(THD *thd, Item_cond *item)
 
3875
  :Item_bool_func(thd, item),
3853
3876
   abort_on_null(item->abort_on_null),
3854
3877
   and_tables_cache(item->and_tables_cache)
3855
3878
{
3859
3882
}
3860
3883
 
3861
3884
 
3862
 
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
 
3885
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3863
3886
{
3864
3887
  List_iterator_fast<Item> li(item->list);
3865
3888
  while (Item *it= li++)
3866
 
    list.push_back(it->copy_andor_structure(session));
 
3889
    list.push_back(it->copy_andor_structure(thd));
3867
3890
}
3868
3891
 
3869
3892
 
3870
3893
bool
3871
 
Item_cond::fix_fields(Session *session, Item **)
 
3894
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
3872
3895
{
3873
3896
  assert(fixed == 0);
3874
3897
  List_iterator<Item> li(list);
3875
3898
  Item *item;
3876
 
  void *orig_session_marker= session->session_marker;
3877
 
  unsigned char buff[sizeof(char*)];                    // Max local vars in function
 
3899
  void *orig_thd_marker= thd->thd_marker;
 
3900
  uchar buff[sizeof(char*)];                    // Max local vars in function
3878
3901
  not_null_tables_cache= used_tables_cache= 0;
3879
3902
  const_item_cache= 1;
3880
3903
 
3881
3904
  if (functype() == COND_OR_FUNC)
3882
 
    session->session_marker= 0;
 
3905
    thd->thd_marker= 0;
3883
3906
  /*
3884
3907
    and_table_cache is the value that Item_cond_or() returns for
3885
3908
    not_null_tables()
3886
3909
  */
3887
3910
  and_tables_cache= ~(table_map) 0;
3888
3911
 
3889
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
3912
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3890
3913
    return true;                                // Fatal error flag is set!
3891
3914
  /*
3892
3915
    The following optimization reduces the depth of an AND-OR tree.
3919
3942
 
3920
3943
    // item can be substituted in fix_fields
3921
3944
    if ((!item->fixed &&
3922
 
         item->fix_fields(session, li.ref())) ||
 
3945
         item->fix_fields(thd, li.ref())) ||
3923
3946
        (item= *li.ref())->check_cols(1))
3924
 
      return true;
 
3947
      return true; /* purecov: inspected */
3925
3948
    used_tables_cache|=     item->used_tables();
3926
3949
    if (item->const_item())
3927
3950
      and_tables_cache= (table_map) 0;
3931
3954
      not_null_tables_cache|= tmp_table_map;
3932
3955
      and_tables_cache&= tmp_table_map;
3933
3956
      const_item_cache= false;
3934
 
    }
 
3957
    }  
3935
3958
    with_sum_func=          with_sum_func || item->with_sum_func;
3936
3959
    with_subselect|=        item->with_subselect;
3937
3960
    if (item->maybe_null)
3938
3961
      maybe_null=1;
3939
3962
  }
3940
 
  session->lex->current_select->cond_count+= list.elements;
3941
 
  session->session_marker= orig_session_marker;
 
3963
  thd->lex->current_select->cond_count+= list.elements;
 
3964
  thd->thd_marker= orig_thd_marker;
3942
3965
  fix_length_and_dec();
3943
3966
  fixed= 1;
3944
3967
  return false;
3945
3968
}
3946
3969
 
3947
3970
 
3948
 
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
 
3971
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((__unused__)))
3949
3972
{
3950
3973
  List_iterator<Item> li(list);
3951
3974
  Item *item;
3972
3995
      not_null_tables_cache|= tmp_table_map;
3973
3996
      and_tables_cache&= tmp_table_map;
3974
3997
      const_item_cache= false;
3975
 
    }
 
3998
    }  
3976
3999
  }
3977
4000
}
3978
4001
 
3979
4002
 
3980
 
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
4003
bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
3981
4004
{
3982
4005
  List_iterator_fast<Item> li(list);
3983
4006
  Item *item;
3990
4013
 
3991
4014
/**
3992
4015
  Transform an Item_cond object with a transformer callback function.
3993
 
 
 
4016
  
3994
4017
    The function recursively applies the transform method to each
3995
4018
     member item of the condition list.
3996
4019
    If the call of the method for a member item returns a new item
3997
4020
    the old item is substituted for a new one.
3998
4021
    After this the transformer is applied to the root node
3999
 
    of the Item_cond object.
4000
 
 
 
4022
    of the Item_cond object. 
 
4023
     
4001
4024
  @param transformer   the transformer callback function to be applied to
4002
4025
                       the nodes of the tree of the object
4003
4026
  @param arg           parameter to be passed to the transformer
4004
4027
 
4005
4028
  @return
4006
 
    Item returned as the result of transformation of the root node
 
4029
    Item returned as the result of transformation of the root node 
4007
4030
*/
4008
4031
 
4009
 
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
 
4032
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
4010
4033
{
4011
4034
  List_iterator<Item> li(list);
4012
4035
  Item *item;
4017
4040
      return 0;
4018
4041
 
4019
4042
    /*
4020
 
      Session::change_item_tree() should be called only if the tree was
 
4043
      THD::change_item_tree() should be called only if the tree was
4021
4044
      really transformed, i.e. when a new item has been created.
4022
4045
      Otherwise we'll be allocating a lot of unnecessary memory for
4023
4046
      change records at each execution.
4024
4047
    */
4025
4048
    if (new_item != item)
4026
 
      current_session->change_item_tree(li.ref(), new_item);
 
4049
      current_thd->change_item_tree(li.ref(), new_item);
4027
4050
  }
4028
4051
  return Item_func::transform(transformer, arg);
4029
4052
}
4032
4055
/**
4033
4056
  Compile Item_cond object with a processor and a transformer
4034
4057
  callback functions.
4035
 
 
 
4058
  
4036
4059
    First the function applies the analyzer to the root node of
4037
4060
    the Item_func object. Then if the analyzer succeeeds (returns true)
4038
4061
    the function recursively applies the compile method to member
4040
4063
    If the call of the method for a member item returns a new item
4041
4064
    the old item is substituted for a new one.
4042
4065
    After this the transformer is applied to the root node
4043
 
    of the Item_cond object.
4044
 
 
 
4066
    of the Item_cond object. 
 
4067
     
4045
4068
  @param analyzer      the analyzer callback function to be applied to the
4046
4069
                       nodes of the tree of the object
4047
4070
  @param[in,out] arg_p parameter to be passed to the analyzer
4050
4073
  @param arg_t         parameter to be passed to the transformer
4051
4074
 
4052
4075
  @return
4053
 
    Item returned as the result of transformation of the root node
 
4076
    Item returned as the result of transformation of the root node 
4054
4077
*/
4055
4078
 
4056
 
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4057
 
                         Item_transformer transformer, unsigned char *arg_t)
 
4079
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
 
4080
                         Item_transformer transformer, uchar *arg_t)
4058
4081
{
4059
4082
  if (!(this->*analyzer)(arg_p))
4060
4083
    return 0;
4061
 
 
 
4084
  
4062
4085
  List_iterator<Item> li(list);
4063
4086
  Item *item;
4064
4087
  while ((item= li++))
4065
4088
  {
4066
 
    /*
 
4089
    /* 
4067
4090
      The same parameter value of arg_p must be passed
4068
4091
      to analyze any argument of the condition formula.
4069
 
    */
4070
 
    unsigned char *arg_v= *arg_p;
 
4092
    */   
 
4093
    uchar *arg_v= *arg_p;
4071
4094
    Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4072
4095
    if (new_item && new_item != item)
4073
4096
      li.replace(new_item);
4081
4104
  List_iterator<Item> li(list);
4082
4105
  Item *item;
4083
4106
 
4084
 
  switch (order) {
4085
 
  case (T_PREFIX):
 
4107
  switch(order) {
 
4108
  case(PREFIX):
4086
4109
    (*traverser)(this, arg);
4087
4110
    while ((item= li++))
4088
4111
    {
4090
4113
    }
4091
4114
    (*traverser)(NULL, arg);
4092
4115
    break;
4093
 
  case (T_POSTFIX):
 
4116
  case(POSTFIX):
4094
4117
    while ((item= li++))
4095
4118
    {
4096
4119
      item->traverse_cond(traverser, arg, order);
4107
4130
  (Calculation done by update_sum_func() and copy_sum_funcs() in
4108
4131
  sql_select.cc)
4109
4132
 
4110
 
  @param session                        Thread handler
 
4133
  @param thd                    Thread handler
4111
4134
  @param ref_pointer_array      Pointer to array of reference fields
4112
4135
  @param fields         All fields in select
4113
4136
 
4116
4139
    that have or refer (HAVING) to a SUM expression.
4117
4140
*/
4118
4141
 
4119
 
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
 
4142
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
4120
4143
                               List<Item> &fields)
4121
4144
{
4122
4145
  List_iterator<Item> li(list);
4123
4146
  Item *item;
4124
4147
  while ((item= li++))
4125
 
    item->split_sum_func(session, ref_pointer_array,
4126
 
                         fields, li.ref(), true);
 
4148
    item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4127
4149
}
4128
4150
 
4129
4151
 
4168
4190
}
4169
4191
 
4170
4192
 
4171
 
void Item_cond::neg_arguments(Session *session)
 
4193
void Item_cond::neg_arguments(THD *thd)
4172
4194
{
4173
4195
  List_iterator<Item> li(list);
4174
4196
  Item *item;
4175
4197
  while ((item= li++))          /* Apply not transformation to the arguments */
4176
4198
  {
4177
 
    Item *new_item= item->neg_transformer(session);
 
4199
    Item *new_item= item->neg_transformer(thd);
4178
4200
    if (!new_item)
4179
4201
    {
4180
4202
      if (!(new_item= new Item_func_not(item)))
4181
4203
        return;                                 // Fatal OEM error
4182
4204
    }
4183
 
    li.replace(new_item);
 
4205
    VOID(li.replace(new_item));
4184
4206
  }
4185
4207
}
4186
4208
 
4205
4227
*/
4206
4228
 
4207
4229
 
4208
 
int64_t Item_cond_and::val_int()
 
4230
longlong Item_cond_and::val_int()
4209
4231
{
4210
4232
  assert(fixed == 1);
4211
4233
  List_iterator_fast<Item> li(list);
4223
4245
}
4224
4246
 
4225
4247
 
4226
 
int64_t Item_cond_or::val_int()
 
4248
longlong Item_cond_or::val_int()
4227
4249
{
4228
4250
  assert(fixed == 1);
4229
4251
  List_iterator_fast<Item> li(list);
4284
4306
}
4285
4307
 
4286
4308
 
4287
 
int64_t Item_func_isnull::val_int()
 
4309
longlong Item_func_isnull::val_int()
4288
4310
{
4289
4311
  assert(fixed == 1);
4290
4312
  /*
4296
4318
  return args[0]->is_null() ? 1: 0;
4297
4319
}
4298
4320
 
4299
 
int64_t Item_is_not_null_test::val_int()
 
4321
longlong Item_is_not_null_test::val_int()
4300
4322
{
4301
4323
  assert(fixed == 1);
4302
4324
  if (!used_tables_cache && !with_subselect)
4321
4343
  if (!args[0]->maybe_null)
4322
4344
  {
4323
4345
    used_tables_cache= 0;                       /* is always true */
4324
 
    cached_value= (int64_t) 1;
 
4346
    cached_value= (longlong) 1;
4325
4347
  }
4326
4348
  else
4327
4349
  {
4329
4351
    if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
4330
4352
    {
4331
4353
      /* Remember if the value is always NULL or never NULL */
4332
 
      cached_value= (int64_t) !args[0]->is_null();
 
4354
      cached_value= (longlong) !args[0]->is_null();
4333
4355
    }
4334
4356
  }
4335
4357
}
4336
4358
 
4337
4359
 
4338
 
int64_t Item_func_isnotnull::val_int()
 
4360
longlong Item_func_isnotnull::val_int()
4339
4361
{
4340
4362
  assert(fixed == 1);
4341
4363
  return args[0]->is_null() ? 0 : 1;
4350
4372
}
4351
4373
 
4352
4374
 
4353
 
int64_t Item_func_like::val_int()
 
4375
longlong Item_func_like::val_int()
4354
4376
{
4355
4377
  assert(fixed == 1);
4356
4378
  String* res = args[0]->val_str(&tmp_value1);
4369
4391
  if (canDoTurboBM)
4370
4392
    return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4371
4393
  return my_wildcmp(cmp.cmp_collation.collation,
4372
 
                    res->ptr(),res->ptr()+res->length(),
 
4394
                    res->ptr(),res->ptr()+res->length(),
4373
4395
                    res2->ptr(),res2->ptr()+res2->length(),
4374
 
                    make_escape_code(cmp.cmp_collation.collation, escape),
4375
 
                    internal::wild_one,internal::wild_many) ? 0 : 1;
 
4396
                    escape,wild_one,wild_many) ? 0 : 1;
4376
4397
}
4377
4398
 
4378
4399
 
4389
4410
    if (!res2)
4390
4411
      return OPTIMIZE_NONE;
4391
4412
 
4392
 
    if (*res2->ptr() != internal::wild_many)
 
4413
    if (*res2->ptr() != wild_many)
4393
4414
    {
4394
 
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != internal::wild_one)
 
4415
      if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
4395
4416
        return OPTIMIZE_OP;
4396
4417
    }
4397
4418
  }
4399
4420
}
4400
4421
 
4401
4422
 
4402
 
bool Item_func_like::fix_fields(Session *session, Item **ref)
 
4423
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4403
4424
{
4404
4425
  assert(fixed == 0);
4405
 
  if (Item_bool_func2::fix_fields(session, ref) ||
4406
 
      escape_item->fix_fields(session, &escape_item))
 
4426
  if (Item_bool_func2::fix_fields(thd, ref) ||
 
4427
      escape_item->fix_fields(thd, &escape_item))
4407
4428
    return true;
4408
4429
 
4409
4430
  if (!escape_item->const_during_execution())
4411
4432
    my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4412
4433
    return true;
4413
4434
  }
4414
 
 
 
4435
  
4415
4436
  if (escape_item->const_item())
4416
4437
  {
4417
 
    
4418
4438
    /* If we are on execution stage */
4419
4439
    String *escape_str= escape_item->val_str(&tmp_value1);
4420
4440
    if (escape_str)
4421
4441
    {
4422
 
      escape= (char *)memory::sql_alloc(escape_str->length());
4423
 
      strcpy(escape, escape_str->ptr()); 
 
4442
      if (escape_used_in_parsing && (
 
4443
             (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
4444
                escape_str->numchars() != 1) ||
 
4445
               escape_str->numchars() > 1)))
 
4446
      {
 
4447
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
 
4448
        return true;
 
4449
      }
 
4450
 
 
4451
      if (use_mb(cmp.cmp_collation.collation))
 
4452
      {
 
4453
        CHARSET_INFO *cs= escape_str->charset();
 
4454
        my_wc_t wc;
 
4455
        int rc= cs->cset->mb_wc(cs, &wc,
 
4456
                                (const uchar*) escape_str->ptr(),
 
4457
                                (const uchar*) escape_str->ptr() +
 
4458
                                               escape_str->length());
 
4459
        escape= (int) (rc > 0 ? wc : '\\');
 
4460
      }
 
4461
      else
 
4462
      {
 
4463
        /*
 
4464
          In the case of 8bit character set, we pass native
 
4465
          code instead of Unicode code as "escape" argument.
 
4466
          Convert to "cs" if charset of escape differs.
 
4467
        */
 
4468
        CHARSET_INFO *cs= cmp.cmp_collation.collation;
 
4469
        uint32 unused;
 
4470
        if (escape_str->needs_conversion(escape_str->length(),
 
4471
                                         escape_str->charset(), cs, &unused))
 
4472
        {
 
4473
          char ch;
 
4474
          uint errors;
 
4475
          uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
 
4476
                                          escape_str->length(),
 
4477
                                          escape_str->charset(), &errors);
 
4478
          escape= cnvlen ? ch : '\\';
 
4479
        }
 
4480
        else
 
4481
          escape= *(escape_str->ptr());
 
4482
      }
4424
4483
    }
4425
4484
    else
4426
 
    {
4427
 
      escape= (char *)memory::sql_alloc(1);
4428
 
      strcpy(escape, "\\");
4429
 
    } 
4430
 
   
 
4485
      escape= '\\';
 
4486
 
4431
4487
    /*
4432
4488
      We could also do boyer-more for non-const items, but as we would have to
4433
4489
      recompute the tables for each row it's not worth it.
4434
4490
    */
4435
 
    if (args[1]->const_item() && !use_strnxfrm(collation.collation))
 
4491
    if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
 
4492
       !(specialflag & SPECIAL_NO_NEW_FUNC))
4436
4493
    {
4437
4494
      String* res2 = args[1]->val_str(&tmp_value2);
4438
4495
      if (!res2)
4439
4496
        return false;                           // Null argument
4440
 
 
 
4497
      
4441
4498
      const size_t len   = res2->length();
4442
4499
      const char*  first = res2->ptr();
4443
4500
      const char*  last  = first + len - 1;
4445
4502
        len must be > 2 ('%pattern%')
4446
4503
        heuristic: only do TurboBM for pattern_len > 2
4447
4504
      */
4448
 
 
 
4505
      
4449
4506
      if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
4450
 
          *first == internal::wild_many &&
4451
 
          *last  == internal::wild_many)
 
4507
          *first == wild_many &&
 
4508
          *last  == wild_many)
4452
4509
      {
4453
4510
        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
 
  
 
4511
        for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
4460
4512
        canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
4461
4513
      }
4462
4514
      if (canDoTurboBM)
4463
4515
      {
4464
4516
        pattern     = first + 1;
4465
4517
        pattern_len = (int) len - 2;
4466
 
        int *suff = (int*) session->alloc((int) (sizeof(int)*
 
4518
        int *suff = (int*) thd->alloc((int) (sizeof(int)*
4467
4519
                                      ((pattern_len + 1)*2+
4468
4520
                                      alphabet_size)));
4469
4521
        bmGs      = suff + pattern_len + 1;
4483
4535
}
4484
4536
 
4485
4537
#ifdef LIKE_CMP_TOUPPER
4486
 
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
 
4538
#define likeconv(cs,A) (uchar) (cs)->toupper(A)
4487
4539
#else
4488
 
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
 
4540
#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
4489
4541
#endif
4490
4542
 
4491
4543
 
4499
4551
  int            f = 0;
4500
4552
  int            g = plm1;
4501
4553
  int *const splm1 = suff + plm1;
4502
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4554
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4503
4555
 
4504
4556
  *splm1 = pattern_len;
4505
4557
 
4506
4558
  if (!cs->sort_order)
4507
4559
  {
4508
 
    for (int i = pattern_len - 2; i >= 0; i--)
 
4560
    int i;
 
4561
    for (i = pattern_len - 2; i >= 0; i--)
4509
4562
    {
4510
4563
      int tmp = *(splm1 + i - f);
4511
4564
      if (g < i && tmp < i - g)
4512
 
        suff[i] = tmp;
 
4565
        suff[i] = tmp;
4513
4566
      else
4514
4567
      {
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;
 
4568
        if (i < g)
 
4569
          g = i; // g = min(i, g)
 
4570
        f = i;
 
4571
        while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
 
4572
          g--;
 
4573
        suff[i] = f - g;
4521
4574
      }
4522
4575
    }
4523
4576
  }
4524
4577
  else
4525
4578
  {
4526
 
    for (int i = pattern_len - 2; 0 <= i; --i)
 
4579
    int i;
 
4580
    for (i = pattern_len - 2; 0 <= i; --i)
4527
4581
    {
4528
4582
      int tmp = *(splm1 + i - f);
4529
4583
      if (g < i && tmp < i - g)
4530
 
        suff[i] = tmp;
 
4584
        suff[i] = tmp;
4531
4585
      else
4532
4586
      {
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;
 
4587
        if (i < g)
 
4588
          g = i; // g = min(i, g)
 
4589
        f = i;
 
4590
        while (g >= 0 &&
 
4591
               likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
 
4592
          g--;
 
4593
        suff[i] = f - g;
4540
4594
      }
4541
4595
    }
4542
4596
  }
4597
4651
  int *end = bmBc + alphabet_size;
4598
4652
  int j;
4599
4653
  const int plm1 = pattern_len - 1;
4600
 
  const CHARSET_INFO *const cs= cmp.cmp_collation.collation;
 
4654
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4601
4655
 
4602
4656
  for (i = bmBc; i < end; i++)
4603
4657
    *i = pattern_len;
4605
4659
  if (!cs->sort_order)
4606
4660
  {
4607
4661
    for (j = 0; j < plm1; j++)
4608
 
      bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
 
4662
      bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
4609
4663
  }
4610
4664
  else
4611
4665
  {
4612
4666
    for (j = 0; j < plm1; j++)
4613
 
      bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
 
4667
      bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4614
4668
  }
4615
4669
}
4616
4670
 
4629
4683
  int shift = pattern_len;
4630
4684
  int j     = 0;
4631
4685
  int u     = 0;
4632
 
  const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
 
4686
  CHARSET_INFO  *cs= cmp.cmp_collation.collation;
4633
4687
 
4634
4688
  const int plm1=  pattern_len - 1;
4635
4689
  const int tlmpl= text_len - pattern_len;
4651
4705
 
4652
4706
      register const int v = plm1 - i;
4653
4707
      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];
 
4708
      bcShift    = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
 
4709
      shift      = max(turboShift, bcShift);
 
4710
      shift      = max(shift, bmGs[i]);
4657
4711
      if (shift == bmGs[i])
4658
 
        u = (pattern_len - shift < v) ? pattern_len - shift : v;
 
4712
        u = min(pattern_len - shift, v);
4659
4713
      else
4660
4714
      {
4661
 
        if (turboShift < bcShift)
4662
 
          shift= max(shift, u + 1);
4663
 
        u = 0;
 
4715
        if (turboShift < bcShift)
 
4716
          shift = max(shift, u + 1);
 
4717
        u = 0;
4664
4718
      }
4665
4719
      j+= shift;
4666
4720
    }
4673
4727
      register int i = plm1;
4674
4728
      while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4675
4729
      {
4676
 
        i--;
4677
 
        if (i == plm1 - shift)
4678
 
          i-= u;
 
4730
        i--;
 
4731
        if (i == plm1 - shift)
 
4732
          i-= u;
4679
4733
      }
4680
 
 
4681
4734
      if (i < 0)
4682
 
        return 1;
 
4735
        return 1;
4683
4736
 
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
 
      
 
4737
      register const int v = plm1 - i;
 
4738
      turboShift = u - v;
 
4739
      bcShift    = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
 
4740
      shift      = max(turboShift, bcShift);
 
4741
      shift      = max(shift, bmGs[i]);
4690
4742
      if (shift == bmGs[i])
4691
 
        u= (pattern_len - shift < v) ? pattern_len - shift : v;
 
4743
        u = min(pattern_len - shift, v);
4692
4744
      else
4693
4745
      {
4694
 
        if (turboShift < bcShift)
4695
 
          shift= max(shift, u + 1);
4696
 
        u = 0;
 
4746
        if (turboShift < bcShift)
 
4747
          shift = max(shift, u + 1);
 
4748
        u = 0;
4697
4749
      }
4698
 
 
4699
4750
      j+= shift;
4700
4751
    }
4701
4752
    return 0;
4719
4770
    very fast to use.
4720
4771
*/
4721
4772
 
4722
 
int64_t Item_cond_xor::val_int()
 
4773
longlong Item_cond_xor::val_int()
4723
4774
{
4724
4775
  assert(fixed == 1);
4725
4776
  List_iterator<Item> li(list);
4726
4777
  Item *item;
4727
 
  int result=0;
 
4778
  int result=0; 
4728
4779
  null_value=0;
4729
4780
  while ((item=li++))
4730
4781
  {
4735
4786
      return 0;
4736
4787
    }
4737
4788
  }
4738
 
  return (int64_t) result;
 
4789
  return (longlong) result;
4739
4790
}
4740
4791
 
4741
4792
/**
4757
4808
       IS NOT NULL(a)     -> IS NULL(a)
4758
4809
    @endverbatim
4759
4810
 
4760
 
  @param session                thread handler
 
4811
  @param thd            thread handler
4761
4812
 
4762
4813
  @return
4763
4814
    New item or
4764
4815
    NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4765
4816
*/
4766
4817
 
4767
 
Item *Item_func_not::neg_transformer(Session *) /* NOT(x)  ->  x */
 
4818
Item *Item_func_not::neg_transformer(THD *thd __attribute__((__unused__)))      /* NOT(x)  ->  x */
4768
4819
{
4769
4820
  return args[0];
4770
4821
}
4771
4822
 
4772
4823
 
4773
 
Item *Item_bool_rowready_func2::neg_transformer(Session *)
 
4824
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((__unused__)))
4774
4825
{
4775
4826
  Item *item= negated_item();
4776
4827
  return item;
4780
4831
/**
4781
4832
  a IS NULL  ->  a IS NOT NULL.
4782
4833
*/
4783
 
Item *Item_func_isnull::neg_transformer(Session *)
 
4834
Item *Item_func_isnull::neg_transformer(THD *thd __attribute__((__unused__)))
4784
4835
{
4785
4836
  Item *item= new Item_func_isnotnull(args[0]);
4786
4837
  return item;
4790
4841
/**
4791
4842
  a IS NOT NULL  ->  a IS NULL.
4792
4843
*/
4793
 
Item *Item_func_isnotnull::neg_transformer(Session *)
 
4844
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((__unused__)))
4794
4845
{
4795
4846
  Item *item= new Item_func_isnull(args[0]);
4796
4847
  return item;
4797
4848
}
4798
4849
 
4799
4850
 
4800
 
Item *Item_cond_and::neg_transformer(Session *session)  /* NOT(a AND b AND ...)  -> */
 
4851
Item *Item_cond_and::neg_transformer(THD *thd)  /* NOT(a AND b AND ...)  -> */
4801
4852
                                        /* NOT a OR NOT b OR ... */
4802
4853
{
4803
 
  neg_arguments(session);
 
4854
  neg_arguments(thd);
4804
4855
  Item *item= new Item_cond_or(list);
4805
4856
  return item;
4806
4857
}
4807
4858
 
4808
4859
 
4809
 
Item *Item_cond_or::neg_transformer(Session *session)   /* NOT(a OR b OR ...)  -> */
 
4860
Item *Item_cond_or::neg_transformer(THD *thd)   /* NOT(a OR b OR ...)  -> */
4810
4861
                                        /* NOT a AND NOT b AND ... */
4811
4862
{
4812
 
  neg_arguments(session);
 
4863
  neg_arguments(thd);
4813
4864
  Item *item= new Item_cond_and(list);
4814
4865
  return item;
4815
4866
}
4816
4867
 
4817
4868
 
4818
 
Item *Item_func_nop_all::neg_transformer(Session *)
 
4869
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((__unused__)))
4819
4870
{
4820
4871
  /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4821
4872
  Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4826
4877
  return new_item;
4827
4878
}
4828
4879
 
4829
 
Item *Item_func_not_all::neg_transformer(Session *)
 
4880
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((__unused__)))
4830
4881
{
4831
4882
  /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4832
4883
  Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4933
4984
  fields.push_back(f);
4934
4985
}
4935
4986
 
4936
 
uint32_t Item_equal::members()
 
4987
uint Item_equal::members()
4937
4988
{
4938
4989
  return fields.elements;
4939
4990
}
4949
5000
  @retval
4950
5001
    1       if nultiple equality contains a reference to field
4951
5002
  @retval
4952
 
    0       otherwise
 
5003
    0       otherwise    
4953
5004
*/
4954
5005
 
4955
5006
bool Item_equal::contains(Field *field)
4967
5018
 
4968
5019
/**
4969
5020
  Join members of another Item_equal object.
4970
 
 
 
5021
  
4971
5022
    The function actually merges two multiple equalities.
4972
5023
    After this operation the Item_equal object additionally contains
4973
5024
    the field items of another item of the type Item_equal.
4974
5025
    If the optional constant items are not equal the cond_false flag is
4975
 
    set to 1.
 
5026
    set to 1.  
4976
5027
  @param item    multiple equality whose members are to be joined
4977
5028
*/
4978
5029
 
4982
5033
  Item *c= item->const_item;
4983
5034
  if (c)
4984
5035
  {
4985
 
    /*
4986
 
      The flag cond_false will be set to 1 after this, if
4987
 
      the multiple equality already contains a constant and its
 
5036
    /* 
 
5037
      The flag cond_false will be set to 1 after this, if 
 
5038
      the multiple equality already contains a constant and its 
4988
5039
      value is  not equal to the value of c.
4989
5040
    */
4990
5041
    add(c);
4991
5042
  }
4992
5043
  cond_false|= item->cond_false;
4993
 
}
 
5044
4994
5045
 
4995
5046
 
4996
5047
/**
5066
5117
  }
5067
5118
}
5068
5119
 
5069
 
bool Item_equal::fix_fields(Session *, Item **)
 
5120
bool Item_equal::fix_fields(THD *thd __attribute__((__unused__)), Item **ref __attribute__((__unused__)))
5070
5121
{
5071
5122
  List_iterator_fast<Item_field> li(fields);
5072
5123
  Item *item;
5101
5152
  }
5102
5153
}
5103
5154
 
5104
 
int64_t Item_equal::val_int()
 
5155
longlong Item_equal::val_int()
5105
5156
{
5106
5157
  Item_field *item_field;
5107
5158
  if (cond_false)
5114
5165
  while ((item_field= it++))
5115
5166
  {
5116
5167
    /* Skip fields of non-const tables. They haven't been read yet */
5117
 
    if (item_field->field->getTable()->const_table)
 
5168
    if (item_field->field->table->const_table)
5118
5169
    {
5119
5170
      if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5120
5171
        return 0;
5130
5181
                                      item->collation.collation);
5131
5182
}
5132
5183
 
5133
 
bool Item_equal::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
 
5184
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
5134
5185
{
5135
5186
  List_iterator_fast<Item_field> it(fields);
5136
5187
  Item *item;
5142
5193
  return Item_func::walk(processor, walk_subquery, arg);
5143
5194
}
5144
5195
 
5145
 
Item *Item_equal::transform(Item_transformer transformer, unsigned char *arg)
 
5196
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
5146
5197
{
5147
5198
  List_iterator<Item_field> it(fields);
5148
5199
  Item *item;
5153
5204
      return 0;
5154
5205
 
5155
5206
    /*
5156
 
      Session::change_item_tree() should be called only if the tree was
 
5207
      THD::change_item_tree() should be called only if the tree was
5157
5208
      really transformed, i.e. when a new item has been created.
5158
5209
      Otherwise we'll be allocating a lot of unnecessary memory for
5159
5210
      change records at each execution.
5160
5211
    */
5161
5212
    if (new_item != item)
5162
 
      current_session->change_item_tree((Item **) it.ref(), new_item);
 
5213
      current_thd->change_item_tree((Item **) it.ref(), new_item);
5163
5214
  }
5164
5215
  return Item_func::transform(transformer, arg);
5165
5216
}
5186
5237
  str->append(')');
5187
5238
}
5188
5239
 
5189
 
} /* namespace drizzled */