~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

Reverted 1103

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
/* Some general useful functions */
18
18
 
19
 
#include "config.h"
20
 
 
21
 
#include <float.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#include <string>
25
 
#include <vector>
26
 
#include <algorithm>
27
 
 
 
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
30
22
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
33
23
#include <drizzled/nested_join.h>
34
24
#include <drizzled/sql_parse.h>
35
25
#include <drizzled/item/sum.h>
42
32
#include <drizzled/field/double.h>
43
33
#include <drizzled/unireg.h>
44
34
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
49
 
#include "drizzled/plugin/storage_engine.h"
50
35
 
51
36
#include <drizzled/item/string.h>
52
37
#include <drizzled/item/int.h>
53
38
#include <drizzled/item/decimal.h>
54
39
#include <drizzled/item/float.h>
55
40
#include <drizzled/item/null.h>
56
 
#include <drizzled/temporal.h>
57
 
 
58
 
#include <drizzled/refresh_version.h>
59
 
 
60
 
#include "drizzled/table/singular.h"
61
 
 
62
 
#include "drizzled/table_proto.h"
 
41
 
 
42
#include <drizzled/table_proto.h>
 
43
 
 
44
#include <string>
 
45
#include <vector>
 
46
#include <algorithm>
 
47
 
63
48
 
64
49
using namespace std;
65
50
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
70
 
extern plugin::StorageEngine *myisam_engine;
71
 
 
72
 
/* Functions defined in this cursor */
 
51
/* Functions defined in this file */
 
52
 
 
53
void open_table_error(TableShare *share, int error, int db_errno,
 
54
                      myf errortype, int errarg);
73
55
 
74
56
/*************************************************************************/
75
57
 
76
 
// @note this should all be the destructor
77
 
int Table::delete_table(bool free_share)
 
58
/* Get column name from column hash */
 
59
 
 
60
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
 
61
{
 
62
  *length= (uint32_t) strlen((*buff)->field_name);
 
63
  return (unsigned char*) (*buff)->field_name;
 
64
}
 
65
 
 
66
 
 
67
/*
 
68
  Returns pointer to '.frm' extension of the file name.
 
69
 
 
70
  SYNOPSIS
 
71
    fn_rext()
 
72
    name       file name
 
73
 
 
74
  DESCRIPTION
 
75
    Checks file name part starting with the rightmost '.' character,
 
76
    and returns it if it is equal to '.dfe'.
 
77
 
 
78
  TODO
 
79
    It is a good idea to get rid of this function modifying the code
 
80
    to garantee that the functions presently calling fn_rext() always
 
81
    get arguments in the same format: either with '.frm' or without '.frm'.
 
82
 
 
83
  RETURN VALUES
 
84
    Pointer to the '.frm' extension. If there is no extension,
 
85
    or extension is not '.frm', pointer at the end of file name.
 
86
*/
 
87
 
 
88
char *fn_rext(char *name)
 
89
{
 
90
  char *res= strrchr(name, '.');
 
91
  if (res && !strcmp(res, ".dfe"))
 
92
    return res;
 
93
  return name + strlen(name);
 
94
}
 
95
 
 
96
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
 
97
{
 
98
  assert(db != NULL);
 
99
 
 
100
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
 
101
      (my_strcasecmp(system_charset_info,
 
102
                    INFORMATION_SCHEMA_NAME.c_str(),
 
103
                    db->str) == 0))
 
104
  {
 
105
    return TABLE_CATEGORY_INFORMATION;
 
106
  }
 
107
 
 
108
  return TABLE_CATEGORY_USER;
 
109
}
 
110
 
 
111
 
 
112
/*
 
113
  Allocate a setup TableShare structure
 
114
 
 
115
  SYNOPSIS
 
116
    alloc_table_share()
 
117
    TableList           Take database and table name from there
 
118
    key                 Table cache key (db \0 table_name \0...)
 
119
    key_length          Length of key
 
120
 
 
121
  RETURN
 
122
    0  Error (out of memory)
 
123
    #  Share
 
124
*/
 
125
 
 
126
TableShare *alloc_table_share(TableList *table_list, char *key,
 
127
                               uint32_t key_length)
 
128
{
 
129
  MEM_ROOT mem_root;
 
130
  TableShare *share;
 
131
  char *key_buff, *path_buff;
 
132
  char path[FN_REFLEN];
 
133
  uint32_t path_length;
 
134
 
 
135
  path_length= build_table_filename(path, sizeof(path) - 1,
 
136
                                    table_list->db,
 
137
                                    table_list->table_name, false);
 
138
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
139
  if (multi_alloc_root(&mem_root,
 
140
                       &share, sizeof(*share),
 
141
                       &key_buff, key_length,
 
142
                       &path_buff, path_length + 1,
 
143
                       NULL))
 
144
  {
 
145
    memset(share, 0, sizeof(*share));
 
146
 
 
147
    share->set_table_cache_key(key_buff, key, key_length);
 
148
 
 
149
    share->path.str= path_buff;
 
150
    share->path.length= path_length;
 
151
    strcpy(share->path.str, path);
 
152
    share->normalized_path.str=    share->path.str;
 
153
    share->normalized_path.length= path_length;
 
154
 
 
155
    share->version=       refresh_version;
 
156
 
 
157
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
 
158
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
 
159
    pthread_cond_init(&share->cond, NULL);
 
160
  }
 
161
  return(share);
 
162
}
 
163
 
 
164
 
 
165
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
 
166
{
 
167
  enum_field_types field_type;
 
168
 
 
169
  switch(proto_field_type)
 
170
  {
 
171
  case drizzled::message::Table::Field::TINYINT:
 
172
    field_type= DRIZZLE_TYPE_TINY;
 
173
    break;
 
174
  case drizzled::message::Table::Field::INTEGER:
 
175
    field_type= DRIZZLE_TYPE_LONG;
 
176
    break;
 
177
  case drizzled::message::Table::Field::DOUBLE:
 
178
    field_type= DRIZZLE_TYPE_DOUBLE;
 
179
    break;
 
180
  case drizzled::message::Table::Field::TIMESTAMP:
 
181
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
182
    break;
 
183
  case drizzled::message::Table::Field::BIGINT:
 
184
    field_type= DRIZZLE_TYPE_LONGLONG;
 
185
    break;
 
186
  case drizzled::message::Table::Field::DATETIME:
 
187
    field_type= DRIZZLE_TYPE_DATETIME;
 
188
    break;
 
189
  case drizzled::message::Table::Field::DATE:
 
190
    field_type= DRIZZLE_TYPE_DATE;
 
191
    break;
 
192
  case drizzled::message::Table::Field::VARCHAR:
 
193
    field_type= DRIZZLE_TYPE_VARCHAR;
 
194
    break;
 
195
  case drizzled::message::Table::Field::DECIMAL:
 
196
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
197
    break;
 
198
  case drizzled::message::Table::Field::ENUM:
 
199
    field_type= DRIZZLE_TYPE_ENUM;
 
200
    break;
 
201
  case drizzled::message::Table::Field::BLOB:
 
202
    field_type= DRIZZLE_TYPE_BLOB;
 
203
    break;
 
204
  default:
 
205
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
 
206
    assert(1);
 
207
  }
 
208
 
 
209
  return field_type;
 
210
}
 
211
 
 
212
static Item *default_value_item(enum_field_types field_type,
 
213
                                const CHARSET_INFO *charset,
 
214
                                bool default_null, const string *default_value,
 
215
                                const string *default_bin_value)
 
216
{
 
217
  Item *default_item= NULL;
 
218
  int error= 0;
 
219
 
 
220
  if (default_null)
 
221
  {
 
222
    return new Item_null();
 
223
  }
 
224
 
 
225
  switch(field_type)
 
226
  {
 
227
  case DRIZZLE_TYPE_TINY:
 
228
  case DRIZZLE_TYPE_LONG:
 
229
  case DRIZZLE_TYPE_LONGLONG:
 
230
    default_item= new Item_int(default_value->c_str(),
 
231
                               (int64_t) my_strtoll10(default_value->c_str(),
 
232
                                                      NULL,
 
233
                                                      &error),
 
234
                               default_value->length());
 
235
    break;
 
236
  case DRIZZLE_TYPE_DOUBLE:
 
237
    default_item= new Item_float(default_value->c_str(),
 
238
                                 default_value->length());
 
239
    break;
 
240
  case DRIZZLE_TYPE_NULL:
 
241
    assert(false);
 
242
  case DRIZZLE_TYPE_TIMESTAMP:
 
243
  case DRIZZLE_TYPE_DATETIME:
 
244
  case DRIZZLE_TYPE_DATE:
 
245
    if (default_value->compare("NOW()") == 0)
 
246
      break;
 
247
  case DRIZZLE_TYPE_ENUM:
 
248
    default_item= new Item_string(default_value->c_str(),
 
249
                                  default_value->length(),
 
250
                                  system_charset_info);
 
251
    break;
 
252
  case DRIZZLE_TYPE_VARCHAR:
 
253
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
254
    if (charset==&my_charset_bin)
 
255
    {
 
256
      default_item= new Item_string(default_bin_value->c_str(),
 
257
                                    default_bin_value->length(),
 
258
                                    &my_charset_bin);
 
259
    }
 
260
    else
 
261
    {
 
262
      default_item= new Item_string(default_value->c_str(),
 
263
                                    default_value->length(),
 
264
                                    system_charset_info);
 
265
    }
 
266
    break;
 
267
  case DRIZZLE_TYPE_NEWDECIMAL:
 
268
    default_item= new Item_decimal(default_value->c_str(),
 
269
                                   default_value->length(),
 
270
                                   system_charset_info);
 
271
    break;
 
272
  }
 
273
 
 
274
  return default_item;
 
275
}
 
276
 
 
277
int parse_table_proto(Session *session,
 
278
                      drizzled::message::Table &table,
 
279
                      TableShare *share)
 
280
{
 
281
  int error= 0;
 
282
  handler *handler_file= NULL;
 
283
 
 
284
  {
 
285
    share->storage_engine= ha_resolve_by_name(session, table.engine().name());
 
286
  }
 
287
 
 
288
  drizzled::message::Table::TableOptions table_options;
 
289
 
 
290
  if (table.has_options())
 
291
    table_options= table.options();
 
292
 
 
293
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
294
 
 
295
  if (table_options.has_pack_keys())
 
296
  {
 
297
    if (table_options.pack_keys())
 
298
      db_create_options|= HA_OPTION_PACK_KEYS;
 
299
    else
 
300
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
301
  }
 
302
 
 
303
  if (table_options.pack_record())
 
304
    db_create_options|= HA_OPTION_PACK_RECORD;
 
305
 
 
306
  if (table_options.has_checksum())
 
307
  {
 
308
    if (table_options.checksum())
 
309
      db_create_options|= HA_OPTION_CHECKSUM;
 
310
    else
 
311
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
312
  }
 
313
 
 
314
  if (table_options.has_delay_key_write())
 
315
  {
 
316
    if (table_options.delay_key_write())
 
317
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
318
    else
 
319
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
320
  }
 
321
 
 
322
  /* db_create_options was stored as 2 bytes in FRM
 
323
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
324
   */
 
325
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
326
  share->db_options_in_use= share->db_create_options;
 
327
 
 
328
 
 
329
  share->avg_row_length= table_options.has_avg_row_length() ?
 
330
    table_options.avg_row_length() : 0;
 
331
 
 
332
  share->page_checksum= table_options.has_page_checksum() ?
 
333
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
334
    : HA_CHOICE_UNDEF;
 
335
 
 
336
  share->row_type= table_options.has_row_type() ?
 
337
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
338
 
 
339
  share->block_size= table_options.has_block_size() ?
 
340
    table_options.block_size() : 0;
 
341
 
 
342
  share->table_charset= get_charset(table_options.has_collation_id()?
 
343
                                    table_options.collation_id() : 0);
 
344
 
 
345
  if (!share->table_charset)
 
346
  {
 
347
    /* unknown charset in head[38] or pre-3.23 frm */
 
348
    if (use_mb(default_charset_info))
 
349
    {
 
350
      /* Warn that we may be changing the size of character columns */
 
351
      errmsg_printf(ERRMSG_LVL_WARN,
 
352
                    _("'%s' had no or invalid character set, "
 
353
                      "and default character set is multi-byte, "
 
354
                      "so character column sizes may have changed"),
 
355
                    share->path.str);
 
356
    }
 
357
    share->table_charset= default_charset_info;
 
358
  }
 
359
 
 
360
  share->db_record_offset= 1;
 
361
 
 
362
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
363
 
 
364
  share->db_low_byte_first= true;
 
365
 
 
366
  share->max_rows= table_options.has_max_rows() ?
 
367
    table_options.max_rows() : 0;
 
368
 
 
369
  share->min_rows= table_options.has_min_rows() ?
 
370
    table_options.min_rows() : 0;
 
371
 
 
372
  share->keys= table.indexes_size();
 
373
 
 
374
  share->key_parts= 0;
 
375
  for (int indx= 0; indx < table.indexes_size(); indx++)
 
376
    share->key_parts+= table.indexes(indx).index_part_size();
 
377
 
 
378
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
379
                                     table.indexes_size() * sizeof(KEY)
 
380
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
381
 
 
382
  KEY_PART_INFO *key_part;
 
383
 
 
384
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
385
    (share->key_info+table.indexes_size());
 
386
 
 
387
 
 
388
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
389
                                            sizeof(ulong*)*share->key_parts);
 
390
 
 
391
  share->keynames.count= table.indexes_size();
 
392
  share->keynames.name= NULL;
 
393
  share->keynames.type_names= (const char**)
 
394
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
395
 
 
396
  share->keynames.type_lengths= (unsigned int*)
 
397
    alloc_root(&share->mem_root,
 
398
               sizeof(unsigned int) * (table.indexes_size()+1));
 
399
 
 
400
  share->keynames.type_names[share->keynames.count]= NULL;
 
401
  share->keynames.type_lengths[share->keynames.count]= 0;
 
402
 
 
403
  KEY* keyinfo= share->key_info;
 
