~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field.h

  • Committer: Prafulla Tekawade
  • Date: 2010-07-13 16:07:35 UTC
  • mto: (1662.1.4 rollup)
  • mto: This revision was merged to the branch mainline in revision 1664.
  • Revision ID: prafulla_t@users.sourceforge.net-20100713160735-2fsdtrm3azayuyu1
This bug is simillar to mysql bug 36133
http://bugs.mysql.com/bug.php?id=36133

Taking changes from that fix.

  - The problem was that the range optimizer evaluated constant expressions, 
    and among them it would try to evaluate IN-subquery predicates slated for
    handling with materialization strategy. However, these predicates require
    that parent_join->setup_subquery_materialization() is invoked before one
    attempts to evaluate them.
  
  - Fixed by making the range optimizer not to evaluate expressions that have
    item->is_expensive() == TRUE (these are materialization subqueries and 
    stored function calls). This should also resolve the problem that EXPLAIN 
    may be too long. 
    This change cuts off some opportunities for range optimizer, but this is 
    the price we're willing to pay for separation of query optimization and
    execution. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
22
22
  variables must declare the size_of() member function.
23
23
*/
24
24
 
25
 
 
26
 
 
27
25
#ifndef DRIZZLED_FIELD_H
28
26
#define DRIZZLED_FIELD_H
29
27
 
30
 
#include <drizzled/sql_error.h>
31
 
#include <drizzled/type/decimal.h>
32
 
#include <drizzled/key_map.h>
33
 
#include <drizzled/sql_list.h>
34
 
#include <drizzled/structs.h>
35
 
#include <drizzled/charset_info.h>
36
 
#include <drizzled/item_result.h>
37
 
#include <drizzled/charset_info.h>
 
28
#include "drizzled/sql_error.h"
 
29
#include "drizzled/decimal.h"
 
30
#include "drizzled/key_map.h"
 
31
#include "drizzled/sql_bitmap.h"
 
32
#include "drizzled/sql_list.h"
 
33
#include "drizzled/structs.h"
 
34
#include "drizzled/charset_info.h"
 
35
#include "drizzled/item_result.h"
38
36
 
39
37
#include <string>
40
38
#include <vector>
41
39
 
42
 
