~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/create_field.cc

  • 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-2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008-2009 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
21
21
 * @file Implementation of CreateField class
22
22
 */
23
23
 
24
 
#include <config.h>
 
24
#include "config.h"
25
25
#include <errno.h>
26
26
#include <float.h>
27
 
#include <drizzled/sql_select.h>
28
 
#include <drizzled/error.h>
29
 
#include <drizzled/field.h>
30
 
#include <drizzled/create_field.h>
31
 
#include <drizzled/field/str.h>
32
 
#include <drizzled/field/num.h>
33
 
#include <drizzled/field/blob.h>
34
 
#include <drizzled/field/boolean.h>
35
 
#include <drizzled/field/enum.h>
36
 
#include <drizzled/field/null.h>
37
 
#include <drizzled/field/date.h>
38
 
#include <drizzled/field/decimal.h>
39
 
#include <drizzled/field/real.h>
40
 
#include <drizzled/field/double.h>
41
 
#include <drizzled/field/int32.h>
42
 
#include <drizzled/field/int64.h>
43
 
#include <drizzled/field/num.h>
44
 
#include <drizzled/field/epoch.h>
45
 
#include <drizzled/field/datetime.h>
46
 
#include <drizzled/field/varstring.h>
47
 
#include <drizzled/field/uuid.h>
48
 
#include <drizzled/temporal.h>
49
 
#include <drizzled/item/string.h>
50
 
#include <drizzled/table.h>
51
 
 
52
 
#include <drizzled/display.h>
 
27
#include "drizzled/sql_select.h"
 
28
#include "drizzled/error.h"
 
29
#include "drizzled/field.h"
 
30
#include "drizzled/create_field.h"
 
31
#include "drizzled/field/str.h"
 
32
#include "drizzled/field/num.h"
 
33
#include "drizzled/field/blob.h"
 
34
#include "drizzled/field/enum.h"
 
35
#include "drizzled/field/null.h"
 
36
#include "drizzled/field/date.h"
 
37
#include "drizzled/field/decimal.h"
 
38
#include "drizzled/field/real.h"
 
39
#include "drizzled/field/double.h"
 
40
#include "drizzled/field/long.h"
 
41
#include "drizzled/field/int64_t.h"
 
42
#include "drizzled/field/num.h"
 
43
#include "drizzled/field/timestamp.h"
 
44
#include "drizzled/field/datetime.h"
 
45
#include "drizzled/field/varstring.h"
 
46
#include "drizzled/temporal.h"
53
47
 
54
48
#include <algorithm>
55
49
 
75
69
 
76
70
  /* Fix if the original table had 4 byte pointer blobs */
77
71
  if (flags & BLOB_FLAG)
78
 
  {
79
 
    pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
80
 
  }
 
72
    pack_length= (pack_length - old_field->table->getShare()->blob_ptr_size + portable_sizeof_char_ptr);
81
73
 
82
74
  switch (sql_type) 