404
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
405
  {
 
406
    drizzled::message::Table::Index indx= table.indexes(keynr);
 
407
 
 
408
    keyinfo->table= 0;
 
409
    keyinfo->flags= 0;
 
410
 
 
411
    if (indx.is_unique())
 
412
      keyinfo->flags|= HA_NOSAME;
 
413
 
 
414
    if (indx.has_options())
 
415
    {
 
416
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
417
      if (indx_options.pack_key())
 
418
        keyinfo->flags|= HA_PACK_KEY;
 
419
 
 
420
      if (indx_options.var_length_key())
 
421
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
422
 
 
423
      if (indx_options.null_part_key())
 
424
        keyinfo->flags|= HA_NULL_PART_KEY;
 
425
 
 
426
      if (indx_options.binary_pack_key())
 
427
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
428
 
 
429
      if (indx_options.has_partial_segments())
 
430
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
431
 
 
432
      if (indx_options.auto_generated_key())
 
433
        keyinfo->flags|= HA_GENERATED_KEY;
 
434
 
 
435
      if (indx_options.has_key_block_size())
 
436
      {
 
437
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
438
        keyinfo->block_size= indx_options.key_block_size();
 
439
      }
 
440
      else
 
441
      {
 
442
        keyinfo->block_size= 0;
 
443
      }
 
444
 
 
445
    }
 
446
 
 
447
    switch(indx.type())
 
448
    {
 
449
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
 
450
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
451
      break;
 
452
    case drizzled::message::Table::Index::BTREE:
 
453
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
454
      break;
 
455
    case drizzled::message::Table::Index::RTREE:
 
456
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
457
      break;
 
458
    case drizzled::message::Table::Index::HASH:
 
459
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
460
      break;
 
461
    case drizzled::message::Table::Index::FULLTEXT:
 
462
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
463
 
 
464
    default:
 
465
      /* TODO: suitable warning ? */
 
466
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
467
      break;
 
468
    }
 
469
 
 
470
    keyinfo->key_length= indx.key_length();
 
471
 
 
472
    keyinfo->key_parts= indx.index_part_size();
 
473
 
 
474
    keyinfo->key_part= key_part;
 
475
    keyinfo->rec_per_key= rec_per_key;
 
476
 
 
477
    for (unsigned int partnr= 0;
 
478
        partnr < keyinfo->key_parts;
 
479
        partnr++, key_part++)
 
480
    {
 
481
      drizzled::message::Table::Index::IndexPart part;
 
482
      part= indx.index_part(partnr);
 
483
 
 
484
      *rec_per_key++= 0;
 
485
 
 
486
      key_part->field= NULL;
 
487
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
488
      key_part->null_bit= 0;
 
489
      /* key_part->null_offset is only set if null_bit (see later) */
 
490
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
491
      /* key_part->type ???? */
 
492
      key_part->key_part_flag= 0;
 
493
      if (part.has_in_reverse_order())
 
494
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
495
 
 
496
      key_part->length= part.compare_length();
 
497
 
 
498
      key_part->store_length= key_part->length;
 
499
 
 
500
      /* key_part->offset is set later */
 
501
      key_part->key_type= part.key_type();
 
502
 
 
503
    }
 
504
 
 
505
    if (!indx.has_comment())
 
506
    {
 
507
      keyinfo->comment.length= 0;
 
508
      keyinfo->comment.str= NULL;
 
509
    }
 
510
    else
 
511
    {
 
512
      keyinfo->flags|= HA_USES_COMMENT;
 
513
      keyinfo->comment.length= indx.comment().length();
 
514
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
515
                                         indx.comment().c_str(),
 
516
                                         keyinfo->comment.length);
 
517
    }
 
518
 
 
519
    keyinfo->name= strmake_root(&share->mem_root,
 
520
                                indx.name().c_str(),
 
521
                                indx.name().length());
 
522
 
 
523
    share->keynames.type_names[keynr]= keyinfo->name;
 
524
    share->keynames.type_lengths[keynr]= indx.name().length();
 
525
  }
 
526
 
 
527
  share->keys_for_keyread.reset();
 
528
  set_prefix(share->keys_in_use, share->keys);
 
529
 
 
530
  if (table_options.has_connect_string())
 
531
  {
 
532
    size_t len= table_options.connect_string().length();
 
533
    const char* str= table_options.connect_string().c_str();
 
534
 
 
535
    share->connect_string.length= len;
 
536
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
537
  }
 
538
 
 
539
  if (table_options.has_comment())
 
540
  {
 
541
    size_t len= table_options.comment().length();
 
542
    const char* str= table_options.comment().c_str();
 
543
 
 
544
    share->comment.length= len;
 
545
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
546
  }
 
547
 
 
548
  share->key_block_size= table_options.has_key_block_size() ?
 
549
    table_options.key_block_size() : 0;
 
550
 
 
551
  share->fields= table.field_size();
 
552
 
 
553
  share->field= (Field**) alloc_root(&share->mem_root,
 
554
                                     ((share->fields+1) * sizeof(Field*)));
 
555
  share->field[share->fields]= NULL;
 
556
 
 
557
  uint32_t null_fields= 0;
 
558
  share->reclength= 0;
 
559
 
 
560
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
561
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
562
 
 
563
  assert(field_offsets && field_pack_length); // TODO: fixme
 
564
 
 
565
  uint32_t interval_count= 0;
 
566
  uint32_t interval_parts= 0;
 
567
 
 
568
  uint32_t stored_columns_reclength= 0;
 
569
 
 
570
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
571
  {
 
572
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
573
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
 
574
      null_fields++;
 
575
 
 
576
    enum_field_types drizzle_field_type=
 
577
      proto_field_type_to_drizzle_type(pfield.type());
 
578
 
 
579
    field_offsets[fieldnr]= stored_columns_reclength;
 
580
 
 
581
    /* the below switch is very similar to
 
582
       CreateField::create_length_to_internal_length in field.cc
 
583
       (which should one day be replace by just this code)
 
584
    */
 
585
    switch(drizzle_field_type)
 
586
    {
 
587
    case DRIZZLE_TYPE_BLOB:
 
588
    case DRIZZLE_TYPE_VARCHAR:
 
589
      {
 
590
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
591
          pfield.string_options();
 
592
 
 
593
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
594
                                            field_options.collation_id() : 0);
 
595
 
 
596
        if (!cs)
 
597
          cs= default_charset_info;
 
598
 
 
599
        field_pack_length[fieldnr]=
 
600
          calc_pack_length(drizzle_field_type,
 
601
                           field_options.length() * cs->mbmaxlen);
 
602
 
 
603
      }
 
604
      break;
 
605
    case DRIZZLE_TYPE_ENUM:
 
606
      {
 
607
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
608
          pfield.set_options();
 
609
 
 
610
        field_pack_length[fieldnr]=
 
611
          get_enum_pack_length(field_options.field_value_size());
 
612
 
 
613
        interval_count++;
 
614
        interval_parts+= field_options.field_value_size();
 
615
      }
 
616
      break;
 
617
    case DRIZZLE_TYPE_NEWDECIMAL:
 
618
      {
 
619
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
620
 
 
621
        field_pack_length[fieldnr]=
 
622
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
623
      }
 
624
      break;
 
625
    default:
 
626
      /* Zero is okay here as length is fixed for other types. */
 
627
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
628
    }
 
629
 
 
630
    share->reclength+= field_pack_length[fieldnr];
 
631
    stored_columns_reclength+= field_pack_length[fieldnr];
 
632
 
 
633
  }
 
634
 
 
635
  /* data_offset added to stored_rec_length later */
 
636
  share->stored_rec_length= stored_columns_reclength;
 
637
 
 
638
  share->null_fields= null_fields;
 
639
 
 
640
  ulong null_bits= null_fields;
 
641
  if (!table_options.pack_record())
 
642
    null_bits++;
 
643
  ulong data_offset= (null_bits + 7)/8;
 
644
 
 
645
 
 
646
  share->reclength+= data_offset;
 
647
  share->stored_rec_length+= data_offset;
 
648
 
 
649
  ulong rec_buff_length;
 
650
 
 
651
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
652
  share->rec_buff_length= rec_buff_length;
 
653
 
 
654
  unsigned char* record= NULL;
 
655
 
 
656
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
657
                                     rec_buff_length)))
 
658
    abort();
 
659
 
 
660
  memset(record, 0, rec_buff_length);
 
661
 
 
662
  int null_count= 0;
 
663
 
 
664
  if (!table_options.pack_record())
 
665
  {
 
666
    null_count++; // one bit for delete mark.
 
667
    *record|= 1;
 
668
  }
 
669
 
 
670
  share->default_values= record;
 
671
 
 
672
  if (interval_count)
 
673
  {
 
674
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
675
                                           interval_count*sizeof(TYPELIB));
 
676
  }
 
677
  else
 
678
    share->intervals= NULL;
 
679
 
 
680
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
681
                                  (share->fields+1)*sizeof(char*));
 
682
 
 
683
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
684
                                  (share->fields+1)*sizeof(unsigned int));
 
685
 
 
686
  share->fieldnames.type_names[share->fields]= NULL;
 
687
  share->fieldnames.type_lengths[share->fields]= 0;
 
688
  share->fieldnames.count= share->fields;
 
689
 
 
690
 
 
691
  /* Now fix the TYPELIBs for the intervals (enum values)
 
692
     and field names.
 
693
   */
 
694
 
 
695
  uint32_t interval_nr= 0;
 
696
 
 
697
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
698
  {
 
699
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
700
 
 
701
    /* field names */
 
702
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
703
                                                        pfield.name().c_str(),
 
704
                                                        pfield.name().length());
 
705
 
 
706
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
707
 
 
708
    /* enum typelibs */
 
709
    if (pfield.type() != drizzled::message::Table::Field::ENUM)
 
710
      continue;
 
711
 
 
712
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
713
      pfield.set_options();
 
714
 
 
715
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
716
                                             field_options.collation_id() : 0);
 
717
 
 
718
    if (!charset)
 
719
      charset= default_charset_info;
 
720
 
 
721
    TYPELIB *t= &(share->intervals[interval_nr]);
 
722
 
 
723
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
724
                           (field_options.field_value_size()+1)*sizeof(char*));
 
725
 
 
726
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
727
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
728
 
 
729
    t->type_names[field_options.field_value_size()]= NULL;
 
730
    t->type_lengths[field_options.field_value_size()]= 0;
 
731
 
 
732
    t->count= field_options.field_value_size();
 
733
    t->name= NULL;
 
734
 
 
735
    for (int n= 0; n < field_options.field_value_size(); n++)
 
736
    {
 
737
      t->type_names[n]= strmake_root(&share->mem_root,
 
738
                                     field_options.field_value(n).c_str(),
 
739
                                     field_options.field_value(n).length());
 
740
 
 
741
      /* Go ask the charset what the length is as for "" length=1
 
742
         and there's stripping spaces or some other crack going on.
 
743
       */
 
744
      uint32_t lengthsp;
 
745
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
746
                                        field_options.field_value(n).length());
 
747
      t->type_lengths[n]= lengthsp;
 
748
    }
 
749
    interval_nr++;
 
750
  }
 
751
 
 
752
 
 
753
  /* and read the fields */
 
754
  interval_nr= 0;
 
755
 
 
756
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
757
 
 
758
  if (use_hash)
 
759
    use_hash= !hash_init(&share->name_hash,
 
760
                         system_charset_info,
 
761
                         share->fields, 0, 0,
 
762
                         (hash_get_key) get_field_name, 0, 0);
 
763
 
 
764
  unsigned char* null_pos= record;;
 
765
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
766
 
 
767
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
768
  {
 
769
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
770
 
 
771
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
772
 
 
773
    switch(pfield.format())
 
774
    {
 
775
    case drizzled::message::Table::Field::DefaultFormat:
 
776
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
777
      break;
 
778
    case drizzled::message::Table::Field::FixedFormat:
 
779
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
780
      break;
 
781
    case drizzled::message::Table::Field::DynamicFormat:
 
782
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
783
      break;
 
784
    default:
 
785
      assert(1);
 
786
    }
 
787
 
 
788
    Field::utype unireg_type= Field::NONE;
 
789
 
 
790
    if (pfield.has_numeric_options()
 
791
       && pfield.numeric_options().is_autoincrement())
 
792
    {
 
793
      unireg_type= Field::NEXT_NUMBER;
 
794
    }
 
795
 
 
796
    if (pfield.has_options()
 
797
       && pfield.options().has_default_value()
 
798
       && pfield.options().default_value().compare("NOW()") == 0)
 
799
    {
 
800
      if (pfield.options().has_update_value()
 
801
         && pfield.options().update_value().compare("NOW()") == 0)
 
802
      {
 
803
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
804
      }
 
805
      else if (!pfield.options().has_update_value())
 
806
      {
 
807
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
808
      }
 
809
      else
 
810
        assert(1); // Invalid update value.
 
811
    }
 
812
    else if (pfield.has_options()
 
813
             && pfield.options().has_update_value()
 
814
             && pfield.options().update_value().compare("NOW()") == 0)
 
815
    {
 
816
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
817
    }
 
818
 
 
819
    LEX_STRING comment;
 
820
    if (!pfield.has_comment())
 
821
    {
 
822
      comment.str= (char*)"";
 
823
      comment.length= 0;
 
824
    }
 
825
    else
 
826
    {
 
827
      size_t len= pfield.comment().length();
 
828
      const char* str= pfield.comment().c_str();
 
829
 
 
830
      comment.str= strmake_root(&share->mem_root, str, len);
 
831
      comment.length= len;
 
832
    }
 
833
 
 
834
    enum_field_types field_type;
 
835
 
 
836
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
837
 
 
838
    const CHARSET_INFO *charset= &my_charset_bin;
 
839
 
 
840
    if (field_type==DRIZZLE_TYPE_BLOB
 
841
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
842
    {
 
843
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
844
        pfield.string_options();
 
845
 
 
846
      charset= get_charset(field_options.has_collation_id()?
 
847
                           field_options.collation_id() : 0);
 
848
 
 
849
      if (!charset)
 
850
        charset= default_charset_info;
 
851
 
 
852
    }
 
853
 
 
854
    if (field_type==DRIZZLE_TYPE_ENUM)
 
855
    {
 
856
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
857
        pfield.set_options();
 
858
 
 
859
      charset= get_charset(field_options.has_collation_id()?
 
860
                           field_options.collation_id() : 0);
 
861
 
 
862
      if (!charset)
 
863
        charset= default_charset_info;
 
864
 
 
865
    }
 
866
 
 
867
    Item *default_value= NULL;
 
868
 
 
869
    if (pfield.options().has_default_value()
 
870
       || pfield.options().has_default_null()
 
871
       || pfield.options().has_default_bin_value())
 
872
    {
 
873
      default_value= default_value_item(field_type,
 
874
                                        charset,
 
875
                                        pfield.options().default_null(),
 
876
                                        &pfield.options().default_value(),
 
877
                                        &pfield.options().default_bin_value());
 
878
    }
 
879
 
 
880
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
881
 
 
882
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
883
    memset(&temp_table, 0, sizeof(temp_table));
 
884
    temp_table.s= share;
 
885
    temp_table.in_use= session;
 
886
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
887
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
888
 
 
889
    Field* f= make_field(share, &share->mem_root,
 
890
                         record+field_offsets[fieldnr]+data_offset,
 
891
                         pfield.options().length(),
 
892
                         null_pos,
 
893
                         null_bit_pos,
 
894
                         pack_flag,
 
895
                         field_type,
 
896
                         charset,
 
897
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
898
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
899
                         share->intervals+(interval_nr++)
 
900
                         : (TYPELIB*) 0),
 
901
                        share->fieldnames.type_names[fieldnr]);
 
902
 
 
903
    share->field[fieldnr]= f;
 
904
 
 
905
    f->init(&temp_table); /* blob default values need table obj */
 
906
 
 
907
    if (!(f->flags & NOT_NULL_FLAG))
 
908
    {
 
909
      *f->null_ptr|= f->null_bit;
 
910
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
911
        null_pos++;
 
912
      null_count++;
 
913
    }
 
914
 
 
915
    if (default_value)
 
916
    {
 
917
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
918
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
919
      int res= default_value->save_in_field(f, 1);
 
920
      session->count_cuted_fields= old_count_cuted_fields;
 
921
      if (res != 0 && res != 3)
 
922
      {
 
923
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
924
        error= 1;
 
925
        goto err;
 
926
      }
 
927
    }
 
928
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
 
929
            (f->flags & NOT_NULL_FLAG))
 