#include <drizzled/visibility.h>
43
 
 
44
40
namespace drizzled
45
41
{
46
42
 
48
44
#define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE FLOATING_POINT_BUFFER
49
45
 
50
46
#ifdef DEBUG
51
 
#define ASSERT_COLUMN_MARKED_FOR_READ assert(!getTable() || (getTable()->read_set == NULL || isReadSet()))
52
 
#define ASSERT_COLUMN_MARKED_FOR_WRITE assert(!getTable() || (getTable()->write_set == NULL || isWriteSet()))
 
47
#define ASSERT_COLUMN_MARKED_FOR_READ assert(!table || (table->read_set == NULL || isReadSet()))
 
48
#define ASSERT_COLUMN_MARKED_FOR_WRITE assert(!table || (table->write_set == NULL || isWriteSet()))
53
49
#else
54
 
#define ASSERT_COLUMN_MARKED_FOR_READ assert(getTable())
55
 
#define ASSERT_COLUMN_MARKED_FOR_WRITE assert(getTable())
 
50
#define ASSERT_COLUMN_MARKED_FOR_READ
 
51
#define ASSERT_COLUMN_MARKED_FOR_WRITE
56
52
#endif
57
53
 
58
54
typedef struct st_typelib TYPELIB;
67
63
 
68
64
int field_conv(Field *to,Field *from);
69
65
 
 
66
inline uint32_t get_enum_pack_length(int elements)
 
67
{
 
68
  return elements < 256 ? 1 : 2;
 
69
}
 
70
 
70
71
/**
71
72
 * Class representing a Field in a Table
72
73
 *
80
81
 * The store_xxx() methods take various input and convert
81
82
 * the input into the raw bytes stored in the ptr member variable.
82
83
 */
83
 
class DRIZZLED_API Field
 
84
class Field
84
85
{
85
86
  /* Prevent use of these */
86
87
  Field(const Field&);
87
88
  void operator=(Field &);
88
 
 
89
89
public:
90
90
  unsigned char *ptr; /**< Position to field in record. Stores raw field value */
91
91
  unsigned char *null_ptr; /**< Byte where null_bit is */
96
96
   * @note You can use table->in_use as replacement for current_session member
97
97
   * only inside of val_*() and store() members (e.g. you can't use it in cons)
98
98
   */
99
 
private:
100
99
  Table *table;
101
 
 
102
 
public:
103
 
  Table *getTable()
104
 
  {
105
 
    assert(table);
106
 
    return table;
107
 
  }
108
 
 
109
 
  Table *getTable() const
110
 
  {
111
 
    assert(table);
112
 
    return table;
113
 
  }
114
 
 
115
 
  void setTable(Table *table_arg)
116
 
  {
117
 
    table= table_arg;
118
 
  }
119
 
 
120
100
  Table *orig_table; /**< Pointer to the original Table. @TODO What is "the original table"? */
 
101
  const char **table_name; /**< Pointer to the name of the table. @TODO This is redundant with Table::table_name. */
121
102
  const char *field_name; /**< Name of the field */
122
103
  LEX_STRING comment; /**< A comment about the field */
123
104
 
147
128
  utype unireg_check;
148
129
  uint32_t field_length; /**< Length of this field in bytes */
149
130
  uint32_t flags;
150
 
 
151
 
  bool isUnsigned() const
152
 
  {
153
 
    return flags & UNSIGNED_FLAG;
154
 
  }
155
 
 
156
 
private:
157
131
  uint16_t field_index; /**< Index of this Field in Table::fields array */
158
 
 
159
 
public:
160
 
 
161
 
  uint16_t position() const
162
 
  {
163
 
    return field_index;
164
 
  }
165
 
 
166
 
  void setPosition(uint32_t arg)
167
 
  {
168
 
    field_index= arg;
169
 
  }
170
 
 
171
132
  unsigned char null_bit; /**< Bit used to test null bit */
172
133
  /**
173
134
     If true, this field was created in create_tmp_field_from_item from a NULL
183
144
  static void *operator new(size_t size, memory::Root *mem_root);
184
145
  static void operator delete(void *, size_t)
185
146
  { }
186
 
  static void operator delete(void *, memory::Root *)
187
 
  { }
188
147
 
189
148
  Field(unsigned char *ptr_arg,
190
149
        uint32_t length_arg,
193
152
        utype unireg_check_arg,
194
153
        const char *field_name_arg);
195
154
  virtual ~Field() {}
196
 
 
197
 
  bool hasDefault() const
198
 
  {
199
 
    return not (flags & NO_DEFAULT_VALUE_FLAG);
200
 
  }
201
 
 
202
155
  /* Store functions returns 1 on overflow and -1 on fatal error */
203
156
  virtual int store(const char *to,
204
157
                    uint32_t length,
205
158
                    const CHARSET_INFO * const cs)=0;
206
159
  virtual int store(double nr)=0;
207
160
  virtual int store(int64_t nr, bool unsigned_val)=0;
208
 
  virtual int store_decimal(const type::Decimal *d)=0;
209
 
  int store_and_check(enum_check_fields check_level,
210
 
                      const char *to,
211
 
                      uint32_t length,
212
 
                      const CHARSET_INFO * const cs);
 
161
  virtual int store_decimal(const my_decimal *d)=0;
 
162
  int store(const char *to,
 
163
            uint32_t length,
 
164
            const CHARSET_INFO * const cs,
 
165
            enum_check_fields check_level);
213
166
  /**
214
167
    This is called when storing a date in a string.
215
168
 
216
169
    @note
217
170
      Needs to be changed if/when we want to support different time formats.
218
171
  */
219
 
  virtual int store_time(type::Time &ltime, type::timestamp_t t_type);
220
 
  virtual double val_real() const=0;
221
 
  virtual int64_t val_int() const =0;
222
 
  virtual type::Decimal *val_decimal(type::Decimal *) const;
223
 
  String *val_str_internal(String *str) const
 
172
  virtual int store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type t_type);
 
173
  virtual double val_real(void)=0;
 
174
  virtual int64_t val_int(void)=0;
 
175
  virtual my_decimal *val_decimal(my_decimal *);
 
176
  inline String *val_str(String *str)
224
177
  {
225
178
    return val_str(str, str);
226
179
  }
227
 
 
228
180
  /*
229
181
     val_str(buf1, buf2) gets two buffers and should use them as follows:
230
182
     if it needs a temp buffer to convert result to string - use buf1
237
189
     an unnecessary free (and later, may be an alloc).
238
190
     This trickery is used to decrease a number of malloc calls.
239
191
  */
240
 
  virtual String *val_str(String*, String *) const =0;
241
 
 
 
192
  virtual String *val_str(String*, String *)=0;
242
193
  /*
243
194
   str_needs_quotes() returns true if the value returned by val_str() needs
244
195
   to be quoted when used in constructing an SQL query.
247
198
  virtual Item_result result_type () const=0;
248
199
  virtual Item_result cmp_type () const { return result_type(); }
249
200
  virtual Item_result cast_to_int_type () const { return result_type(); }
250
 
 
251
201
  /**
252
202
     Check whether a field type can be partially indexed by a key.
253
203
 
294
244
   */
295
245
  virtual bool eq_def(Field *field);
296
246
 
297
 
  virtual bool is_timestamp() const
298
 
  {
299
 
    return false;
300
 
  }
301
 
 
302
247
  /**
303
248
   * Returns size (in bytes) used to store field data in memory
304
249
   * (i.e. it returns the maximum size of the field in a row of the table,
342
287
  virtual uint32_t key_length() const;
343
288
  virtual enum_field_types type() const =0;
344
289
  virtual enum_field_types real_type() const;
345
 
  virtual int cmp_max(const unsigned char *a, const unsigned char *b, uint32_t max_len);
 
290
  inline  int cmp(const unsigned char *str) { return cmp(ptr,str); }
 
291
  virtual int cmp_max(const unsigned char *a, const unsigned char *b,
 
292
                      uint32_t max_len);
346
293
  virtual int cmp(const unsigned char *,const unsigned char *)=0;
347
 
  int cmp_internal(const unsigned char *str) { return cmp(ptr,str); }
348
294
  virtual int cmp_binary(const unsigned char *a,const unsigned char *b,
349
295
                         uint32_t max_length=UINT32_MAX);
350
296
  virtual int cmp_offset(uint32_t row_offset);
363
309
  // For new field
364
310
  virtual uint32_t size_of() const =0;
365
311
 
366
 
  bool is_null(ptrdiff_t row_offset= 0) const;
367
 
  bool is_real_null(ptrdiff_t row_offset= 0) const;
368
 
  bool is_null_in_record(const unsigned char *record) const;
369
 
  bool is_null_in_record_with_offset(ptrdiff_t offset) const;
 
312
  bool is_null(ptrdiff_t row_offset= 0);
 
313
  bool is_real_null(ptrdiff_t row_offset= 0);
 
314
  bool is_null_in_record(const unsigned char *record);
 
315
  bool is_null_in_record_with_offset(ptrdiff_t offset);
370
316
  void set_null(ptrdiff_t row_offset= 0);
371
317
  void set_notnull(ptrdiff_t row_offset= 0);
372
 
  bool maybe_null(void) const;
373
 
  bool real_maybe_null(void) const;
 
318
  bool maybe_null(void);
 
319
  bool real_maybe_null(void);
374
320
 
375
321
  virtual void make_field(SendField *);
376
322
  virtual void sort_string(unsigned char *buff,uint32_t length)=0;
396
342
                               uint32_t new_null_bit);
397
343
  /** This is used to generate a field in Table from TableShare */
398
344
  Field *clone(memory::Root *mem_root, Table *new_table);
399
 
  void move_field(unsigned char *ptr_arg,unsigned char *null_ptr_arg,unsigned char null_bit_arg)
 
345
  inline void move_field(unsigned char *ptr_arg,unsigned char *null_ptr_arg,unsigned char null_bit_arg)
400
346
  {
401
347
    ptr= ptr_arg;
402
348
    null_ptr= null_ptr_arg;
403
349
    null_bit= null_bit_arg;
404
350
  }
405
 
  void move_field(unsigned char *ptr_arg) { ptr=ptr_arg; }
 
351
  inline void move_field(unsigned char *ptr_arg) { ptr=ptr_arg; }
406
352
  virtual void move_field_offset(ptrdiff_t ptr_diff)
407
353
  {
408
354
    ptr= ADD_TO_PTR(ptr,ptr_diff, unsigned char*);
460
406
  {
461
407
    set_image(buff,length, &my_charset_bin);
462
408
  }
463
 
  int64_t val_int_offset(uint32_t row_offset)
 
409
  inline int64_t val_int_offset(uint32_t row_offset)
464
410
  {
465
411
    ptr+=row_offset;
466
412
    int64_t tmp=val_int();
468
414
    return tmp;
469
415
  }
470
416
 
471
 
  int64_t val_int_internal(const unsigned char *new_ptr)
 
417
  inline int64_t val_int(const unsigned char *new_ptr)
472
418
  {
473
419
    unsigned char *old_ptr= ptr;
 
420
    int64_t return_value;
474
421
    ptr= const_cast<unsigned char*>(new_ptr);
475
 
    int64_t return_value= val_int();
 
422
    return_value= val_int();
476
423
    ptr= old_ptr;
477
424
    return return_value;
478
425
  }
479
 
 
480
 
  String *val_str_internal(String *str, const unsigned char *new_ptr)
 
426
  inline String *val_str(String *str, const unsigned char *new_ptr)
481
427
  {
482
428
    unsigned char *old_ptr= ptr;
483
429
    ptr= const_cast<unsigned char*>(new_ptr);
484
 
    val_str_internal(str);
 
430
    val_str(str);
485
431
    ptr= old_ptr;
486
432
    return str;
487
433
  }
590
536
    return max_length;
591
537
  }
592
538
 
593
 
  uint32_t offset(const unsigned char *record)
 
539
  inline uint32_t offset(const unsigned char *record)
594
540
  {
595
541
    return (uint32_t) (ptr - record);
596
542
  }
597
543
  void copy_from_tmp(int offset);
598
544
  uint32_t fill_cache_field(CacheField *copy);
599
 
  virtual bool get_date(type::Time &ltime,uint32_t fuzzydate) const;
600
 
  virtual bool get_time(type::Time &ltime) const;
 
545
  virtual bool get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate);
 
546
  virtual bool get_time(DRIZZLE_TIME *ltime);
601
547
  virtual const CHARSET_INFO *charset(void) const { return &my_charset_bin; }
602
548
  virtual const CHARSET_INFO *sort_charset(void) const { return charset(); }
603
549
  virtual bool has_charset(void) const { return false; }
629
575
      0 otherwise
630
576
  */
631
577
  bool set_warning(DRIZZLE_ERROR::enum_warning_level,
632
 
                   drizzled::error_t code,
 
578
                   unsigned int code,
633
579
                   int cuted_increment);
634
580
  /**
635
581
    Produce warning or note about datetime string data saved into field.
647
593
      thread.
648
594
  */
649
595
  void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
650
 
                            drizzled::error_t code,
 
596
                            uint32_t code,
651
597
                            const char *str,
652
598
                            uint32_t str_len,
653
 
                            type::timestamp_t ts_type,
 
599
                            enum enum_drizzle_timestamp_type ts_type,
654
600
                            int cuted_increment);