83
75
  {
102
94
  def= 0;
103
95
  char_length= length;
104
96
 
105
 
  if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
106
 
      !(flags & AUTO_INCREMENT_FLAG) &&
 
97
  if (!(flags & (NO_DEFAULT_VALUE_FLAG )) &&
107
98
      old_field->ptr && orig_field &&
108
 
      (not old_field->is_timestamp() ||                /* set def only if */
109
 
       old_field->getTable()->timestamp_field != old_field ||  /* timestamp field */
 
99
      (sql_type != DRIZZLE_TYPE_TIMESTAMP ||                /* set def only if */
 
100
       old_field->table->timestamp_field != old_field ||  /* timestamp field */
110
101
       unireg_check == Field::TIMESTAMP_UN_FIELD))        /* has default val */
111
102
  {
112
103
    ptrdiff_t diff;
113
104
 
114
105
    /* Get the value from default_values */
115
 
    diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
106
    diff= (ptrdiff_t) (orig_field->table->getDefaultValues() - orig_field->table->record[0]);
116
107
    orig_field->move_field_offset(diff);        // Points now at default_values
117
108
    if (! orig_field->is_real_null())
118
109
    {
119
110
      char buff[MAX_FIELD_WIDTH], *pos;
120
111
      String tmp(buff, sizeof(buff), charset), *res;
121
 
      res= orig_field->val_str_internal(&tmp);
 
112
      res= orig_field->val_str(&tmp);
122
113
      pos= (char*) memory::sql_strmake(res->ptr(), res->length());
123
114
      def= new Item_string(pos, res->length(), charset);
124
115
    }
125
 
    orig_field->move_field_offset(-diff);       // Back to getInsertRecord()
 
116
    orig_field->move_field_offset(-diff);       // Back to record[0]
126
117
  }
127
118
}
128
119
 
146
137
      break;
147
138
    case DRIZZLE_TYPE_DECIMAL:
148
139
      key_length= pack_length=
149
 
        class_decimal_get_binary_size(class_decimal_length_to_precision(length,
 
140
        my_decimal_get_binary_size(my_decimal_length_to_precision(length,
150
141
                  decimals,
151
142
                  flags &
152
143
                  UNSIGNED_FLAG),
221
212
  interval= 0;
222
213
  pack_length= key_length= 0;
223
214
  charset= fld_charset;
224
 
  interval_list.clear();
 
215
  interval_list.empty();
225
216
 
226
217
  comment= *fld_comment;
227
218
 
230
221
    it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
231
222
  */
232
223
  if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
233
 
      (fld_type_modifier & NOT_NULL_FLAG) && (fld_type != DRIZZLE_TYPE_TIMESTAMP and fld_type != DRIZZLE_TYPE_MICROTIME))
234
 
  {
 
224
      (fld_type_modifier & NOT_NULL_FLAG) && fld_type != DRIZZLE_TYPE_TIMESTAMP)
235
225
    flags|= NO_DEFAULT_VALUE_FLAG;
236
 
  }
237
226
 
238
227
  if (fld_length && !(length= (uint32_t) atoi(fld_length)))
239
228
    fld_length= 0;
254
243
    case DRIZZLE_TYPE_NULL:
255
244
      break;
256
245
    case DRIZZLE_TYPE_DECIMAL:
257
 
      class_decimal_trim(&length, &decimals);
 
246
      my_decimal_trim(&length, &decimals);
258
247
      if (length > DECIMAL_MAX_PRECISION)
259
248
      {
260
249
        my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
266
255
        my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
267
256
        return(true);
268
257
      }
269
 
      length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
270
 
      pack_length= class_decimal_get_binary_size(length, decimals);
 
258
      length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
 
259
      pack_length= my_decimal_get_binary_size(length, decimals);
271
260
      break;
272
261
    case DRIZZLE_TYPE_VARCHAR:
273
262
      /*
305
294
        return(true);
306
295
      }
307
296
      break;
308
 
    case DRIZZLE_TYPE_MICROTIME:
309
 
      /* 
310
 
        This assert() should be correct due to absence of length
311
 
        specifiers for timestamp. Previous manipulation also wasn't
312
 
        ever called (from examining lcov)
313
 
      */
314
 
      assert(fld_type);
315
297
    case DRIZZLE_TYPE_TIMESTAMP:
316
 
      length= MicroTimestamp::MAX_STRING_LENGTH;
317
 
 
 
298
      if (!fld_length)
 
299
      {
 
300
        length= DateTime::MAX_STRING_LENGTH;
 
301
      }
 
302
 
 
303
      /* This assert() should be correct due to absence of length
 
304
         specifiers for timestamp. Previous manipulation also wasn't
 
305
         ever called (from examining lcov)
 
306
      */
 
307
      assert(length == (uint32_t)DateTime::MAX_STRING_LENGTH);
 
308
 
 
309
      flags|= UNSIGNED_FLAG;
318
310
      if (fld_default_value)
319
311
      {
320
312
        /* Grammar allows only NOW() value for ON UPDATE clause */
330
322
          def= 0;
331
323
        }
332
324
        else
333
 
        {
334
325
          unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
335
 
                         Field::NONE);
336
 
        }
 
326
                                              Field::NONE);
337
327
      }
338
328
      else
339
329
      {
358
348
    case DRIZZLE_TYPE_DATE:
359
349
      length= Date::MAX_STRING_LENGTH;
360
350
      break;
361
 
    case DRIZZLE_TYPE_UUID:
362
 
      length= field::Uuid::max_string_length();
363
 
      break;
364
 
    case DRIZZLE_TYPE_BOOLEAN:
365
 
      length= field::Boolean::max_string_length();
366
 
      break;
367
351
    case DRIZZLE_TYPE_DATETIME:
368
352
      length= DateTime::MAX_STRING_LENGTH;
369
353
      break;
370
 
    case DRIZZLE_TYPE_TIME:
371
 
      length= DateTime::MAX_STRING_LENGTH;
372
 
      break;
373
354
    case DRIZZLE_TYPE_ENUM:
374
355
      {
375
356
        /* Should be safe. */
376
 
        pack_length= 4;
 
357
        pack_length= get_enum_pack_length(fld_interval_list->elements);
377
358
 
378
 
        List<String>::iterator it(fld_interval_list->begin());
 
359
        List_iterator<String> it(*fld_interval_list);
379
360
        String *tmp;
380
361
        while ((tmp= it++))
381
362
          interval_list.push_back(tmp);
407
388
  return false; /* success */
408
389
}
409
390
 
410
 
std::ostream& operator<<(std::ostream& output, const CreateField &field)
411
 
{
412
 
  output << "CreateField:(";
413
 
  output <<  field.field_name;
414
 
  output << ", ";
415
 
  output << drizzled::display::type(field.type());
416
 
  output << ", { ";
417
 
 
418
 
  if (field.flags & NOT_NULL_FLAG)
419
 
    output << " NOT_NULL";
420
 
 
421
 
  if (field.flags & PRI_KEY_FLAG)
422
 
    output << ", PRIMARY KEY";
423
 
 
424
 
  if (field.flags & UNIQUE_KEY_FLAG)
425
 
    output << ", UNIQUE KEY";
426
 
 
427
 
  if (field.flags & MULTIPLE_KEY_FLAG)
428
 
    output << ", MULTIPLE KEY";
429
 
 
430
 
  if (field.flags & BLOB_FLAG)
431
 
    output << ", BLOB";
432
 
 
433
 
  if (field.flags & UNSIGNED_FLAG)
434
 
    output << ", UNSIGNED";
435
 
 
436
 
  if (field.flags & BINARY_FLAG)
437
 
    output << ", BINARY";
438
 
  output << "}, ";
439
 
  if (field.field)
440
 
    output << *field.field;
441
 
  output << ")";
442
 
 
443
 
  return output;  // for multiple << operators.
444
 
}
445
 
 
446
391
} /* namespace drizzled */