930
    {
 
931
      f->set_notnull();
 
932
      f->store((int64_t) 1, true);
 
933
    }
 
934
    else
 
935
      f->reset();
 
936
 
 
937
    /* hack to undo f->init() */
 
938
    f->table= NULL;
 
939
    f->orig_table= NULL;
 
940
 
 
941
    f->field_index= fieldnr;
 
942
    f->comment= comment;
 
943
    if (!default_value
 
944
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
945
       && (f->flags & NOT_NULL_FLAG)
 
946
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
947
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
948
 
 
949
    if (f->unireg_check == Field::NEXT_NUMBER)
 
950
      share->found_next_number_field= &(share->field[fieldnr]);
 
951
 
 
952
    if (share->timestamp_field == f)
 
953
      share->timestamp_field_offset= fieldnr;
 
954
 
 
955
    if (use_hash) /* supposedly this never fails... but comments lie */
 
956
      (void) my_hash_insert(&share->name_hash,
 
957
                            (unsigned char*)&(share->field[fieldnr]));
 
958
 
 
959
  }
 
960
 
 
961
  keyinfo= share->key_info;
 
962
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
 
963
  {
 
964
    key_part= keyinfo->key_part;
 
965
 
 
966
    for (unsigned int partnr= 0;
 
967
         partnr < keyinfo->key_parts;
 
968
         partnr++, key_part++)
 
969
    {
 
970
      /* Fix up key_part->offset by adding data_offset.
 
971
         We really should compute offset as well.
 
972
         But at least this way we are a little better. */
 
973
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
974
    }
 
975
  }
 
976
 
 
977
  /*
 
978
    We need to set the unused bits to 1. If the number of bits is a multiple
 
979
    of 8 there are no unused bits.
 
980
  */
 
981
 
 
982
  if (null_count & 7)
 
983
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
984
 
 
985
  share->null_bytes= (null_pos - (unsigned char*) record +
 
986
                      (null_bit_pos + 7) / 8);
 
987
 
 
988
  share->last_null_bit_pos= null_bit_pos;
 
989
 
 
990
  free(field_offsets);
 
991
  free(field_pack_length);
 
992
 
 
993
  if (!(handler_file= get_new_handler(share, session->mem_root,
 
994
                                     share->db_type())))
 
995
    abort(); // FIXME
 
996
 
 
997
  /* Fix key stuff */
 
998
  if (share->key_parts)
 
999
  {
 
1000
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
1001
                                       &share->keynames, 3) - 1);
 
1002
 
 
1003
    int64_t ha_option= handler_file->ha_table_flags();
 
1004
 
 
1005
    keyinfo= share->key_info;
 
1006
    key_part= keyinfo->key_part;
 
1007
 
 
1008
    for (uint32_t key= 0 ; key < share->keys ; key++,keyinfo++)
 
1009
    {
 
1010
      uint32_t usable_parts= 0;
 
1011
 
 
1012
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
 
1013
      {
 
1014
        /*
 
1015
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1016
          declare this as a primary key.
 
1017
        */
 
1018
        primary_key=key;
 
1019
        for (uint32_t i= 0 ; i < keyinfo->key_parts ;i++)
 
1020
        {
 
1021
          uint32_t fieldnr= key_part[i].fieldnr;
 
1022
          if (!fieldnr ||
 
1023
              share->field[fieldnr-1]->null_ptr ||
 
1024
              share->field[fieldnr-1]->key_length() !=
 
1025
              key_part[i].length)
 
1026
          {
 
1027
            primary_key=MAX_KEY;                // Can't be used
 
1028
            break;
 
1029
          }
 
1030
        }
 
1031
      }
 
1032
 
 
1033
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1034
      {
 
1035
        Field *field;
 
1036
        if (!key_part->fieldnr)
 
1037
        {
 
1038
//          error= 4;                             // Wrong file
 
1039
          abort(); // goto err;
 
1040
        }
 
1041
        field= key_part->field= share->field[key_part->fieldnr-1];
 
1042
        key_part->type= field->key_type();
 
1043
        if (field->null_ptr)
 
1044
        {
 
1045
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1046
                                        share->default_values);
 
1047
          key_part->null_bit= field->null_bit;
 
1048
          key_part->store_length+=HA_KEY_NULL_LENGTH;
 
1049
          keyinfo->flags|=HA_NULL_PART_KEY;
 
1050
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
 
1051
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
1052
        }
 
1053
        if (field->type() == DRIZZLE_TYPE_BLOB ||
 
1054
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
 
1055
        {
 
1056
          if (field->type() == DRIZZLE_TYPE_BLOB)
 
1057
            key_part->key_part_flag|= HA_BLOB_PART;
 
1058
          else
 
1059
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
 
1060
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
 
1061
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
 
1062
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
 
1063
        }
 
1064
        if (i == 0 && key != primary_key)
 
1065
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
 
1066
                           (keyinfo->key_parts == 1)) ?
 
1067
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
 
1068
        if (i == 0)
 
1069
          field->key_start.set(key);
 
1070
        if (field->key_length() == key_part->length &&
 
1071
            !(field->flags & BLOB_FLAG))
 
1072
        {
 
1073
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
 
1074
          {
 
1075
            share->keys_for_keyread.set(key);
 
1076
            field->part_of_key.set(key);
 
1077
            field->part_of_key_not_clustered.set(key);
 
1078
          }
 
1079
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1080
            field->part_of_sortkey.set(key);
 
1081
        }
 
1082
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
 
1083
            usable_parts == i)
 
1084
          usable_parts++;                       // For FILESORT
 
1085
        field->flags|= PART_KEY_FLAG;
 
1086
        if (key == primary_key)
 
1087
        {
 
1088
          field->flags|= PRI_KEY_FLAG;
 
1089
          /*
 
1090
            If this field is part of the primary key and all keys contains
 
1091
            the primary key, then we can use any key to find this column
 
1092
          */
 
1093
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
 
1094
          {
 
1095
            field->part_of_key= share->keys_in_use;
 
1096
            if (field->part_of_sortkey.test(key))
 
1097
              field->part_of_sortkey= share->keys_in_use;
 
1098
          }
 
1099
        }
 
1100
        if (field->key_length() != key_part->length)
 
1101
        {
 
1102
          key_part->key_part_flag|= HA_PART_KEY_SEG;
 
1103
        }
 
1104
      }
 
1105
      keyinfo->usable_key_parts= usable_parts; // Filesort
 
1106
 
 
1107
      set_if_bigger(share->max_key_length,keyinfo->key_length+
 
1108
                    keyinfo->key_parts);
 
1109
      share->total_key_length+= keyinfo->key_length;
 
1110
      /*
 
1111
        MERGE tables do not have unique indexes. But every key could be
 
1112
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1113
      */
 
1114
      if ((keyinfo->flags & HA_NOSAME) ||
 
1115
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
 
1116
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
 
1117
    }
 
1118
    if (primary_key < MAX_KEY &&
 
1119
        (share->keys_in_use.test(primary_key)))
 
1120
    {
 
1121
      share->primary_key= primary_key;
 
1122
      /*
 
1123
        If we are using an integer as the primary key then allow the user to
 
1124
        refer to it as '_rowid'
 
1125
      */
 
1126
      if (share->key_info[primary_key].key_parts == 1)
 
1127
      {
 
1128
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1129
        if (field && field->result_type() == INT_RESULT)
 
1130
        {
 
1131
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
 
1132
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1133
                                      fieldnr);
 
1134
        }
 
1135
      }
 
1136
 
 
1137
    }
 
1138
    else
 
1139
      share->primary_key = MAX_KEY; // we do not have a primary key
 
1140
  }
 
1141
  else
 
1142
    share->primary_key= MAX_KEY;
 
1143
 
 
1144
  if (share->found_next_number_field)
 
1145
  {
 
1146
    Field *reg_field= *share->found_next_number_field;
 
1147
    if ((int) (share->next_number_index= (uint32_t)
 
1148
               find_ref_key(share->key_info, share->keys,
 
1149
                            share->default_values, reg_field,
 
1150
                            &share->next_number_key_offset,
 
1151
                            &share->next_number_keypart)) < 0)
 
1152
    {
 
1153
      /* Wrong field definition */
 
1154
      error= 4;
 
1155
      goto err;
 
1156
    }
 
1157
    else
 
1158
      reg_field->flags |= AUTO_INCREMENT_FLAG;
 
1159
  }
 
1160
 
 
1161
  if (share->blob_fields)
 
1162
  {
 
1163
    Field **ptr;
 
1164
    uint32_t k, *save;
 
1165
 
 
1166
    /* Store offsets to blob fields to find them fast */
 
1167
    if (!(share->blob_field= save=
 
1168
          (uint*) alloc_root(&share->mem_root,
 
1169
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1170
      goto err;
 
1171
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
 
1172
    {
 
1173
      if ((*ptr)->flags & BLOB_FLAG)
 
1174
        (*save++)= k;
 
1175
    }
 
1176
  }
 
1177
 
 
1178
  share->db_low_byte_first= handler_file->low_byte_first();
 
1179
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
 
1180
 
 
1181
  my_bitmap_map *bitmaps;
 
1182
 
 
1183
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
 
1184
                                             share->column_bitmap_size)))
 
1185
    goto err;
 
1186
  bitmap_init(&share->all_set, bitmaps, share->fields);
 
1187
  bitmap_set_all(&share->all_set);
 
1188
 
 
1189
  if (handler_file)
 
1190
    delete handler_file;
 
1191
  return (0);
 
1192
 
 
1193
err:
 
1194
  share->error= error;
 
1195
  share->open_errno= my_errno;
 
1196
  share->errarg= 0;
 
1197
  hash_free(&share->name_hash);
 
1198
  if (handler_file)
 
1199
    delete handler_file;
 
1200
  share->open_table_error(error, share->open_errno, 0);
 
1201
 
 
1202
  return error;
 
1203
}
 
1204
 
 
1205
/*
 
1206
  Read table definition from a binary / text based .frm file
 
1207
 
 
1208
  SYNOPSIS
 
1209
  open_table_def()
 
1210
  session               Thread handler
 
1211
  share         Fill this with table definition
 
1212
 
 
1213
  NOTES
 
1214
    This function is called when the table definition is not cached in
 
1215
    table_def_cache
 
1216
    The data is returned in 'share', which is alloced by
 
1217
    alloc_table_share().. The code assumes that share is initialized.
 
1218
 
 
1219
  RETURN VALUES
 
1220
   0    ok
 
1221
   1    Error (see open_table_error)
 
1222
   2    Error (see open_table_error)
 
1223
   3    Wrong data in .frm file
 
1224
   4    Error (see open_table_error)
 
1225
   5    Error (see open_table_error: charset unavailable)
 
1226
   6    Unknown .frm version
 
1227
*/
 
1228
 
 
1229
int open_table_def(Session *session, TableShare *share)
 
1230
{
 
1231
  int error;
 
1232
  bool error_given;
 
1233
 
 
1234
  error= 1;
 
1235
  error_given= 0;
 
1236
 
 
1237
  drizzled::message::Table table;
 
1238
 
 
1239
  error= StorageEngine::getTableProto(share->normalized_path.str, &table);
 
1240
 
 
1241
  if (error != EEXIST)
 
1242
  {
 
1243
    if (error>0)
 
1244
    {
 
1245
      my_errno= error;
 
1246
      error= 1;
 
1247
    }
 
1248
    else
 
1249
    {
 
1250
      if (!table.IsInitialized())
 
1251
      {
 
1252
        error= 4;
 
1253
      }
 
1254
    }
 
1255
    goto err_not_open;
 
1256
  }
 
1257
 
 
1258
  error= parse_table_proto(session, table, share);
 
1259
 
 
1260
  share->table_category= get_table_category(& share->db);
 
1261
 
 
1262
  if (!error)
 
1263
    session->status_var.opened_shares++;
 
1264
 
 
1265
err_not_open:
 
1266
  if (error && !error_given)
 
1267
  {
 
1268
    share->error= error;
 
1269
    share->open_table_error(error, (share->open_errno= my_errno), 0);
 
1270
  }
 
1271
 
 
1272
  return(error);
 
1273
}
 
1274
 
 
1275
 
 
1276
/*
 
1277
  Open a table based on a TableShare
 
1278
 
 
1279
  SYNOPSIS
 
1280
    open_table_from_share()
 
1281
    session                     Thread handler
 
1282
    share               Table definition
 
1283
    alias               Alias for table
 
1284
    db_stat             open flags (for example HA_OPEN_KEYFILE|
 
1285
                        HA_OPEN_RNDFILE..) can be 0 (example in
 
1286
                        ha_example_table)
 
1287
    prgflag             READ_ALL etc..
 
1288
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
 
1289
    outparam            result table
 
1290
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1291
                        if OTM_CREATE some errors are ignore
 
1292
                        if OTM_ALTER HA_OPEN is not called
 
1293
 
 
1294
  RETURN VALUES
 
1295
   0    ok
 
1296
   1    Error (see open_table_error)
 
1297
   2    Error (see open_table_error)
 
1298
   3    Wrong data in .frm file
 
1299
   4    Error (see open_table_error)
 
1300
   5    Error (see open_table_error: charset unavailable)
 
1301
   7    Table definition has changed in engine
 
1302
*/
 
1303
 
 
1304
int open_table_from_share(Session *session, TableShare *share, const char *alias,
 
1305
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1306
                          Table *outparam, open_table_mode open_mode)
 
1307
{
 
1308
  int error;
 
1309
  uint32_t records, i, bitmap_size;
 
1310
  bool error_reported= false;
 
1311
  unsigned char *record, *bitmaps;
 
1312
  Field **field_ptr;
 
1313
 
 
1314
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1315
  assert(session->lex->is_lex_started);
 
1316
 
 
1317
  error= 1;
 
1318
  outparam->resetTable(session, share, db_stat);
 
1319
 
 
1320
 
 
1321
  if (!(outparam->alias= strdup(alias)))
 
1322
    goto err;
 
1323
 
 
1324
  /* Allocate handler */
 
1325
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1326
  {
 
1327
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1328
                                          share->db_type())))
 
1329
      goto err;
 
1330
  }
 
1331
  else
 
1332
  {
 
1333
    assert(!db_stat);
 
1334
  }
 
1335
 
 
1336
  error= 4;
 
1337
  records= 0;
 
1338
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
 
1339
    records=1;
 
1340
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1341
    records++;
 
1342
 
 
1343
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
 
1344
                                   share->rec_buff_length * records)))
 
1345
    goto err;                                   /* purecov: inspected */
 
1346
 
 
1347
  if (records == 0)
 
1348
  {
 
1349
    /* We are probably in hard repair, and the buffers should not be used */
 
1350
    outparam->record[0]= outparam->record[1]= share->default_values;
 
1351
  }
 
1352
  else
 
1353
  {
 
1354
    outparam->record[0]= record;
 
1355
    if (records > 1)
 
1356
      outparam->record[1]= record+ share->rec_buff_length;
 
1357
    else
 
1358
      outparam->record[1]= outparam->record[0];   // Safety
 
1359
  }
 