655
601
  /**
656
602
    Produce warning or note about integer datetime value saved into field.
667
613
      thread.
668
614
  */
669
615
  void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
670
 
                            drizzled::error_t code,
 
616
                            uint32_t code,
671
617
                            int64_t nr,
672
 
                            type::timestamp_t ts_type,
 
618
                            enum enum_drizzle_timestamp_type ts_type,
673
619
                            int cuted_increment);
674
620
  /**
675
621
    Produce warning or note about double datetime data saved into field.
685
631
      thread.
686
632
  */
687
633
  void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
688
 
                            const drizzled::error_t code,
 
634
                            const uint32_t code,
689
635
                            double nr,
690
 
                            type::timestamp_t ts_type);
691
 
  bool check_overflow(int op_result)
 
636
                            enum enum_drizzle_timestamp_type ts_type);
 
637
  inline bool check_overflow(int op_result)
692
638
  {
693
639
    return (op_result == E_DEC_OVERFLOW);
694
640
  }
722
668
    @return
723
669
      value converted from val
724
670
  */
725
 
  int64_t convert_decimal2int64_t(const type::Decimal *val,
 
671
  int64_t convert_decimal2int64_t(const my_decimal *val,
726
672
                                  bool unsigned_flag,
727
673
                                  int *err);
728
674
  /* The max. number of characters */
729
 
  uint32_t char_length() const
 
675
  inline uint32_t char_length() const
730
676
  {
731
677
    return field_length / charset()->mbmaxlen;
732
678
  }
733
679
 
734
 
  enum column_format_type column_format() const
 
680
  inline enum column_format_type column_format() const
735
681
  {
736
682
    return (enum column_format_type)
737
683
      ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
738
684
  }
739
685
 
740
686
  /* Hash value */
741
 
  virtual void hash(uint32_t *nr, uint32_t *nr2) const;
 
687
  virtual void hash(uint32_t *nr, uint32_t *nr2);
742
688
  friend bool reopen_table(Session *,Table *,bool);
743
689
 
744
690
  friend class CopyField;
754
700
  friend class Item_sum_max;
755
701
  friend class Item_func_group_concat;
756
702
 
757
 
  bool isReadSet() const;
 
703
  bool isReadSet();
758
704
  bool isWriteSet();
759
705
  void setReadSet(bool arg= true);
760
706
  void setWriteSet(bool arg= true);
761
 
 
762
 
protected:
763
 
 
764
 
  void pack_num(uint64_t arg, unsigned char *destination= NULL);
765
 
  void pack_num(uint32_t arg, unsigned char *destination= NULL);
766
 
  uint64_t unpack_num(uint64_t &destination, const unsigned char *arg= NULL) const;
767
 
  uint32_t unpack_num(uint32_t &destination, const unsigned char *arg= NULL) const;
768
707
};
769
708
 