1360
 
 
1361
#ifdef HAVE_purify
 
1362
  /*
 
1363
    We need this because when we read var-length rows, we are not updating
 
1364
    bytes after end of varchar
 
1365
  */
 
1366
  if (records > 1)
 
1367
  {
 
1368
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
 
1369
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
 
1370
    if (records > 2)
 
1371
      memcpy(outparam->record[1], share->default_values,
 
1372
             share->rec_buff_length);
 
1373
  }
 
1374
#endif
 
1375
 
 
1376
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1377
                                          (uint32_t) ((share->fields+1)*
 
1378
                                                  sizeof(Field*)))))
 
1379
    goto err;                                   /* purecov: inspected */
 
1380
 
 
1381
  outparam->field= field_ptr;
 
1382
 
 
1383
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1384
 
 
1385
  outparam->null_flags= (unsigned char*) record+1;
 
1386
 
 
1387
  /* Setup copy of fields from share, but use the right alias and record */
 
1388
  for (i= 0 ; i < share->fields; i++, field_ptr++)
 
1389
  {
 
1390
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
 
1391
      goto err;
 
1392
  }
 
1393
  (*field_ptr)= 0;                              // End marker
 
1394
 
 
1395
  if (share->found_next_number_field)
 
1396
    outparam->found_next_number_field=
 
1397
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1398
  if (share->timestamp_field)
 
1399
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
 
1400
 
 
1401
 
 
1402
  /* Fix key->name and key_part->field */
 
1403
  if (share->key_parts)
 
1404
  {
 
1405
    KEY *key_info, *key_info_end;
 
1406
    KEY_PART_INFO *key_part;
 
1407
    uint32_t n_length;
 
1408
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
 
1409
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
 
1410
      goto err;
 
1411
    outparam->key_info= key_info;
 
1412
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
 
1413
 
 
1414
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
 
1415
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
 
1416
                                                   share->key_parts));
 
1417
 
 
1418
    for (key_info_end= key_info + share->keys ;
 
1419
         key_info < key_info_end ;
 
1420
         key_info++)
 
1421
    {
 
1422
      KEY_PART_INFO *key_part_end;
 
1423
 
 
1424
      key_info->table= outparam;
 
1425
      key_info->key_part= key_part;
 
1426
 
 
1427
      for (key_part_end= key_part+ key_info->key_parts ;
 
1428
           key_part < key_part_end ;
 
1429
           key_part++)
 
1430
      {
 
1431
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
 
1432
 
 
1433
        if (field->key_length() != key_part->length &&
 
1434
            !(field->flags & BLOB_FLAG))
 
1435
        {
 
1436
          /*
 
1437
            We are using only a prefix of the column as a key:
 
1438
            Create a new field for the key part that matches the index
 
1439
          */
 
1440
          field= key_part->field=field->new_field(&outparam->mem_root,
 
1441
                                                  outparam, 0);
 
1442
          field->field_length= key_part->length;
 
1443
        }
 
1444
      }
 
1445
    }
 
1446
  }
 
1447
 
 
1448
  /* Allocate bitmaps */
 
1449
 
 
1450
  bitmap_size= share->column_bitmap_size;
 
1451
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
 
1452
    goto err;
 
1453
  bitmap_init(&outparam->def_read_set,
 
1454
              (my_bitmap_map*) bitmaps, share->fields);
 
1455
  bitmap_init(&outparam->def_write_set,
 
1456
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
 
1457
  bitmap_init(&outparam->tmp_set,
 
1458
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
 
1459
  outparam->default_column_bitmaps();
 
1460
 
 
1461
  /* The table struct is now initialized;  Open the table */
 
1462
  error= 2;
 
1463
  if (db_stat && open_mode != OTM_ALTER)
 
1464
  {
 
1465
    int ha_err;
 
1466
    if ((ha_err= (outparam->file->
 
1467
                  ha_open(outparam, share->normalized_path.str,
 
1468
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
1469
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
 
1470
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
 
1471
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
 
1472
                          HA_OPEN_ABORT_IF_LOCKED :
 
1473
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
1474
    {
 
1475
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1476
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1477
                       outparam->file->auto_repair() &&
 
1478
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1479
 
 
1480
      switch (ha_err)
 
1481
      {
 
1482
        case HA_ERR_NO_SUCH_TABLE:
 
1483
          /*
 
1484
            The table did not exists in storage engine, use same error message
 
1485
            as if the .frm file didn't exist
 
1486
          */
 
1487
          error= 1;
 
1488
          my_errno= ENOENT;
 
1489
          break;
 
1490
        case EMFILE:
 
1491
          /*
 
1492
            Too many files opened, use same error message as if the .frm
 
1493
            file can't open
 
1494
           */
 
1495
          error= 1;
 
1496
          my_errno= EMFILE;
 
1497
          break;
 
1498
        default:
 
1499
          outparam->file->print_error(ha_err, MYF(0));
 
1500
          error_reported= true;
 
1501
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
 
1502
            error= 7;
 
1503
          break;
 
1504
      }
 
1505
      goto err;                                 /* purecov: inspected */
 
1506
    }
 
1507
  }
 
1508
 
 
1509
#if defined(HAVE_purify)
 
1510
  memset(bitmaps, 0, bitmap_size*3);
 
1511
#endif
 
1512
 
 
1513
  session->status_var.opened_tables++;
 
1514
 
 
1515
  return (0);
 
1516
 
 
1517
 err:
 
1518
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1519
    share->open_table_error(error, my_errno, 0);
 
1520
  delete outparam->file;
 
1521
  outparam->file= 0;                            // For easier error checking
 
1522
  outparam->db_stat= 0;
 
1523
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
 
1524
  free((char*) outparam->alias);
 
1525
  return (error);
 
1526
}
 
1527
 
 
1528
/*
 
1529
  Free information allocated by openfrm
 
1530
 
 
1531
  SYNOPSIS
 
1532
    closefrm()
 
1533
    table               Table object to free
 
1534
    free_share          Is 1 if we also want to free table_share
 
1535
*/
 
1536
 
 
1537
int Table::closefrm(bool free_share)
78
1538
{
79
1539
  int error= 0;
80
1540
 
81
1541
  if (db_stat)
82
 
    error= cursor->close();
83
 
  _alias.clear();
84
 
 
 
1542
    error= file->close();
 
1543
  free((char*) alias);
 
1544
  alias= NULL;
85
1545
  if (field)
86
1546
  {
87
1547
    for (Field **ptr=field ; *ptr ; ptr++)
88
 
    {
89
1548
      delete *ptr;
90
 
    }
91
1549
    field= 0;
92
1550
  }
93
 
  delete cursor;
94
 
  cursor= 0;                            /* For easier errorchecking */
95
 
 
 
1551
  delete file;
 
1552
  file= 0;                              /* For easier errorchecking */
96
1553
  if (free_share)
97
1554
  {
98
 
    release();
 
1555
    if (s->tmp_table == NO_TMP_TABLE)
 
1556
      TableShare::release(s);
 
1557
    else
 
1558
      s->free_table_share();
99
1559
  }
 
1560
  free_root(&mem_root, MYF(0));
100
1561
 
101
1562
  return error;
102
1563
}
103
1564
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
 
 
110
 
void Table::resetTable(Session *session,
111
 
                       TableShare *share,
112
 
                       uint32_t db_stat_arg)
113
 
{
114
 
  setShare(share);
115
 
  in_use= session;
116
 
 
117
 
  field= NULL;
118
 
 
119
 
  cursor= NULL;
120
 
  next= NULL;
121
 
  prev= NULL;
122
 
 
123
 
  read_set= NULL;
124
 
  write_set= NULL;
125
 
 
126
 
  tablenr= 0;
127
 
  db_stat= db_stat_arg;
128
 
 
129
 
  record[0]= (unsigned char *) NULL;
130
 
  record[1]= (unsigned char *) NULL;
131
 
 
132
 
  insert_values.clear();
133
 
  key_info= NULL;
134
 
  next_number_field= NULL;
135
 
  found_next_number_field= NULL;
136
 
  timestamp_field= NULL;
137
 
 
138
 
  pos_in_table_list= NULL;
139
 
  group= NULL;
140
 
  _alias.clear();
141
 
  null_flags= NULL;
142
 
 
143
 
  lock_position= 0;
144
 
  lock_data_start= 0;
145
 
  lock_count= 0;
146
 
  used_fields= 0;
147
 
  status= 0;
148
 
  derived_select_number= 0;
149
 
  current_lock= F_UNLCK;
150
 
  copy_blobs= false;
151
 
 
152
 
  maybe_null= false;
153
 
 
154
 
  null_row= false;
155
 
 
156
 
  force_index= false;
157
 
  distinct= false;
158
 
  const_table= false;
159
 
  no_rows= false;
160
 
  key_read= false;
161
 
  no_keyread= false;
162
 
 
163
 
  open_placeholder= false;
164
 
  locked_by_name= false;
165
 
  no_cache= false;
166
 
 
167
 
  auto_increment_field_not_null= false;
168
 
  alias_name_used= false;
169
 
 
170
 
  query_id= 0;
171
 
  quick_condition_rows= 0;
172
 
 
173
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
174
 
  map= 0;
175
 
 
176
 
  reginfo.reset();
177
 
 
178
 
  covering_keys.reset();
179
 
 
180
 
  quick_keys.reset();
181
 
  merge_keys.reset();
182
 
 
183
 
  keys_in_use_for_query.reset();
184
 
  keys_in_use_for_group_by.reset();
185
 
  keys_in_use_for_order_by.reset();
186
 
 
187
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
188
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
189
 
 
190
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
191
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
 
 
193
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
194
 
}
195
 
 
196
 
 
197
1565
 
198
1566
/* Deallocate temporary blob storage */
199
1567
 
203
1571
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
204
1572
       ptr != end ;
205
1573
       ptr++)
206
 
  {
207
 
    ((Field_blob*) table->getField(*ptr))->free();
208
 
  }
 
1574
    ((Field_blob*) table->field[*ptr])->free();
209
1575
}
210
1576
 
211
1577
 
212
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
213
 
{
214
 
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
 
1578
        /* error message when opening a form file */
 
1579
 
 
1580
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
 
1581
{
 
1582
  int err_no;
 
1583
  char buff[FN_REFLEN];
 
1584
  myf errortype= ME_ERROR+ME_WAITTANG;
 
1585
 
 
1586
  switch (pass_error) {
 
1587
  case 7:
 
1588
  case 1:
 
1589
    if (db_errno == ENOENT)
 
1590
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
 
1591
    else
 
1592
    {
 
1593
      sprintf(buff,"%s",normalized_path.str);
 
1594
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
1595
               errortype, buff, db_errno);
 
1596
    }
 
1597
    break;
 
1598
  case 2:
 
1599
  {
 
1600
    handler *file= 0;
 
1601
    const char *datext= "";
 
1602
 
 
1603
    if (db_type() != NULL)
 
1604
    {
 
1605
      if ((file= get_new_handler(this, current_session->mem_root,
 
1606
                                 db_type())))
 
1607
      {
 
1608
        if (!(datext= *db_type()->bas_ext()))
 
1609
          datext= "";
 
1610
      }
 
1611
    }
 
1612
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
1613
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
1614
    sprintf(buff,"%s%s", normalized_path.str,datext);
 
1615
    my_error(err_no,errortype, buff, db_errno);
 
1616
    delete file;
 
1617
    break;
 
1618
  }
 
1619
  case 5:
 
1620
  {
 
1621
    const char *csname= get_charset_name((uint32_t) pass_errarg);
 
1622
    char tmp[10];
 
1623
    if (!csname || csname[0] =='?')
 
1624
    {
 
1625
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
 
1626
      csname= tmp;
 
1627
    }
 
1628
    my_printf_error(ER_UNKNOWN_COLLATION,
 
1629
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
1630
                    MYF(0), csname, table_name.str);
 
1631
    break;
 
1632
  }
 
1633
  case 6:
 
1634
    sprintf(buff,"%s", normalized_path.str);
 
1635
    my_printf_error(ER_NOT_FORM_FILE,
 
1636
                    _("Table '%-.64s' was created with a different version "
 
1637
                    "of Drizzle and cannot be read"),
 
1638
                    MYF(0), buff);
 
1639
    break;
 
1640
  case 8:
 
1641
    break;
 
1642
  default:                              /* Better wrong error than none */
 
1643
  case 4:
 
1644
    sprintf(buff,"%s", normalized_path.str);
 
1645
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
 
1646
    break;
 
1647
  }
 
1648
  return;
 
1649
} /* open_table_error */
 
1650
 
 
1651
 
 
1652
TYPELIB *typelib(MEM_ROOT *mem_root, vector<String*> &strings)
 
1653
{
 
1654
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
215
1655
  if (!result)
216
1656
    return 0;
217
 
  result->count= strings.elements;
 
1657
  result->count= strings.size();
218
1658
  result->name= "";
219
1659
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
220
1660
  
221
 
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
 
1661
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
222
1662
    return 0;
223
1663
    
224
1664
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
1665
 
226
 
  List_iterator<String> it(strings);
227
 
  String *tmp;
228
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
1666
  vector<String*>::iterator it= strings.begin();
 
1667
  for (int i= 0; it != strings.end(); ++it, ++i )
229
1668
  {
230
 
    result->type_names[i]= tmp->ptr();
231
 
    result->type_lengths[i]= tmp->length();
 
1669
    result->type_names[i]= (*it)->c_ptr();
 
1670
    result->type_lengths[i]= (*it)->length();
232
1671
  }
233
1672
 
234
1673
  result->type_names[result->count]= 0;   // End marker
248
1687
  return (nr);
249
1688
} /* set_zone */
250
1689
 
 
1690
        /* Adjust number to next larger disk buffer */
 
1691
 
 
1692
ulong next_io_size(register ulong pos)
 
1693
{
 
1694
  register ulong offset;
 
1695
  if ((offset= pos & (IO_SIZE-1)))
 
1696
    return pos-offset+IO_SIZE;
 
1697
  return pos;
 
1698
} /* next_io_size */
 
1699
 
251
1700
 
252
1701
/*
253
1702
  Store an SQL quoted string.
275
1724
        (mblen= my_ismbchar(default_charset_info, pos, end)))
276
1725
    {
277
1726
      res->append(pos, mblen);
278
 
      pos+= mblen - 1;
 
1727
      pos+= mblen;
279
1728
      if (pos >= end)
280
1729
        break;
281
1730
      continue;
311
1760
}
312
1761
 
313
1762
 
 
1763
/*
 
1764
  Set up column usage bitmaps for a temporary table
 
1765
 
 
1766
  IMPLEMENTATION
 
1767
    For temporary tables, we need one bitmap with all columns set and
 
1768
    a tmp_set bitmap to be used by things like filesort.
 
1769
*/
 
1770
 
 
1771
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
1772
{
 
1773
  uint32_t field_count= s->fields;
 
1774
 
 
1775
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count);
 
1776
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
1777
 
 
1778
  /* write_set and all_set are copies of read_set */
 
1779
  def_write_set= def_read_set;
 
1780
  s->all_set= def_read_set;
 
1781
  bitmap_set_all(&this->s->all_set);
 
1782
  default_column_bitmaps();
 
1783
}
 
1784
 
 
1785
 
 
1786
 
 
1787
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
1788
{
 
1789
  create_info->max_rows= s->max_rows;
 
1790
  create_info->min_rows= s->min_rows;
 
1791
  create_info->table_options= s->db_create_options;
 
1792
  create_info->avg_row_length= s->avg_row_length;
 
1793
  create_info->block_size= s->block_size;
 
1794
  create_info->row_type= s->row_type;
 
1795
  create_info->default_table_charset= s->table_charset;
 
1796
  create_info->table_charset= 0;
 
1797
  create_info->comment= s->comment;
 
1798
 
 
1799
  return;
 
1800
}
 
1801
 
314
1802
int rename_file_ext(const char * from,const char * to,const char * ext)
315
1803
{
316
1804
  string from_s, to_s;
319
1807
  from_s.append(ext);
320
1808
  to_s.append(to);
321
1809
  to_s.append(ext);
322
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1810
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1811
}
 
1812
 
 
1813
/*
 
1814
  DESCRIPTION
 
1815
    given a buffer with a key value, and a map of keyparts
 
1816
    that are present in this value, returns the length of the value
 
1817
*/
 
1818
uint32_t calculate_key_len(Table *table, uint32_t key,
 
1819
                       const unsigned char *,
 
1820
                       key_part_map keypart_map)
 
1821
{
 
1822
  /* works only with key prefixes */
 
1823
  assert(((keypart_map + 1) & keypart_map) == 0);
 
1824
 
 
1825
  KEY *key_info= table->s->key_info+key;
 
1826
  KEY_PART_INFO *key_part= key_info->key_part;
 
1827
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
 
1828
  uint32_t length= 0;
 
1829
 
 
1830
  while (key_part < end_key_part && keypart_map)
 
1831
  {
 
1832
    length+= key_part->store_length;
 
1833
    keypart_map >>= 1;
 
1834
    key_part++;
 
1835
  }
 
1836
  return length;
323
1837
}
324
1838
 
325
1839
/*
330
1844
    org_name            Name of database and length
331
1845
 
332
1846
  RETURN
333
 
    false error
334
 
    true ok
 
1847
    0   ok
 
1848
    1   error
335
1849
*/
336
1850
 
337
 
bool check_db_name(Session *session, identifier::Schema &schema_identifier)
 
1851
bool check_db_name(LEX_STRING *org_name)
338
1852
{
339
 
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
340
 
  {
341
 
    return false;
342
 
  }
343
 
 
344
 
  return schema_identifier.isValid();
 
1853
  char *name= org_name->str;
 
1854
  uint32_t name_length= org_name->length;
 
1855
 
 
1856
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
1857
    return 1;
 
1858
 
 
1859
  if (name != any_db)
 
1860
    my_casedn_str(files_charset_info, name);
 
1861
 
 
1862
  return check_identifier_name(org_name);
345
1863
}
346
1864
 
 
1865
 
347
1866
/*
348
1867
  Allow anything as a table name, as long as it doesn't contain an
349
1868
  ' ' at the end
414
1933
    bitmap_clear_all(&table->def_read_set);
415
1934
    bitmap_clear_all(&table->def_write_set);
416
1935
  */
417
 
  def_read_set.reset();
418
 
  def_write_set.reset();
419
 
  column_bitmaps_set(def_read_set, def_write_set);
 
1936
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
1937
  column_bitmaps_set(&def_read_set, &def_write_set);
420
1938
}
421
1939
 
422
1940
 
423
1941
/*
424
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
1942
  Tell handler we are going to call position() and rnd_pos() later.
425
1943
 
426
1944
  NOTES:
427
1945
  This is needed for handlers that uses the primary key to find the
432
1950
void Table::prepare_for_position()
433
1951
{
434
1952
 
435
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
436
 
      getShare()->hasPrimaryKey())
 
1953
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
1954
      s->primary_key < MAX_KEY)
437
1955
  {
438
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
1956
    mark_columns_used_by_index_no_reset(s->primary_key);
439
1957
  }
440
1958
  return;
441
1959
}
453
1971
 
454
1972
void Table::mark_columns_used_by_index(uint32_t index)
455
1973
{
456
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
1974
  MY_BITMAP *bitmap= &tmp_set;
457
1975
 
458
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
459
 
  bitmap->reset();
460
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
461
 
  column_bitmaps_set(*bitmap, *bitmap);
 
1976
  (void) file->extra(HA_EXTRA_KEYREAD);
 
1977
  bitmap_clear_all(bitmap);
 
1978
  mark_columns_used_by_index_no_reset(index, bitmap);
 
1979
  column_bitmaps_set(bitmap, bitmap);
462
1980
  return;
463
1981
}
464
1982
 
478
1996
{
479
1997
 
480
1998
  key_read= 0;
481
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
1999
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
482
2000
  default_column_bitmaps();
483
2001
  return;
484
2002
}
490
2008
 
491
2009
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
492
2010
{
493
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
2011
    mark_columns_used_by_index_no_reset(index, read_set);
494
2012
}
495
2013
 
496
 
 
497
2014
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
498
 
                                                boost::dynamic_bitset<>& bitmap)
 
2015
                                                MY_BITMAP *bitmap)
499
2016
{
500
 
  KeyPartInfo *key_part= key_info[index].key_part;
501
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
502
 
  for (; key_part != key_part_end; key_part++)
503
 
  {
504
 
    if (! bitmap.empty())
505
 
      bitmap.set(key_part->fieldnr-1);
506
 
  }
 
2017
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
2018
  KEY_PART_INFO *key_part_end= (key_part +
 
2019
                                key_info[index].key_parts);
 
2020
  for (;key_part != key_part_end; key_part++)
 
2021
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
507
2022
}
508
2023
 
509
2024
 
522
2037
    We must set bit in read set as update_auto_increment() is using the
523
2038
    store() to check overflow of auto_increment values
524
2039
  */
525
 
  setReadSet(found_next_number_field->position());
526
 
  setWriteSet(found_next_number_field->position());
527
 
  if (getShare()->next_number_keypart)
528
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
2040
  setReadSet(found_next_number_field->field_index);
 
2041
  setWriteSet(found_next_number_field->field_index);
 
2042
  if (s->next_number_keypart)
 
2043
    mark_columns_used_by_index_no_reset(s->next_number_index);
529
2044
}
530
2045
 
531
2046
 
550
2065
void Table::mark_columns_needed_for_delete()
551
2066
{
552
2067
  /*
553
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2068
    If the handler has no cursor capabilites, or we have row-based
554
2069
    replication active for the current statement, we have to read
555
2070
    either the primary key, the hidden primary key or all columns to
556
2071
    be able to do an delete
557
2072
 
558
2073
  */
559
 
  if (not getShare()->hasPrimaryKey())
 
2074
  if (s->primary_key == MAX_KEY)
560
2075
  {
561
2076
    /* fallback to use all columns in the table to identify row */
562
2077
    use_all_columns();
563
2078
    return;
564
2079
  }
565
2080
  else
566
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2081
    mark_columns_used_by_index_no_reset(s->primary_key);
567
2082
 
568
2083
  /* If we the engine wants all predicates we mark all keys */
569
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2084
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
570
2085
  {
571
2086
    Field **reg_field;
572
2087
    for (reg_field= field ; *reg_field ; reg_field++)
573
2088
    {
574
2089
      if ((*reg_field)->flags & PART_KEY_FLAG)
575
 
        setReadSet((*reg_field)->position());
 
2090
        setReadSet((*reg_field)->field_index);
576
2091
    }
577
2092
  }
578
2093
}
590
2105
    if neeed, either the primary key column or all columns to be read.
591
2106
    (see mark_columns_needed_for_delete() for details)
592
2107
 
593
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2108
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
594
2109
    mark all USED key columns as 'to-be-read'. This allows the engine to
595
2110
    loop over the given record to find all changed keys and doesn't have to
596
2111
    retrieve the row again.
599
2114
void Table::mark_columns_needed_for_update()
600
2115
{
601
2116
  /*
602
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2117
    If the handler has no cursor capabilites, or we have row-based
603
2118
    logging active for the current statement, we have to read either
604
2119
    the primary key, the hidden primary key or all columns to be
605
2120
    able to do an update
606
2121
  */
607
 
  if (not getShare()->hasPrimaryKey())
 
2122
  if (s->primary_key == MAX_KEY)
608
2123
  {
609
2124
    /* fallback to use all columns in the table to identify row */
610
2125
    use_all_columns();
611
2126
    return;
612
2127
  }
613
2128
  else
614
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2129
    mark_columns_used_by_index_no_reset(s->primary_key);
615
2130
 
616
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2131
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
617
2132
  {
618
2133
    /* Mark all used key columns for read */
619
2134
    Field **reg_field;
621
2136
    {
622
2137
      /* Merge keys is all keys that had a column refered to in the query */
623
2138
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
624
 
        setReadSet((*reg_field)->position());
 
2139
        setReadSet((*reg_field)->field_index);
625
2140
    }
626
2141
  }
627
2142
 
629
2144
 
630
2145
 
631
2146
/*
632
 
  Mark columns the Cursor needs for doing an insert
 
2147
  Mark columns the handler needs for doing an insert
633
2148
 
634
2149
  For now, this is used to mark fields used by the trigger
635
2150
  as changed.
653
2168
  {
654
2169
    Field_blob* const blob= (Field_blob*) field[*ptr];
655
2170
    length+= blob->get_length((const unsigned char*)
656
 
                              (data + blob->offset(getInsertRecord()))) +
 
2171
                              (data + blob->offset(record[0]))) +
657
2172
      HA_KEY_BLOB_LENGTH;
658
2173
  }
659
2174
  return length;
660
2175
}
661
2176
 
662
 
void Table::setVariableWidth(void)
663
 
{
664
 
  assert(in_use);
665
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
666
 
  {
667
 
    getMutableShare()->setVariableWidth();
668
 
    return;
669
 
  }
670
 
 
671
 
  assert(0); // Programming error, you can't set this on a plain old Table.
672
 
}
673
 
 
674
2177
/****************************************************************************
675
2178
 Functions for creating temporary tables.
676
2179
****************************************************************************/
 
2180
 
 
2181
 
 
2182
/* Prototypes */
 
2183
void free_tmp_table(Session *session, Table *entry);
 
2184
 
677
2185
/**
678
2186
  Create field for temporary table from given field.
679
2187
 
680
 
  @param session               Thread Cursor
 
2188
  @param session               Thread handler
681
2189
  @param org_field    field from which new field will be created
682
2190
  @param name         New field name
683
2191
  @param table         Temporary table
708
2216
  */
709
2217
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
710
2218
      (org_field->flags & BLOB_FLAG))
711
 
  {
712
 
    table->setVariableWidth();
713
2219
    new_field= new Field_varstring(convert_blob_length,
714
2220
                                   org_field->maybe_null(),
715
 
                                   org_field->field_name,
 
2221
                                   org_field->field_name, table->s,
716
2222
                                   org_field->charset());
717
 
  }
718
2223
  else
719
 
  {
720
2224
    new_field= org_field->new_field(session->mem_root, table,
721
 
                                    table == org_field->getTable());
722
 
  }
 
2225
                                    table == org_field->table);
723
2226
  if (new_field)
724
2227
  {
725
2228
    new_field->init(table);
732
2235
    if (org_field->maybe_null() || (item && item->maybe_null))
733
2236
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
734
2237
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
735
 
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
 
2238
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
736
2239
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
737
2240
      ((Field_double *) new_field)->not_fixed= true;
738
2241
  }
741
2244
 
742
2245
 
743
2246
/**
 
2247
  Create field for information schema table.
 
2248
 
 
2249
  @param session                Thread handler
 
2250
  @param table          Temporary table
 
2251
  @param item           Item to create a field for
 
2252
 
 
2253
  @retval
 
2254
    0                   on error
 
2255
  @retval
 
2256
    new_created field
 
2257
*/
 
2258
 
 
2259
static Field *create_tmp_field_for_schema(Item *item, Table *table)
 
2260
{
 
2261
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
2262
  {
 
2263
    Field *field;
 
2264
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
2265
      field= new Field_blob(item->max_length, item->maybe_null,
 
2266
                            item->name, item->collation.collation);
 
2267
    else
 
2268
      field= new Field_varstring(item->max_length, item->maybe_null,
 
2269
                                 item->name,
 
2270
                                 table->s, item->collation.collation);
 
2271
    if (field)
 
2272
      field->init(table);
 
2273
    return field;
 
2274
  }
 
2275
  return item->tmp_table_field_from_field_type(table, 0);
 
2276
}
 
2277
 
 
2278
 
 
2279
/**
744
2280
  Create a temp table according to a field list.
745
2281
 
746
2282
  Given field pointers are changed to point at tmp_table for
772
2308
 
773
2309
Table *
774
2310
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
775
 
                 Order *group, bool distinct, bool save_sum_fields,
 
2311
                 order_st *group, bool distinct, bool save_sum_fields,
776
2312
                 uint64_t select_options, ha_rows rows_limit,
777
2313
                 const char *table_alias)
778
2314
{
779
 
  memory::Root *mem_root_save;
 
2315
  MEM_ROOT *mem_root_save, own_root;
 
2316
  Table *table;
 
2317
  TableShare *share;
780
2318
  uint  i,field_count,null_count,null_pack_length;
781
2319
  uint32_t  copy_func_count= param->func_count;
782
2320
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
783
2321
  uint32_t  blob_count,group_null_items, string_count;
784
2322
  uint32_t fieldnr= 0;
785
2323
  ulong reclength, string_total_length;
786
 
  bool  using_unique_constraint= false;
787
 
  bool  use_packed_rows= true;
 
2324
  bool  using_unique_constraint= 0;
 
2325
  bool  use_packed_rows= 0;
788
2326
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
789
 
  unsigned char *pos, *group_buff;
 
2327
  char  *tmpname,path[FN_REFLEN];
 
2328
  unsigned char *pos, *group_buff, *bitmaps;
790
2329
  unsigned char *null_flags;
791
2330
  Field **reg_field, **from_field, **default_field;
 
2331
  uint32_t *blob_field;
792
2332
  CopyField *copy= 0;
793
 
  KeyInfo *keyinfo;
794
 
  KeyPartInfo *key_part_info;
 
2333
  KEY *keyinfo;
 
2334
  KEY_PART_INFO *key_part_info;
795
2335
  Item **copy_func;
796
2336
  MI_COLUMNDEF *recinfo;
797
2337
  uint32_t total_uneven_bit_length= 0;
798
2338
  bool force_copy_fields= param->force_copy_fields;
799
 
  uint64_t max_rows= 0;
800
 
 
801
 
  session->status_var.created_tmp_tables++;
 
2339
 
 
2340
  status_var_increment(session->status_var.created_tmp_tables);
 
2341
 
 
2342
  /* if we run out of slots or we are not using tempool */
 
2343
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
2344
          session->thread_id, session->tmp_table++);
 
2345
 
 
2346
  /*
 
2347
    No need to change table name to lower case as we are only creating
 
2348
    MyISAM or HEAP tables here
 
2349
  */
 
2350
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
2351
 
802
2352
 
803
2353
  if (group)