770
 
namespace field {
771
 
 
772
 
inline bool isDateTime(const enum_field_types &arg)
773
 
{
774
 
  switch (arg)
775
 
  {
776
 
  case DRIZZLE_TYPE_DATE:
777
 
  case DRIZZLE_TYPE_DATETIME:
778
 
  case DRIZZLE_TYPE_MICROTIME:
779
 
  case DRIZZLE_TYPE_TIME:
780
 
  case DRIZZLE_TYPE_TIMESTAMP:
781
 
    return true;
782
 
 
783
 
  case DRIZZLE_TYPE_BLOB:
784
 
  case DRIZZLE_TYPE_BOOLEAN:
785
 
  case DRIZZLE_TYPE_DECIMAL:
786
 
  case DRIZZLE_TYPE_DOUBLE:
787
 
  case DRIZZLE_TYPE_ENUM:
788
 
  case DRIZZLE_TYPE_LONG:
789
 
  case DRIZZLE_TYPE_LONGLONG:
790
 
  case DRIZZLE_TYPE_NULL:
791
 
  case DRIZZLE_TYPE_UUID:
792
 
  case DRIZZLE_TYPE_VARCHAR:
793
 
    return false;
794
 
  }
795
 
 
796
 
  assert(0);
797
 
  abort();
798
 
}
799
 
 
800
 
} // namespace field
801
 
 
802
 