804
2354
  {
805
 
    if (! param->quick_group)
806
 
    {
 
2355
    if (!param->quick_group)
807
2356
      group= 0;                                 // Can't use group key
808
 
    }
809
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
2357
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
810
2358
    {
811
2359
      /*
812
2360
        marker == 4 means two things:
816
2364
      */
817
2365
      (*tmp->item)->marker= 4;
818
2366
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
819
 
        using_unique_constraint= true;
 
2367
        using_unique_constraint=1;
820
2368
    }
821
2369
    if (param->group_length >= MAX_BLOB_WIDTH)
822
 
      using_unique_constraint= true;
 
2370
      using_unique_constraint=1;
823
2371
    if (group)
824
2372
      distinct= 0;                              // Can't use distinct
825
2373
  }
835
2383
    these items are stored in the temporary table.
836
2384
  */
837
2385
  if (param->precomputed_group_by)
838
 
  {
839
2386
    copy_func_count+= param->sum_func_count;
840
 
  }
841
 
 
842
 
  table::Singular *table;
843
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
844
 
 
845
 
  if (not table->getMemRoot()->multi_alloc_root(0,
846
 
                                                &default_field, sizeof(Field*) * (field_count),
847
 
                                                &from_field, sizeof(Field*)*field_count,
848
 
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
849
 
                                                &param->keyinfo, sizeof(*param->keyinfo),
850
 
                                                &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
851
 
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
852
 
                                                &group_buff, (group && ! using_unique_constraint ?
853
 
                                                              param->group_length : 0),
854
 
                                                NULL))
 
2387
 
 
2388
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2389
 
 
2390
  if (!multi_alloc_root(&own_root,
 
2391
                        &table, sizeof(*table),
 
2392
                        &share, sizeof(*share),
 
2393
                        &reg_field, sizeof(Field*) * (field_count+1),
 
2394
                        &default_field, sizeof(Field*) * (field_count),
 
2395
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
2396
                        &from_field, sizeof(Field*)*field_count,
 
2397
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
2398
                        &param->keyinfo, sizeof(*param->keyinfo),
 
2399
                        &key_part_info,
 
2400
                        sizeof(*key_part_info)*(param->group_parts+1),
 
2401
                        &param->start_recinfo,
 
2402
                        sizeof(*param->recinfo)*(field_count*2+4),
 
2403
                        &tmpname, (uint32_t) strlen(path)+1,
 
2404
                        &group_buff, (group && ! using_unique_constraint ?
 
2405
                                      param->group_length : 0),
 
2406
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
2407
                        NULL))
855
2408
  {
856
 
    return NULL;
 
2409
    return NULL;                                /* purecov: inspected */
857
2410
  }
858
2411
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
859
2412
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
860
2413
  {
861
 
    return NULL;
 
2414
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
2415
    return NULL;                                /* purecov: inspected */
862
2416
  }
863
2417
  param->items_to_copy= copy_func;
 
2418
  strcpy(tmpname,path);
864
2419
  /* make table according to fields */
865
2420
 
 
2421
  memset(table, 0, sizeof(*table));
 
2422
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
866
2423
  memset(default_field, 0, sizeof(Field*) * (field_count));
867
2424
  memset(from_field, 0, sizeof(Field*)*field_count);
868
2425
 
 
2426
  table->mem_root= own_root;
869
2427
  mem_root_save= session->mem_root;
870
 
  session->mem_root= table->getMemRoot();
 
2428
  session->mem_root= &table->mem_root;
871
2429
 
872
 
  table->getMutableShare()->setFields(field_count+1);
873
 
  table->setFields(table->getMutableShare()->getFields(true));
874
 
  reg_field= table->getMutableShare()->getFields(true);
875
 
  table->setAlias(table_alias);
 
2430
  table->field=reg_field;
 
2431
  table->alias= table_alias;
876
2432
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
877
2433
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
878
2434
  table->map=1;
879
2435
  table->copy_blobs= 1;
880
 
  assert(session);
881
2436
  table->in_use= session;
882
2437
  table->quick_keys.reset();
883
2438
  table->covering_keys.reset();
884
2439
  table->keys_in_use_for_query.reset();
885
2440
 
886
 
  table->getMutableShare()->blob_field.resize(field_count+1);
887
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
2441
  table->setShare(share);
 
2442
  share->init(tmpname, tmpname);
 
2443
  share->blob_field= blob_field;
 
2444
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
2445
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
2446
  share->table_charset= param->table_charset;
 
2447
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
2448
  share->keys_for_keyread.reset();
 
2449
  share->keys_in_use.reset();
892
2450
 
893
2451
  /* Calculate which type of fields we will store in the temporary table */
894
2452
 
936
2494
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
937
2495
                             tmp_from_field, &default_field[fieldnr],
938
2496
                             group != 0,not_all_columns,
939
 
                             false,
 
2497
                             distinct, 0,
940
2498
                             param->convert_blob_length);
941
2499
          if (!new_field)
942
2500
            goto err;                                   // Should be OOM
955
2513
          }
956
2514
          session->mem_root= mem_root_save;
957
2515
          session->change_item_tree(argp, new Item_field(new_field));
958
 
          session->mem_root= table->getMemRoot();
 
2516
          session->mem_root= &table->mem_root;
959
2517
          if (!(new_field->flags & NOT_NULL_FLAG))
960
2518
          {
961
2519
            null_count++;
965
2523
            */
966
2524
            (*argp)->maybe_null=1;
967
2525
          }
968
 
          new_field->setPosition(fieldnr++);
 
2526
          new_field->field_index= fieldnr++;
969
2527
        }
970
2528
      }
971
2529
    }
981
2539
        We here distinguish between UNION and multi-table-updates by the fact
982
2540
        that in the later case group is set to the row pointer.
983
2541
      */
984
 
      Field *new_field=
 
2542
      Field *new_field= (param->schema_table) ?
 
2543
        create_tmp_field_for_schema(item, table) :
985
2544
        create_tmp_field(session, table, item, type, &copy_func,
986
2545
                         tmp_from_field, &default_field[fieldnr],
987
2546
                         group != 0,
988
2547
                         !force_copy_fields &&
989
2548
                           (not_all_columns || group != 0),
 
2549
                         /*
 
2550
                           If item->marker == 4 then we force create_tmp_field
 
2551
                           to create a 64-bit longs for BIT fields because HEAP
 
2552
                           tables can't index BIT fields directly. We do the same
 
2553
                           for distinct, as we want the distinct index to be
 
2554
                           usable in this case too.
 
2555
                         */
 
2556
                         item->marker == 4 || param->bit_fields_as_long,
990
2557
                         force_copy_fields,
991
2558
                         param->convert_blob_length);
992
2559
 
1012
2579
        group_null_items++;
1013
2580
        new_field->flags|= GROUP_FLAG;
1014
2581
      }
1015
 
      new_field->setPosition(fieldnr++);
 
2582
      new_field->field_index= fieldnr++;
1016
2583
      *(reg_field++)= new_field;
1017
2584
    }
1018
2585
    if (!--hidden_field_count)
1030
2597
      null_count= 0;
1031
2598
    }
1032
2599
  }
1033
 
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
1034
 
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
 
2600
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
2601
  assert(field_count >= (uint32_t) (reg_field - table->field));
1035
2602
  field_count= fieldnr;
1036
2603
  *reg_field= 0;
1037
2604
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->setFieldSize(field_count);
 
2605
  share->fields= field_count;
1039
2606
 
1040
2607
  /* If result table is small; use a heap */
1041
2608
  /* future: storage engine selection can be made dynamic? */
1042
 
  if (blob_count || using_unique_constraint || 
1043
 
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
1044
 
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
2609
  if (blob_count || using_unique_constraint ||
 
2610
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
2611
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
1046
2612
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
2613
    share->storage_engine= myisam_engine;
 
2614
    table->file= get_new_handler(share, &table->mem_root,
 
2615
                                 share->db_type());
1049
2616
    if (group &&
1050
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
1052
 
    {
1053
 
      using_unique_constraint= true;
1054
 
    }
 
2617
        (param->group_parts > table->file->max_key_parts() ||
 
2618
         param->group_length > table->file->max_key_length()))
 
2619
      using_unique_constraint=1;
1055
2620
  }
1056
2621
  else
1057
2622
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
2623
    share->storage_engine= heap_engine;
 
2624
    table->file= get_new_handler(share, &table->mem_root,
 
2625
                                 share->db_type());
1060
2626
  }
1061
 
  if (! table->cursor)
 
2627
  if (!table->file)
1062
2628
    goto err;
1063
2629
 
1064
2630
 
1065
 
  if (! using_unique_constraint)
 
2631
  if (!using_unique_constraint)
1066
2632
    reclength+= group_null_items;       // null flag is stored separately
1067
2633
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
2634
  share->blob_fields= blob_count;
1069
2635
  if (blob_count == 0)
1070
2636
  {
1071
2637
    /* We need to ensure that first byte is not 0 for the delete link */
1084
2650
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
1085
2651
    use_packed_rows= 1;
1086
2652
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
2653
  share->reclength= reclength;
1088
2654
  {
1089
2655
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
1091
 
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1092
 
    {
 
2656
    share->rec_buff_length= alloc_length;
 
2657
    if (!(table->record[0]= (unsigned char*)
 
2658
                            alloc_root(&table->mem_root, alloc_length*3)))
1093
2659
      goto err;
1094
 
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
2660
    table->record[1]= table->record[0]+alloc_length;
 
2661
    share->default_values= table->record[1]+alloc_length;
1097
2662
  }
1098
2663
  copy_func[0]= 0;                              // End marker
1099
2664
  param->func_count= copy_func - param->items_to_copy;
1100
2665
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
2666
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
2667
 
1103
2668
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
2669
  null_flags=(unsigned char*) table->record[0];
 
2670
  pos=table->record[0]+ null_pack_length;
1106
2671
  if (null_pack_length)
1107
2672
  {
1108
2673
    memset(recinfo, 0, sizeof(*recinfo));
1111
2676
    recinfo++;
1112
2677
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
2678
 
1114
 
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
2679
    table->null_flags= (unsigned char*) table->record[0];
 
2680
    share->null_fields= null_count+ hidden_null_count;
 
2681
    share->null_bytes= null_pack_length;
1117
2682
  }
1118
2683
  null_count= (blob_count == 0) ? 1 : 0;
1119
2684
  hidden_field_count=param->hidden_field_count;
1120
 
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
 
2685
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
1121
2686
  {
1122
2687
    Field *field= *reg_field;
1123
2688
    uint32_t length;
1161
2726
         inherit the default value that is defined for the field referred
1162
2727
         by the Item_field object from which 'field' has been created.
1163
2728
      */
1164
 
      ptrdiff_t diff;
 
2729
      my_ptrdiff_t diff;
1165
2730
      Field *orig_field= default_field[i];
1166
2731
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
2732
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
 
2733
                            orig_field->table->record[0]);
1168
2734
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
2735
      if (orig_field->is_real_null())
1170
2736
        field->set_null();
1173
2739
        field->set_notnull();
1174
2740
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
2741
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
2742
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
2743
    }
1178
2744
 
1179
2745
    if (from_field[i])
1192
2758
      recinfo->type=FIELD_NORMAL;
1193
2759
    if (!--hidden_field_count)
1194
2760
      null_count=(null_count+7) & ~7;           // move to next byte
 
2761
 
 
2762
    // fix table name in field entry
 
2763
    field->table_name= &table->alias;
1195
2764
  }
1196
2765
 
1197
2766
  param->copy_field_end=copy;
1199
2768
  table->storeRecordAsDefault();        // Make empty default record
1200
2769
 
1201
2770
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
1202
 
  {
1203
 
    max_rows= ~(uint64_t) 0;
1204
 
  }
 
2771
    share->max_rows= ~(ha_rows) 0;
1205
2772
  else
1206
 
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
1208
 
                           min(session->variables.tmp_table_size,
1209
 
                               session->variables.max_heap_table_size) :
1210
 
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
1212
 
  }
 
2773
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
2774
                                 min(session->variables.tmp_table_size,
 
2775
                                     session->variables.max_heap_table_size) :
 
2776
                                 session->variables.tmp_table_size) /
 
2777
                                 share->reclength);
1213
2778
 
1214
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
2779
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
1215
2780
  /*
1216
2781
    Push the LIMIT clause to the temporary table creation, so that we
1217
2782
    materialize only up to 'rows_limit' records instead of all result records.
1218
2783
  */
1219
 
  set_if_smaller(max_rows, rows_limit);
1220
 
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
1222
 
 
 
2784
  set_if_smaller(share->max_rows, rows_limit);
1223
2785
  param->end_write_records= rows_limit;
1224
2786
 
1225
2787
  keyinfo= param->keyinfo;
1228
2790
  {
1229
2791
    table->group=group;                         /* Table is grouped by key */
1230
2792
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
2793
    share->keys=1;
 
2794
    share->uniques= test(using_unique_constraint);
1233
2795
    table->key_info=keyinfo;
1234
2796
    keyinfo->key_part=key_part_info;
1235
2797
    keyinfo->flags=HA_NOSAME;
1238
2800
    keyinfo->rec_per_key= 0;
1239
2801
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
2802
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
2803
    order_st *cur_group= group;
1242
2804
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
2805
    {
1244
2806
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
2807
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
2808
      key_part_info->null_bit= 0;
1247
2809
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
2810
      key_part_info->offset= field->offset(table->record[0]);
1249
2811
      key_part_info->length= (uint16_t) field->key_length();
1250
2812
      key_part_info->type=   (uint8_t) field->key_type();
1251
 
      key_part_info->key_type= 
 
2813
      key_part_info->key_type =
1252
2814
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1253
2815
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1254
2816
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1255
 
        0 : 1;
 
2817
        0 : FIELDFLAG_BINARY;
1256
2818
      if (!using_unique_constraint)
1257
2819
      {
1258
2820
        cur_group->buff=(char*) group_buff;
1261
2823
                                                     test(maybe_null),
1262
2824
                                                     field->null_ptr,
1263
2825
                                                     field->null_bit)))
1264
 
          goto err;
 
2826
          goto err; /* purecov: inspected */
1265
2827
        if (maybe_null)
1266
2828
        {
1267
2829
          /*
1273
2835
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
2836
          key_part_info->null_bit=field->null_bit;
1275
2837
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
2838
                                              (unsigned char*) table->record[0]);
1277
2839
          cur_group->buff++;                        // Pointer to field data
1278
2840
          group_buff++;                         // Skipp null flag
1279
2841
        }
1300
2862
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
2863
        used for lookups.
1302
2864
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
2865
      share->uniques= 1;
1304
2866
    }
1305
2867
    null_pack_length-=hidden_null_pack_length;
1306
2868
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
2869
                         (share->uniques ? test(null_pack_length) : 0));
1308
2870
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
1310
 
    if (!(key_part_info= (KeyPartInfo*)
1311
 
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
 
2871
    share->keys= 1;
 
2872
    if (!(key_part_info= (KEY_PART_INFO*)
 
2873
          alloc_root(&table->mem_root,
 
2874
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
1312
2875
      goto err;
1313
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
 
2876
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
1314
2877
    table->key_info=keyinfo;
1315
2878
    keyinfo->key_part=key_part_info;
1316
2879
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
1324
2887
      blobs can distinguish NULL from 0. This extra field is not needed
1325
2888
      when we do not use UNIQUE indexes for blobs.
1326
2889
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
2890
    if (null_pack_length && share->uniques)
1328
2891
    {
1329
2892
      key_part_info->null_bit= 0;
1330
2893
      key_part_info->offset=hidden_null_pack_length;
1331
2894
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
2895
      key_part_info->field= new Field_varstring(table->record[0],
1334
2896
                                                (uint32_t) key_part_info->length,
1335
2897
                                                0,
1336
2898
                                                (unsigned char*) 0,
1337
2899
                                                (uint32_t) 0,
 
2900
                                                Field::NONE,
1338
2901
                                                NULL,
 
2902
                                                table->s,
1339
2903
                                                &my_charset_bin);
1340
2904
      if (!key_part_info->field)
1341
2905
        goto err;
1342
2906
      key_part_info->field->init(table);
1343
 
      key_part_info->key_type= 1; /* binary comparison */
 
2907
      key_part_info->key_type=FIELDFLAG_BINARY;
1344
2908
      key_part_info->type=    HA_KEYTYPE_BINARY;
1345
2909
      key_part_info++;
1346
2910
    }