std::ostream& operator<<(std::ostream& output, const Field &field);
803
 
 
804
709
} /* namespace drizzled */
805
710
 
806
711
/** @TODO Why is this in the middle of the file???*/
807
 
#include <drizzled/create_field.h>
 
712
#include "drizzled/create_field.h"
808
713
 
809
714
namespace drizzled
810
715
{
833
738
  SendField() {}
834
739
};
835
740
 
 
741
/**
 
742
 * A class for quick copying data to fields
 
743
 */
 
744
class CopyField :public memory::SqlAlloc
 
745
{
 
746
  /**
 
747
    Convenience definition of a copy function returned by
 
748
    get_copy_func.
 
749
  */
 
750
  typedef void Copy_func(CopyField*);
 
751
  Copy_func *get_copy_func(Field *to, Field *from);
 
752
public:
 
753
  unsigned char *from_ptr;
 
754
  unsigned char *to_ptr;
 
755
  unsigned char *from_null_ptr;
 
756
  unsigned char *to_null_ptr;
 
757
  bool *null_row;
 
758
  uint32_t from_bit;
 
759
  uint32_t to_bit;
 
760
  uint32_t from_length;
 
761
  uint32_t to_length;
 
762
  Field *from_field;
 
763
  Field *to_field;
 
764
  String tmp;                                   // For items
 
765
 
 
766
  CopyField() {}
 
767
  ~CopyField() {}
 
768
  void set(Field *to,Field *from,bool save);    // Field to field
 
769
  void set(unsigned char *to,Field *from);              // Field to string
 
770
  void (*do_copy)(CopyField *);
 
771
  void (*do_copy2)(CopyField *);                // Used to handle null values
 
772
};
 
773
 
836
774
uint32_t pack_length_to_packflag(uint32_t type);
837
775
uint32_t calc_pack_length(enum_field_types type,uint32_t length);
838
776
int set_field_to_null(Field *field);