1347
2911
    /* Create a distinct key over the columns we are going to return */
1348
 
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
 
2912
    for (i=param->hidden_field_count, reg_field=table->field + i ;
1349
2913
         i < field_count;
1350
2914
         i++, reg_field++, key_part_info++)
1351
2915
    {
1352
2916
      key_part_info->null_bit= 0;
1353
2917
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
2918
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
2919
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
1356
 
      /* @todo The below method of computing the key format length of the
1357
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
2920
      /* TODO:
 
2921
        The below method of computing the key format length of the
 
2922
        key part is a copy/paste from opt_range.cc, and table.cc.
1358
2923
        This should be factored out, e.g. as a method of Field.
1359
2924
        In addition it is not clear if any of the Field::*_length
1360
2925
        methods is supposed to compute the same length. If so, it
1373
2938
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
2939
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
2940
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1376
 
        0 : 1;
 
2941
        0 : FIELDFLAG_BINARY;
1377
2942
    }
1378
2943
  }
1379
2944
 
1380
2945
  if (session->is_fatal_error)                          // If end of memory
1381
 
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
2946
    goto err;                                    /* purecov: inspected */
 
2947
  share->db_record_offset= 1;
 
2948
  if (share->db_type() == myisam_engine)
1384
2949
  {
1385
2950
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
2951
                                       &param->recinfo, select_options))
1387
2952
      goto err;
1388
2953
  }
1389
 
  assert(table->in_use);
1390
2954
  if (table->open_tmp_table())
1391
2955
    goto err;
1392
2956
 
1396
2960
 
1397
2961
err:
1398
2962
  session->mem_root= mem_root_save;
1399
 
  table= NULL;
1400
 
 
1401
 
  return NULL;
 
2963
  table->free_tmp_table(session);                    /* purecov: inspected */
 
2964
  return NULL;                          /* purecov: inspected */
1402
2965
}
1403
2966
 
1404
2967
/****************************************************************************/
1405
2968
 
1406
 
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
 
                               boost::dynamic_bitset<>& write_set_arg)
1408
 
{
1409
 
  read_set= &read_set_arg;
1410
 
  write_set= &write_set_arg;
1411
 
}
1412
 
 
1413
 
 
1414
 
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1415
 
{
1416
 
  const boost::dynamic_bitset<> old= in_map;
1417
 
  in_map= getShare()->all_set;
 
2969
/**
 
2970
  Create a reduced Table object with properly set up Field list from a
 
2971
  list of field definitions.
 
2972
 
 
2973
    The created table doesn't have a table handler associated with
 
2974
    it, has no keys, no group/distinct, no copy_funcs array.
 
2975
    The sole purpose of this Table object is to use the power of Field
 
2976
    class to read/write data to/from table->record[0]. Then one can store
 
2977
    the record in any container (RB tree, hash, etc).
 
2978
    The table is created in Session mem_root, so are the table's fields.
 
2979
    Consequently, if you don't BLOB fields, you don't need to free it.
 
2980
 
 
2981
  @param session         connection handle
 
2982
  @param field_list  list of column definitions
 
2983
 
 
2984
  @return
 
2985
    0 if out of memory, Table object in case of success
 
2986
*/
 
2987
 
 
2988
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
2989
{
 
2990
  uint32_t field_count= field_list.elements;
 
2991
  uint32_t blob_count= 0;
 
2992
  Field **field;
 
2993
  CreateField *cdef;                           /* column definition */
 
2994
  uint32_t record_length= 0;
 
2995
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
2996
  uint32_t null_pack_length;              /* NULL representation array length */
 
2997
  uint32_t *blob_field;
 
2998
  unsigned char *bitmaps;
 
2999
  Table *table;
 
3000
  TableShare *share;
 
3001
 
 
3002
  if (!multi_alloc_root(session->mem_root,
 
3003
                        &table, sizeof(*table),
 
3004
                        &share, sizeof(*share),
 
3005
                        &field, (field_count + 1) * sizeof(Field*),
 
3006
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
3007
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
3008
                        NULL))
 
3009
    return NULL;
 
3010
 
 
3011
  memset(table, 0, sizeof(*table));
 
3012
  memset(share, 0, sizeof(*share));
 
3013
  table->field= field;
 
3014
  table->s= share;
 
3015
  share->blob_field= blob_field;
 
3016
  share->fields= field_count;
 
3017
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
3018
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
3019
 
 
3020
  /* Create all fields and calculate the total length of record */
 
3021
  List_iterator_fast<CreateField> it(field_list);
 
3022
  while ((cdef= it++))
 
3023
  {
 
3024
    *field= make_field(share, NULL, 0, cdef->length,
 
3025
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
3026
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
3027
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
 
3028
                       cdef->unireg_check,
 
3029
                       cdef->interval, cdef->field_name);
 
3030
    if (!*field)
 
3031
      goto error;
 
3032
    (*field)->init(table);
 
3033
    record_length+= (*field)->pack_length();
 
3034
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
3035
      null_count++;
 
3036
 
 
3037
    if ((*field)->flags & BLOB_FLAG)
 
3038
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
3039
 
 
3040
    field++;
 
3041
  }
 
3042
  *field= NULL;                             /* mark the end of the list */
 
3043
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
3044
  share->blob_fields= blob_count;
 
3045
 
 
3046
  null_pack_length= (null_count + 7)/8;
 
3047
  share->reclength= record_length + null_pack_length;
 
3048
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
3049
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
3050
  if (!table->record[0])
 
3051
    goto error;
 
3052
 
 
3053
  if (null_pack_length)
 
3054
  {
 
3055
    table->null_flags= (unsigned char*) table->record[0];
 
3056
    share->null_fields= null_count;
 
3057
    share->null_bytes= null_pack_length;
 
3058
  }
 
3059
 
 
3060
  table->in_use= session;           /* field->reset() may access table->in_use */
 
3061
  {
 
3062
    /* Set up field pointers */
 
3063
    unsigned char *null_pos= table->record[0];
 
3064
    unsigned char *field_pos= null_pos + share->null_bytes;
 
3065
    uint32_t null_bit= 1;
 
3066
 
 
3067
    for (field= table->field; *field; ++field)
 
3068
    {
 
3069
      Field *cur_field= *field;
 
3070
      if ((cur_field->flags & NOT_NULL_FLAG))
 
3071
        cur_field->move_field(field_pos);
 
3072
      else
 
3073
      {
 
3074
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
3075
        null_bit<<= 1;
 
3076
        if (null_bit == (1 << 8))
 
3077
        {
 
3078
          ++null_pos;
 
3079
          null_bit= 1;
 
3080
        }
 
3081
      }
 
3082
      cur_field->reset();
 
3083
 
 
3084
      field_pos+= cur_field->pack_length();
 
3085
    }
 
3086
  }
 
3087
  return table;
 
3088
error:
 
3089
  for (field= table->field; *field; ++field)
 
3090
    delete *field;                         /* just invokes field destructor */
 
3091
  return 0;
 
3092
}
 
3093
 
 
3094
bool Table::open_tmp_table()
 
3095
{
 
3096
  int error;
 
3097
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
3098
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
3099
  {
 
3100
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
3101
    db_stat= 0;
 
3102
    return true;
 
3103
  }
 
3104
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
3105
  return false;
 
3106
}
 
3107
 
 
3108
 
 
3109
/*
 
3110
  Create MyISAM temporary table
 
3111
 
 
3112
  SYNOPSIS
 
3113
    create_myisam_tmp_table()
 
3114
      keyinfo         Description of the index (there is always one index)
 
3115
      start_recinfo   MyISAM's column descriptions
 
3116
      recinfo INOUT   End of MyISAM's column descriptions
 
3117
      options         Option bits
 
3118
 
 
3119
  DESCRIPTION
 
3120
    Create a MyISAM temporary table according to passed description. The is
 
3121
    assumed to have one unique index or constraint.
 
3122
 
 
3123
    The passed array or MI_COLUMNDEF structures must have this form:
 
3124
 
 
3125
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
3126
         when there are many nullable columns)
 
3127
      2. Table columns
 
3128
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
3129
 
 
3130
    This function may use the free element to create hash column for unique
 
3131
    constraint.
 
3132
 
 
3133
   RETURN
 
3134
     false - OK
 
3135
     true  - Error
 
3136
*/
 
3137
 
 
3138
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
3139
                                    MI_COLUMNDEF *start_recinfo,
 
3140
                                    MI_COLUMNDEF **recinfo,
 
3141
                                    uint64_t options)
 
3142
{
 
3143
  int error;
 
3144
  MI_KEYDEF keydef;
 
3145
  MI_UNIQUEDEF uniquedef;
 
3146
  TableShare *share= s;
 
3147
 
 
3148
  if (share->keys)
 
3149
  {                                             // Get keys for ni_create
 
3150
    bool using_unique_constraint= 0;
 
3151
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
3152
                                            sizeof(*seg) * keyinfo->key_parts);
 
3153
    if (!seg)
 
3154
      goto err;
 
3155
 
 
3156
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
3157
    if (keyinfo->key_length >= file->max_key_length() ||
 
3158
        keyinfo->key_parts > file->max_key_parts() ||
 
3159
        share->uniques)
 
3160
    {
 
3161
      /* Can't create a key; Make a unique constraint instead of a key */
 
3162
      share->keys=    0;
 
3163
      share->uniques= 1;
 
3164
      using_unique_constraint=1;
 
3165
      memset(&uniquedef, 0, sizeof(uniquedef));
 
3166
      uniquedef.keysegs=keyinfo->key_parts;
 
3167
      uniquedef.seg=seg;
 
3168
      uniquedef.null_are_equal=1;
 
3169
 
 
3170
      /* Create extra column for hash value */
 
3171
      memset(*recinfo, 0, sizeof(**recinfo));
 
3172
      (*recinfo)->type= FIELD_CHECK;
 
3173
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
3174
      (*recinfo)++;
 
3175
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
3176
    }
 
3177
    else
 
3178
    {
 
3179
      /* Create an unique key */
 
3180
      memset(&keydef, 0, sizeof(keydef));
 
3181
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
3182
      keydef.keysegs=  keyinfo->key_parts;
 
3183
      keydef.seg= seg;
 
3184
    }
 
3185
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
3186
    {
 
3187
      Field *key_field=keyinfo->key_part[i].field;
 
3188
      seg->flag=     0;
 
3189
      seg->language= key_field->charset()->number;
 
3190
      seg->length=   keyinfo->key_part[i].length;
 
3191
      seg->start=    keyinfo->key_part[i].offset;
 
3192
      if (key_field->flags & BLOB_FLAG)
 
3193
      {
 
3194
        seg->type=
 
3195
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
 
3196
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
3197
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
3198
                                  - share->blob_ptr_size);
 
3199
        seg->flag= HA_BLOB_PART;
 
3200
        seg->length= 0;                 // Whole blob in unique constraint
 
3201
      }
 
3202
      else
 
3203
      {
 
3204
        seg->type= keyinfo->key_part[i].type;
 
3205
      }
 
3206
      if (!(key_field->flags & NOT_NULL_FLAG))
 
3207
      {
 
3208
        seg->null_bit= key_field->null_bit;
 
3209
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
3210
        /*
 
3211
          We are using a GROUP BY on something that contains NULL
 
3212
          In this case we have to tell MyISAM that two NULL should
 
3213
          on INSERT be regarded at the same value
 
3214
        */
 
3215
        if (!using_unique_constraint)
 
3216
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
3217
      }
 
3218
    }
 
3219
  }
 
3220
  MI_CREATE_INFO create_info;
 
3221
  memset(&create_info, 0, sizeof(create_info));
 
3222
 
 
3223
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3224
      OPTION_BIG_TABLES)
 
3225
    create_info.data_file_length= ~(uint64_t) 0;
 
3226
 
 
3227
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
3228
                       (uint32_t) (*recinfo-start_recinfo),
 
3229
                       start_recinfo,
 
3230
                       share->uniques, &uniquedef,
 
3231
                       &create_info,
 
3232
                       HA_CREATE_TMP_TABLE)))
 
3233
  {
 
3234
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
3235
    db_stat= 0;
 
3236
    goto err;
 
3237
  }
 
3238
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
3239
  share->db_record_offset= 1;
 
3240
  return false;
 
3241
 err:
 
3242
  return true;
 
3243
}
 
3244
 
 
3245
 
 
3246
void Table::free_tmp_table(Session *session)
 
3247
{
 
3248
  MEM_ROOT own_root= mem_root;
 
3249
  const char *save_proc_info;
 
3250
 
 
3251
  save_proc_info=session->get_proc_info();
 
3252
  session->set_proc_info("removing tmp table");
 
3253
 
 
3254
  // Release latches since this can take a long time
 
3255
  ha_release_temporary_latches(session);
 
3256
 
 
3257
  if (file)
 
3258
  {
 
3259
    if (db_stat)
 
3260
      file->ha_drop_table(s->table_name.str);
 
3261
    else
 
3262
      s->db_type()->deleteTable(session, s->table_name.str);
 
3263
    delete file;
 
3264
  }
 
3265
 
 
3266
  /* free blobs */
 
3267
  for (Field **ptr= field ; *ptr ; ptr++)
 
3268
    (*ptr)->free();
 
3269
  free_io_cache(this);
 
3270
 
 
3271
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
3272
  session->set_proc_info(save_proc_info);
 
3273
}
 
3274
 
 
3275
/**
 
3276
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
3277
  to this.
 
3278
*/
 
3279
 
 
3280
bool create_myisam_from_heap(Session *session, Table *table,
 
3281
                             MI_COLUMNDEF *start_recinfo,
 
3282
                             MI_COLUMNDEF **recinfo,
 
3283
                             int error, bool ignore_last_dupp_key_error)
 
3284
{
 
3285
  Table new_table;
 
3286
  TableShare share;
 
3287
  const char *save_proc_info;
 
3288
  int write_err;
 
3289
 
 
3290
  if (table->s->db_type() != heap_engine ||
 
3291
      error != HA_ERR_RECORD_FILE_FULL)
 
3292
  {
 
3293
    table->file->print_error(error,MYF(0));
 
3294
    return true;
 
3295
  }
 
3296
 
 
3297
  // Release latches since this can take a long time
 
3298
  ha_release_temporary_latches(session);
 
3299
 
 
3300
  new_table= *table;
 
3301
  share= *table->s;
 
3302
  new_table.s= &share;
 
3303
  new_table.s->storage_engine= myisam_engine;
 
3304
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
3305
                                        new_table.s->db_type())))
 
3306
    return true;                                // End of memory
 
3307
 
 
3308
  save_proc_info=session->get_proc_info();
 
3309
  session->set_proc_info("converting HEAP to MyISAM");
 
3310
 
 
3311
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
3312
                                        recinfo, session->lex->select_lex.options |
 
3313
                                        session->options))
 
3314
    goto err2;
 
3315
  if (new_table.open_tmp_table())
 
3316
    goto err1;
 
3317
  if (table->file->indexes_are_disabled())
 
3318
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3319
  table->file->ha_index_or_rnd_end();
 
3320
  table->file->ha_rnd_init(1);
 
3321
  if (table->no_rows)
 
3322
  {
 
3323
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
3324
    new_table.no_rows=1;
 
3325
  }
 
3326
 
 
3327
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
3328
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
3329
 
 
3330
  /*
 
3331
    copy all old rows from heap table to MyISAM table
 
3332
    This is the only code that uses record[1] to read/write but this
 
3333
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
3334
  */
 
3335
  while (!table->file->rnd_next(new_table.record[1]))
 
3336
  {
 
3337
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
3338
    if (write_err)
 
3339
      goto err;
 
3340
  }
 
3341
  /* copy row that filled HEAP table */
 
3342
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
3343
  {
 
3344
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3345
        !ignore_last_dupp_key_error)
 
3346
      goto err;
 
3347
  }
 
3348
 
 
3349
  /* remove heap table and change to use myisam table */
 
3350
  (void) table->file->ha_rnd_end();
 
3351
  (void) table->file->close();                  // This deletes the table !
 
3352
  delete table->file;
 
3353
  table->file= NULL;
 
3354
  new_table.s= table->s;                       // Keep old share
 
3355
  *table= new_table;
 
3356
  *table->s= share;
 
3357
 
 
3358
  table->file->change_table_ptr(table, table->s);
 
3359
  table->use_all_columns();
 
3360
  if (save_proc_info)
 
3361
  {
 
3362
    const char *new_proc_info=
 
3363
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
3364
      "Copying to tmp table on disk" : save_proc_info);
 
3365
    session->set_proc_info(new_proc_info);
 
3366
  }
 
3367
  return false;
 
3368
 
 
3369
 err:
 
3370
  table->file->print_error(write_err, MYF(0));
 
3371
  (void) table->file->ha_rnd_end();
 
3372
  (void) new_table.file->close();
 
3373
 err1:
 
3374
  new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
 
3375
 err2:
 
3376
  delete new_table.file;
 
3377
  session->set_proc_info(save_proc_info);
 
3378
  table->mem_root= new_table.mem_root;
 
3379
  return true;
 
3380
}
 
3381
 
 
3382
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
 
3383
{
 
3384
  my_bitmap_map *old= bitmap->bitmap;
 
3385
  bitmap->bitmap= s->all_set.bitmap;
1418
3386
  return old;
1419
3387
}
1420
3388
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
3389
void Table::restore_column_map(my_bitmap_map *old)
1422
3390
{
1423
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1424
 
  {
1425
 
    if (old.test(i))
1426
 
    {
1427
 
      read_set->set(i);
1428
 
    }
1429
 
    else
1430
 
    {
1431
 
      read_set->reset(i);
1432
 
    }
1433
 
  }
 
3391
  read_set->bitmap= old;
1434
3392
}
1435
3393
 
1436
3394
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1439
3397
  uint32_t best= MAX_KEY;
1440
3398
  if (usable_keys->any())
1441
3399
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
3400
    for (uint32_t nr= 0; nr < s->keys ; nr++)
1443
3401
    {
1444
3402
      if (usable_keys->test(nr))
1445
3403
      {
1466
3424
{
1467
3425
  for (; *ptr ; ptr++)
1468
3426
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
3427
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
3428
      return true;
1471
3429
  }
1472
3430
  return false;
1473
3431
}
1474
3432
 
1475
 
/**
1476
 
   True if the table's input and output record buffers are comparable using
1477
 
   compare_records(TABLE*).
1478
 
 */
1479
 
bool Table::records_are_comparable()
1480
 
{
1481
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1482
 
          write_set->is_subset_of(*read_set));
1483
 
}
1484
 
 
1485
 
/**
1486
 
   Compares the input and outbut record buffers of the table to see if a row
1487
 
   has changed. The algorithm iterates over updated columns and if they are
1488
 
   nullable compares NULL bits in the buffer before comparing actual
1489
 
   data. Special care must be taken to compare only the relevant NULL bits and
1490
 
   mask out all others as they may be undefined. The storage engine will not
1491
 
   and should not touch them.
1492
 
 
1493
 
   @param table The table to evaluate.
1494
 
 
1495
 
   @return true if row has changed.
1496
 
   @return false otherwise.
1497
 
*/
1498
 
bool Table::compare_records()
1499
 
{
1500
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1501
 
  {
1502
 
    /*
1503
 
      Storage engine may not have read all columns of the record.  Fields
1504
 
      (including NULL bits) not in the write_set may not have been read and
1505
 
      can therefore not be compared.
1506
 
    */
1507
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1508
 
    {
1509
 
      Field *f= *ptr;
1510
 
      if (write_set->test(f->position()))
1511
 
      {
1512
 
        if (f->real_maybe_null())
1513
 
        {
1514
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1515
 
 
1516
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1517
 
              ((record[1][null_byte_index]) & f->null_bit))
1518
 
            return true;
1519
 
        }
1520
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1521
 
          return true;
1522
 
      }
1523
 
    }
1524
 
    return false;
1525
 
  }
1526
 
 
1527
 
  /*
1528
 
    The storage engine has read all columns, so it's safe to compare all bits
1529
 
    including those not in the write_set. This is cheaper than the
1530
 
    field-by-field comparison done above.
1531
 
  */
1532
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
3433
/* Return false if row hasn't changed */
 
3434
 
 
3435
bool Table::compare_record()
 
3436
{
 
3437
  if (s->blob_fields + s->varchar_fields == 0)
 
3438
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
1536
3439
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1538
 
    return true; /* Diff in NULL value */
1539
 
 
 
3440
  if (memcmp(null_flags,
 
3441
             null_flags + s->rec_buff_length,
 
3442
             s->null_bytes))
 
3443
    return true;                                // Diff in NULL value
1540
3444
  /* Compare updated fields */
1541
3445
  for (Field **ptr= field ; *ptr ; ptr++)
1542
3446
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
3447
    if (isWriteSet((*ptr)->field_index) &&
 
3448
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
3449
      return true;
1546
3450
  }
1547
3451
  return false;
1553
3457
 */
1554
3458
void Table::storeRecord()
1555
3459
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3460
  memcpy(record[1], record[0], (size_t) s->reclength);
1557
3461
}
1558
3462
 
1559
3463
/*
1562
3466
 */
1563
3467
void Table::storeRecordAsInsert()
1564
3468
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3469
  memcpy(insert_values, record[0], (size_t) s->reclength);
1567
3470
}
1568
3471
 
1569
3472
/*
1572
3475
 */
1573
3476
void Table::storeRecordAsDefault()
1574
3477
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3478
  memcpy(s->default_values, record[0], (size_t) s->reclength);
1576
3479
}
1577
3480
 
1578
3481
/*
1581
3484
 */
1582
3485
void Table::restoreRecord()
1583
3486
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
3487
  memcpy(record[0], record[1], (size_t) s->reclength);
1585
3488
}
1586
3489
 
1587
3490
/*
1590
3493
 */
1591
3494
void Table::restoreRecordAsDefault()
1592
3495
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
3496
  memcpy(record[0], s->default_values, (size_t) s->reclength);
1594
3497
}
1595
3498
 
1596
3499
/*
1600
3503
void Table::emptyRecord()
1601
3504
{
1602
3505
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
1604
 
}
1605
 
 
1606
 
Table::Table() : 
1607
 
  field(NULL),
1608
 
  cursor(NULL),
1609
 
  next(NULL),
1610
 
  prev(NULL),
1611
 
  read_set(NULL),
1612
 
  write_set(NULL),
1613
 
  tablenr(0),
1614
 
  db_stat(0),
1615
 
  def_read_set(),
1616
 
  def_write_set(),
1617
 
  tmp_set(),
1618
 
  in_use(NULL),
1619
 
  key_info(NULL),
1620
 
  next_number_field(NULL),
1621
 
  found_next_number_field(NULL),
1622
 
  timestamp_field(NULL),
1623
 
  pos_in_table_list(NULL),
1624
 
  group(NULL),
1625
 
  null_flags(NULL),
1626
 
  lock_position(0),
1627
 
  lock_data_start(0),
1628
 
  lock_count(0),
1629
 
  used_fields(0),
1630
 
  status(0),
1631
 
  derived_select_number(0),
1632
 
  current_lock(F_UNLCK),
1633
 
  copy_blobs(false),
1634
 
  maybe_null(false),
1635
 
  null_row(false),
1636
 
  force_index(false),
1637
 
  distinct(false),
1638
 
  const_table(false),
1639
 
  no_rows(false),
1640
 
  key_read(false),
1641
 
  no_keyread(false),
1642
 
  open_placeholder(false),
1643
 
  locked_by_name(false),
1644
 
  no_cache(false),
1645
 
  auto_increment_field_not_null(false),
1646
 
  alias_name_used(false),
1647
 
  query_id(0),
1648
 
  quick_condition_rows(0),
1649
 
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
 
  map(0),
1651
 
  quick_rows(),
1652
 
  const_key_parts(),
1653
 
  quick_key_parts(),
1654
 
  quick_n_ranges()
1655
 
{
1656
 
  record[0]= (unsigned char *) 0;
1657
 
  record[1]= (unsigned char *) 0;
 
3506
  memset(null_flags, 255, s->null_bytes);
1658
3507
}
1659
3508
 
1660
3509
/*****************************************************************************
1662
3511
  Returns -1 if row was not found, 0 if row was found and 1 on errors
1663
3512
*****************************************************************************/
1664
3513
 
1665
 
/** Help function when we get some an error from the table Cursor. */
 
3514
/** Help function when we get some an error from the table handler. */
1666
3515
 
1667
3516
int Table::report_error(int error)
1668
3517
{
1676
3525
    print them to the .err log
1677
3526
  */
1678
3527
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1679
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
1680
 
                  error, getShare()->getPath());
1681
 
  print_error(error, MYF(0));
 
3528
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
3529
                    error, s->path.str);
 
3530
  file->print_error(error,MYF(0));
1682
3531
 
1683
3532
  return 1;
1684
3533
}
1691
3540
  null_row= 0;
1692
3541
  status= STATUS_NO_RECORD;
1693
3542
  maybe_null= table_list->outer_join;
1694
 
  TableList *embedding= table_list->getEmbedding();
 
3543
  TableList *embedding= table_list->embedding;
1695
3544
  while (!maybe_null && embedding)
1696
3545
  {
1697
3546
    maybe_null= embedding->outer_join;
1698
 
    embedding= embedding->getEmbedding();
 
3547
    embedding= embedding->embedding;
1699
3548
  }
1700
3549
  tablenr= table_number;
1701
3550
  map= (table_map) 1 << table_number;
1702
3551
  force_index= table_list->force_index;
1703
 
  covering_keys= getShare()->keys_for_keyread;
 
3552
  covering_keys= s->keys_for_keyread;
1704
3553
  merge_keys.reset();
1705
3554
}
1706
3555
 
1707
 
 
1708
 
bool Table::fill_item_list(List<Item> *item_list) const
1709
 
{
1710
 
  /*
1711
 
    All Item_field's created using a direct pointer to a field
1712
 
    are fixed in Item_field constructor.
1713
 
  */
1714
 
  for (Field **ptr= field; *ptr; ptr++)
1715
 
  {
1716
 
    Item_field *item= new Item_field(*ptr);
1717
 
    if (!item || item_list->push_back(item))
1718
 
      return true;
1719
 
  }
1720
 
  return false;
1721
 
}
1722
 
 
1723
 
 
1724
 
void Table::filesort_free_buffers(bool full)
1725
 
{
1726
 
  if (sort.record_pointers)
1727
 
  {
1728
 
    free((unsigned char*) sort.record_pointers);
1729
 
    sort.record_pointers=0;
1730
 
  }
1731
 
  if (full)
1732
 
  {
1733
 
    if (sort.sort_keys )
1734
 
    {
1735
 
      if ((unsigned char*) sort.sort_keys)
1736
 
        free((unsigned char*) sort.sort_keys);
1737
 
      sort.sort_keys= 0;
1738
 
    }
1739
 
    if (sort.buffpek)
1740
 
    {
1741
 
      if ((unsigned char*) sort.buffpek)
1742
 
        free((unsigned char*) sort.buffpek);
1743
 
      sort.buffpek= 0;
1744
 
      sort.buffpek_len= 0;
1745
 
    }
1746
 
  }
1747
 
 
1748
 
  if (sort.addon_buf)
1749
 
  {
1750
 
    free((char *) sort.addon_buf);
1751
 
    free((char *) sort.addon_field);
1752
 
    sort.addon_buf=0;
1753
 
    sort.addon_field=0;
1754
 
  }
1755
 
}
1756
 
 
1757
 
/*
1758
 
  Is this instance of the table should be reopen or represents a name-lock?
1759
 
*/
1760
 
bool Table::needs_reopen_or_name_lock() const
1761
 
1762
 
  return getShare()->getVersion() != refresh_version;
1763
 
}
1764
 
 
1765
 
uint32_t Table::index_flags(uint32_t idx) const
1766
 
{
1767
 
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1768
 
}
1769
 
 
1770
 
void Table::print_error(int error, myf errflag) const
1771
 
{
1772
 
  getShare()->getEngine()->print_error(error, errflag, *this);
1773
 
}
1774
 
 
1775
 
} /* namespace drizzled */
 
3556
Field *Table::find_field_in_table_sef(const char *name)
 
3557
{
 
3558
  Field **field_ptr;
 
3559
  if (s->name_hash.records)
 
3560
  {
 
3561
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
 
3562
                                    strlen(name));
 
3563
    if (field_ptr)
 
3564
    {
 
3565
      /*
 
3566
        field_ptr points to field in TableShare. Convert it to the matching
 
3567
        field in table
 
3568
      */
 
3569
      field_ptr= (field + (field_ptr - s->field));
 
3570
    }
 
3571
  }
 
3572
  else
 
3573
  {
 
3574
    if (!(field_ptr= field))
 
3575
      return (Field *)0;
 
3576
    for (; *field_ptr; ++field_ptr)
 
3577
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
 
3578
        break;
 
3579
  }
 
3580
  if (field_ptr)
 
3581
    return *field_ptr;
 
3582
  else
 
3583
    return (Field *)0;
 
3584
}
 
3585
 
 
3586
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3587
template class List<String>;
 
3588
template class List_iterator<String>;
 
3589
#endif